I wanted to make a lambda available at dev-api.example.com/auth/*.
The lambda will act like an auth service. So it will have urls like
dev-api.example.com/auth/register
dev-api.example.com/auth/login
and more ...
Like wise more lambdas will be hooked to single ApiGateway.
With that design decision, I wrote following serverless.yml file.
// serverless.yml
...
custom:
customDomain:
domainName: dev-api.example.com
stage: prod
basePath: ''
...
functions:
auth:
handler: src/index.handler
events:
- http:
method: ANY
path: /{auth+}
It does not seem to work. Whenever I visit dev-api.example.com/auth/register it returns Not Found error.
AWS API Gateway only accepts {proxy+} syntax (Link), then I think serverless fw just support {proxy+} and {any+}.
If you want to just create a function to handle 2 api endpoint, in this case, the endpoints are
POST /auth/register (I think so)
POST /auth/login
Then you have setting in serverless.yml like
...
functions:
auth:
handler: src/index.handler
events:
- http:
method: ANY
path: auth/{any+} # this matches any path, the token 'any' doesn't mean anything special
...
Thanks #hoangdv , your suggestion almost fixed the problem.
The issue was with path. It should have been path: auth/{proxy+} instead of path: /{auth+}
functions:
auth:
handler: src/index.handler
events:
- http:
method: ANY
path: auth/{proxy+}
Related
I'm new to Lambda Computing and AWS. I'm trying to set up a REST API Service with Lambda. I have three different functions defined in my serverless.yml file from my handler something like this:
functions:
users:
handler: handler.users
events:
- http:
path: users
method: get
cors: true
integration: lambda
stats:
handler: handler.Stats
events:
- http:
path: users/{id}/stats
method: get
cors: true
integration: lambda
contribution:
handler: handler.contribution
events:
- http:
path: patientset/{pid}/contribution
method: get
cors: true
integration: lambda
When I deploy the same, it throws me an error:
Serverless Error ---------------------------------------
An error occurred: ApiGatewayResourcePatientsetPidVar - A sibling ({id}) of this resource already has a variable path part -- only one is allowed (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException; Request ID: f4047858-b52d-4721-b0a2-069a59254e6b; Proxy: null).
So to test it, I change the path for the function contribution from patientset/{pid}/contribution to patientset/{id}/contribution, the deployment is successful.
But this is what I don't require. I need to define the proper name convention for each function to help recognize what kind of id a function is expecting as it's path parameter.
I also tried resolving the same with some suggestions around as found here, but this also didn't help. If anyone can help provide any solution for the same & this explains this weird behavior from serverless, highly appreciated.
Thanks in advance.
Check if path is not repeated for any of handlers
Comment the section causing issue and deploy once.
Then uncomment then section, redeploy.
Its a known bug in serverless with AWS
I faced same issue got resolved with this.
Seems to be a long standing AWS issue where changing the endpoint variable causes an issue
https://github.com/serverless/serverless/issues/3785
In my SAM templates, my team has defined an API that is mostly to our liking. I would like to debug this API locally, but it isn't set explicitly as an Event under our Function. So sam local start-api fails with the error
Error: Template does not have any APIs connected to Lambda functions
How can I convince SAM that the API we have defined is the event meant to invoke this Lambda? What should I do to test this locally?
edit - to clarify, the current template structure looks something like
Lambda:
Type: AWS::Serverless::Function
Properties:
...
LambdaRole:
....
MAILAPI:
Type: AWS::Serverless::Api
Properties:
...
Not sure if this implements all the gateway params we defined so I wont mark this as resolved yet, but this is a promising start!
This allowed me to start the API as expected locally
Events:
Api:
Type: Api
Properties:
Path: /
Method: post
RestApiId:
Ref: MAILAPI
With (of course) our API resource defined under the MAILAPI label (edited question to show this)
As part of a AWS SAM template, I have a function with an HttpPost event trigger. Because I'm using the AWS SAM transform, I am not explicitly declaring the API Gateway that gets created to route this http post to trigger the function. Given that, is there any way to reference the generated URL endpoint, such as in a stack output or describe-stack-resources, so that I can programatically get the invocation URL for the function? I know I can get the endpoint by navigating to the stack in the console, finding the ApiGateway resource, and clicking around randomly until one of the pages shows it. But I'd like a method that my application code can reproduce.
Shortened template for reference:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
...
SendJobUpdateFunction:
Type: AWS::Serverless::Function
Properties:
...
Runtime: nodejs10.x
Events:
HttpPost:
Type: Api
Properties:
Path: '/jobs'
Method: post
...
I'm currently deploying using the sam CLI, which has I think a very similar syntax to aws cloudformtion.
According to the documentation and this previous question, you can get it with:
!Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/${Stage}"
Where ${Stage} is your own parameter containing the deployed stage.
I would like to enable caching for API Gateway for my serverless functions, but having hard time to understand where to do it and what way.
I have tried to set up queryStringParameters in my serverless functions but that results in error, also tried to add them under my GLOBAL Api but no luck (also would prefer avoid doing this in global)
Also checked my resources in the API Gateway and caching is disabled for RequestParams and QueryStringParams are missing from there.
As a reference:
https://awslabs.github.io/serverless-application-model/internals/generated_resources.html
As a reference:
https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessapi
As a reference:
https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Template
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Globals:
Api:
EndpointConfiguration: REGIONAL
CacheClusterEnabled: true
CacheClusterSize: "0.5"
MethodSettings:
- CachingEnabled: true
CacheDataEncrypted: true
CacheTtlInSeconds: 60
HttpMethod: "*"
ResourcePath: "/*"
Resources:
......
GetItem:
Type: 'AWS::Serverless::Function'
Properties:
Handler: GetItem.handler
Runtime: nodejs8.10
Timeout: 20
CodeUri: "codes"
Events:
GetItem:
Type: Api
Properties:
Path: /item/{itemCode}
Method: get
......
***********************************EDIT*********************************
Found out if API Gateway does not know about the params then it will ignore it for caching https://forums.aws.amazon.com/thread.jspa?messageID=915838󟥾
I have tried to add multiple methodSetting entries to the template, and it seems the CF dont ignore it, but still the same result. Also im not sure how to do the same for queryStringParameters if possible.
- ResourcePath: "/~1item~1/~1{itemCode}"
CachingEnabled: true
CacheDataEncrypted: true
CacheTtlInSeconds: 60
HttpMethod: "*"
***********************************EDIT*********************************
I would prefer a way to enable the caching for the RequestParams and QueryParams under every resource aka 'AWS::Serverless::Function'
Your help is much appreciated.
At this point there is no support from SAM framework to do this. They are planning to release an update where they enable the function more on this link: https://github.com/awslabs/serverless-application-model/issues/1140
Until then the only solution i was able to come up os to create a CloudFront distribution in front of the API gateway, its kind of waste of resource but it works nicely.
To test that I needed CORS enabled in my API Gateway for a Lambda Proxy, I removed the cors:true definition in my serverless.yml.
Then when I put it back, I get the following error:
You can only use "origin" or "origins", but not both at the same time to configure CORS. Please check the docs for more info.
I cant find anything in the docs that would explain why my code would be throwing that error.
I know that the single line version is synonomous with a multi line version like so:
cors:
origins:
- '*'
headers:
- Content-Type
- X-Amz-Date
- Authorization
- X-Api-Key
- X-Amz-Security-Token
allowCredentials: false
as per: https://serverless.com/framework/docs/providers/aws/events/apigateway/#enabling-cors
Does it perhaps cache the config and now it thinks Im declaring it twice, once as 'origin' and another as 'origins'.
I can't see why I would get that error if I just toggled the `cors:true' line between deploys as I did.
This is from my serverless.yml:
functions:
submitApi:
handler: handler.submit
description: Cloud API integration to the Third-Party API
events:
- http:
path: thirdParty
method: post
cors: true
Update:
This issue appears to be a bug that is being tracked in the serverless project, found here: https://github.com/serverless/serverless/issues/6098