如何从 AWS Lambda 函数 + 无服务器框架的 URL 中删除阶段?

How to remove stage from URLs for AWS Lambda functions + Serverless framework?

我正在使用无服务器框架在 AWS Lambda 中部署函数,但我找不到 where/how 我可以从创建的 URL 端点中删除阶段说明符。文档似乎没有涵盖这部分。

例如我的serverless.yml(省略无关部分):

service: cd-mock
provider:
  name: aws
  runtime: python3.6
  region: eu-west-1
package:
  include:
    - handler.py
functions:
  index:
    handler: handler.index
    events:
      - http:
          path: /
          method: get

serverless deploy后返回如下服务信息:

service: cd-mock
stage: dev
region: eu-west-1
stack: cd-mock-dev
api keys:
  None
endpoints:
  GET - https://ab1cd2ef3g.execute-api.eu-west-1.amazonaws.com/dev/
functions:
  index: cd-mock-dev-index

注意 URL 端点以及函数中的 /dev 部分。 dev是配置文件中stage参数的默认值。

serverless.yml 文件中指定 stage: something 将使 /something 作为 URL 中的后缀,并作为函数的一部分。

问题:如何从生成的 URL 端点中删除阶段规范,或者:如何防止该阶段规范成为生成的 URLs 的一部分?

(阶段是函数的一部分,很好。这将很容易在 AWS Lambda 仪表板中分离 stagingproduction 函数。)

这是一个 API 网关 feature/convention 不是来自无服务器框架,所以 serverless 对此无能为力。

API 网关需要一个阶段,它附加在端点的末尾。

API 网关端点是为开发人员准备的,因此并不意味着用户友好。

如果您希望它对用户友好,您可以为其添加自定义域。不同的阶段可以有不同的自定义子域。

您可以做的一件事是使用您拥有的自定义域(例如 mycompany.com)并将其映射到您的 API 网关。这样,您就不会向 https://ab1cd2ef3g.execute-api.eu-west-1.amazonaws.com/dev/ 发出请求,而是向 https://api.mycompany.com/.

发出请求

有一个名为 serverless-domain-manager that makes it much easier to set up this custom domains. Check out this blog post 的插件,可完整了解如何使用它。

由@dashnug 的回答 "API Gateway requires you with a stage and it is appended at the end of your endpoint" 和我在其他地方读到的另一个回复触发,我 'solved' 通过使阶段规范不太清楚(关于引用哪个阶段环境)来解决这个问题使用 v1 作为舞台。这也暗示了某种 API 版本控制,这在我的情况下也是可以接受的。

所以,我的 serverless.yml 部分现在包含:

provider:
  name: aws
  runtime: python3.6
  memorySize: 512
  region: ${opt:region, 'eu-west-1'}
  profile: ${opt:profile, 'default'}
  stage: ${opt:stage, 'v1'}  # A trick to don't end up with "production" or "staging" as stage.

在本地环境中,我们可以在 运行 开发服务器时使用标志 --noPrependStageInUrl:sls offline start --noPrependStageInUrl 在使用无服务器离线时。在线,我们可以设置 CloudFront 或自定义域。

这可以通过使用 httpApi 而不是 http 来解决。而不是

functions:
  index:
    handler: handler.index
    events:
      - http:
          path: /
          method: get

使用这个

functions:
  index:
    handler: handler.index
    events:
      - httpApi:
          path: /
          method: get

如果您不依赖与 http 一起使用的 REST 协议,并且 HTTP 协议适合您,那么这应该可以解决问题。对于阅读差异,我认为这是一个好的开始:

https://docs.aws.amazon.com/en_us/apigateway/latest/developerguide/http-api-vs-rest.html