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

5

39

I'm using Serverless Framework to deploy functions in AWS Lambda, but I can't find where/how I can remove the stage specifier from the URL endpoints created. The documentation does not seem to cover this part.

For example, this is my serverless.yml (with irrelevant parts omitted):

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

After a serverless deploy, the following service information is returned:

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

Notice the /dev part in the URL endpoint, and also in the function. That dev is the default value for the stage parameter in the configuration file.

Specifying stage: something in the serverless.yml file will have that /something as suffix in the URL, and as part of the function.

Question: how can I remove the stage specification from the generated URL endpoints, or: how can I prevent that stage specification to become part of the generated URLs?

(That the stage is part of the function, is fine. That will be easy to separate staging and production functions in the AWS Lambda dashboard.)

Basin answered 20/10, 2017 at 21:5 Comment(0)
C
26

This is an API Gateway feature/convention NOT from Serverless Framework so serverless can't do anything about it.

API Gateway requires you with a stage and it is appended at the end of your endpoint.

API Gateway endpoints are meant for developers though so it is not meant to be user-friendly.

If you want it to be user-friendly, you can add a custom domain for it. Different stages can have different custom subdomains.

Chambray answered 21/10, 2017 at 6:3 Comment(0)
D
50

One thing you can do is use a custom domain that you own (e.g. mycompany.com) and map that to your API Gateway. This way, rather than making a request to https://ab1cd2ef3g.execute-api.eu-west-1.amazonaws.com/dev/, you would make a request to https://api.mycompany.com/.

There's a plugin called serverless-domain-manager that makes it much easier to set up this custom domains. Check out this blog post for a full walkthrough on how to use it.

Decarbonize answered 21/10, 2017 at 17:23 Comment(2)
Thanks - great answer. I wish I could accept both your and @dashmug's answer. Because he was a bit earlier, and also provided some more explanation (mentioning that it was an API Gateway convention), I accepted his answer. Thanks for the link to serverless-domain-manager though!Basin
No problem! @dashmug had a great answer. Glad you got what you're looking for.Decarbonize
B
38

In the local environment, we may use the flag --noPrependStageInUrl when running the dev server: sls offline start --noPrependStageInUrl when using serverless offline. Online, we may set up a CloudFront or custom domain.

Buckbuckaroo answered 19/10, 2020 at 7:51 Comment(3)
This should be the accepted answer, thanks a bunch :)Litter
Very annoying that this is not the accepted answer and other solutions have a higher up-vote. Thanks a bunch for this! Great stuff!Stigma
Because this is not the answer to the question. The question is about serverless deploy command, not for serverless offlineBlythebm
C
26

This is an API Gateway feature/convention NOT from Serverless Framework so serverless can't do anything about it.

API Gateway requires you with a stage and it is appended at the end of your endpoint.

API Gateway endpoints are meant for developers though so it is not meant to be user-friendly.

If you want it to be user-friendly, you can add a custom domain for it. Different stages can have different custom subdomains.

Chambray answered 21/10, 2017 at 6:3 Comment(0)
G
14

This can be solved by using httpApi, which does not prepend the stage to the URL path, instead of http which does.

Instead of

functions:
  index:
    handler: handler.index
    events:
      - http: # <-- change this
          path: /
          method: get

use this

functions:
  index:
    handler: handler.index
    events:
      - httpApi: # <-- to this
          path: /
          method: get

The http key creates an API Gateway "REST" (aka v1) endpoint whereas httpApi creates an "HTTP" (aka v2) endpoint. v1 has more features but v2 is faster and cheaper.

From the Serverless docs:

Despite their confusing name, both versions allow deploying any HTTP API (like REST, GraphQL, etc.).

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

Getup answered 2/10, 2021 at 13:11 Comment(1)
For my case, I have to further add payload: '1.0' to the function configuration.Spurling
B
7

Triggered by @dashnug's answer "API Gateway requires you with a stage and it is appended at the end of your endpoint" and another reply that I read elsewhere, I 'solved' the problem by making the stage specification a bit less telling (about which stage environment was referred to) by using v1 as a stage. That also suggests some sort of API versioning, which is acceptable in my case as well.

So, my serverless.yml section now contains:

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.
Basin answered 8/5, 2019 at 13:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.