I have an API gateway developed by sam cli.
I'd like to add "hello endpoint" which responses constant metadata like version / available endpoints.
In such case, is there way to configure API gateway inline in template.yml?
Or should I write lambda which returns constant response like this?
helloLambda:
Type: AWS::Serverless::Function
Properties:
CodeUri: .....
Handler: .....
Description: this lambda returns constant data
Events:
Api:
Type: Api
Properties:
Path: /hello
Method: GET
You can consider mock integrations in API Gateway.
Please refer to the link:
creating-an-amazon-api-gateway-with-a-mock-integration-using-cloudformation
Good Day!
Related
I'd like to be able to configure API Gateway Responses via serverless framework...
This is what my serverless.yml looks like:
#Deploy an api gateway with custom responses.
---
service: test-apigw
frameworkVersion: ">=3.20"
provider:
name: aws
stage: dev
region: us-east-1
stackName: ${self:service}
apiName: test-apigw
endpointType: REGIONAL
functions:
hello:
handler: handler.endpoint
events:
- http:
path: /hello-world
method: ANY
private: true
package:
individually: true
excludeDevDependencies: false
Now I read somewhere that one can configure resources in a serverless file, however by using CFN code I'd need the ARN or the Ref of an already deployed API Gateway or, declare the API Gateway with CFN code (which I want to avoid)...
Is there a way to configure these Gateway Responses (not integration responses!!) using the same api gateway that my serverless.yml is deploying? i.e. the one with name test-apigw?
It turns out the response I quoted actually works for me.
In the same serverless.yml file, put the GatewayResponses you want to configure.
resources:
Resources:
Unauthorized:
Type: "AWS::ApiGateway::GatewayResponse"
Properties:
ResponseParameters:
gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
ResponseTemplates:
"application/json": ${file(gateway-responses/responses.js):unauthorized}
ResponseType: UNAUTHORIZED
RestApiId: !Ref ApiGatewayRestApi
StatusCode: '401'
At least for version 3.20 of serverless framework, the created API name is ApiGatewayRestApi, this will only work of course, if you're only creating one API Gw in that file and I believe, the API Gateway has to be already deployed.
The correct way to do this is, as the official serverless documentation states, to create the API Gateway with Cloudformation code.
I am trying to deploy the api and lambda function using SAM. But the Method Response and Integration Response are empty. I am aiming to configure the api-gateway like below picture. In this I have manually configured the api-gateway and its working but when I use the SAM to generate the api-gateway it doesn't shpes the Method Response and Integration Response.
Without Sam:
With Sam:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Globals:
Function:
Timeout: 500
MemorySize: 5000
Resources:
MyApi:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
GatewayResponses:
DEFAULT_4xx:
ResponseParameters:
Headers:
Access-Control-Expose-Headers: "'WWW-Authenticate'"
Access-Control-Allow-Origin: "'*'"
InferenceFunction:
Type: AWS::Serverless::Function
Properties:
PackageType: Image
Events:
Inference:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /zero-shot-classification
Method: post
RestApiId: !Ref MyApi
Metadata:
Dockerfile: Dockerfile
DockerContext: ./zero-shot-classification
DockerTag: zero-shot-classification
The difference you see is the difference between how the payload is sent to the lambda and how API gateway processes the response from the lambda. Seeing as in your CloudFormation you do not specify a specification for your API endpoints, AWS SAM will construct this based on the events from your functions. However, AWS SAM will always use the LAMBDA_PROXY integration type, while you seem to be wanting to use the LAMBDA integration type.
I'd suggest you take your manually created API gateway and export it to an openapi/swagger definition. This can then be used as DefinitionBody in you MyApi. That way you can specify it uses the LAMBDA integration instead of the LAMBDA_PROXY integration. Don't forget to update the swagger definition so it uses the created function in your cloudformation and not the function that existed when you exported the API.
That being said, the LAMBDA_PROXY way is more widely used and also removes the need for template mappings in your API Gateway. It is also the only integration type for lambdas that is supported in the HTTP API (API Gateway v2), which is a lot cheaper than the classic REST API.
I've created AWS Lambda in C# using Visual Studio that returns some JSON from the API endpoint. Now I want to run that lambda locally. All the examples use AWS SAM, but they create a new function using the SAM template.
When I run the command sam local start-lambda I get an error saying that the template isn't found. So what is certain is that I need template.yaml, but I'm not sure is there a way to generate this template for existing Lambda?
Any help is appreciated!
Check out the Template Anatomy resource on the AWS documentation.
You might find this example helpful (it's greatly simplified). I use NodeJS for development, but the differences between programming languages when you're creating a SAM Template are trivial. The example is an outline for a simple Lambda function someFunction being invoked by an API Gateway (HTTP) event.
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: My Serverless Application
Parameters:
# Manually define this in AWS IAM for just the services needed.
lambdaExecutionRole:
Description: 'Required. The role used for lambda execution.'
Type: 'String'
Default: 'arn:aws:iam::nnnnnnnnnnnn:role/LambdaExecutionRole'
Globals:
Function:
Runtime: nodejs10.x
# Environment:
# Variables:
# NODE_ENV: test
# DEBUG: myapp:foo
Resources:
performSomeFunction:
Type: 'AWS::Serverless::Function'
Properties:
FunctionName: performSomeFunction
Handler: lambda.someFunction
CodeUri: ./
Description: description of the function being performed
MemorySize: 256
Timeout: 60
Role:
Ref: lambdaExecutionRole
Events:
# API Gateway proxy endpoint.
ProxyApiRoot:
Type: Api
Properties:
Path: '/'
Method: ANY
ProxyApiGreedy:
Type: Api
Properties:
Path: '/{proxy+}'
Method: ANY
As you're getting started with AWS Lambda, one of the big concepts to keep in mind is how your function will be triggered. Functions are triggered by different kinds of events, and there can be many many different types of events. I tend to use API Gateway, Simple Queue Service and CloudWatch Events to trigger mine, but it entirely depends on your use case.
It turned out that you can export Lambda function, and get the generated .yaml template, which was exactly what I needed.
I've been using AWS SAM for a websocket API and that's been working well. Today, I needed to add an HTTPS API, however my attempt to do so results in a new API gateway, under a different subdomain, to be created. I'd like them to share the same domain, so users only need to change the protocol (from HTTPS to WSS).
This is a relevant section of my template.yaml:
# This seems to implicitly create and use a `ServerlessRestApi` API gateway
PingLambda:
Type: AWS::Serverless::Function
Properties:
CodeUri: lambda/
Handler: app.pingHandler
Runtime: nodejs12.x
Events:
Ping:
Type: Api
Properties:
Path: /ping
Method: get
# I use this for the various websocket lambdas, works like a charm
WebSocketApi:
Type: AWS::ApiGatewayV2::Api
Properties:
Name: SimpleRelayWebSocket
ProtocolType: WEBSOCKET
RouteSelectionExpression: \\$default
# ...
# I'd love both of these to use the same subdomain/API gateway setup
Outputs:
APIURL:
Description: URL of the Simple Relay HTTPS API
Value: !Sub 'https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/${Stage}'
WebSocketURL:
Description: URL of the Simple Relay WSS API
Value: !Sub 'wss://${WebSocketApi}.execute-api.${AWS::Region}.amazonaws.com/${Stage}'
I'm not sure how to proceed, considering the WebSocketApi has ProtocolType: WEBSOCKET set there. Is there some way to split the API into multiple things with different protocols, or is there something else I'm missing?
I need to do the same thing. One possible solution is to put both behind a CloudFront distribution. I'll do this probably, since I'm already using CloudFront to serve the front-end from S3, and some back-end endpoints.
I start study AWS serverless using lambda and API Getway, So I was thinking to create a REST API for a sample project. I noticed that in API Getway, we only can create the http methods which can trigger lambda functions, So I'm not sure if I get this right but, do we need one lambda function for each api route? or we can handle it somehow using one lambda function.
For example, lets say my project need api for below list :
Login
Register
GetUserData
Then if I going to make this by using API Getway and Lambda, I need to have 3 Lambda functions?
Like if I want create API for those mentioned above, it should be something like this for the endpoints ?
https://API_GETWAY_DOMAIN/STAGE/LAMBDA_FUNCTION_FOR_LOGIN
https://API_GETWAY_DOMAIN/STAGE/LAMBDA_FUNCTION_FOR_REGISTER
https://API_GETWAY_DOMAIN/STAGE/LAMBDA_FUNCTION_FOR_GET_USER_DATA
And is there any way to send multi http request to one lambda function, and handle each one of them inside the lambda?
It is possible to have multiple API Gateway routes direct to the same Lambda function. How to set that up depends on how you're maintaining your infrastructure.
For example, if you're using CloudFormation with the Serverless Application Model (SAM), which I recommend since it's probably the most straightforward way to keep track of serverless infrastructure (and infrastructure as code = awesome), you would define your AWS::Serverless::Function with a separate API Gateway source event for each route you define in your AWS::Serverless::Api.
Something like the following:
YourApi:
Type: AWS::Serverless::Api
Properties:
...
DefinitionBody:
swagger: 2.0
...
paths:
'/Login':
post:
x-amazon-apigateway-integration:
# APIG->Lambda requests are always POST
httpMethod: post
type: aws_proxy
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${YourLambda.Arn}/invocations
'/Register':
post:
x-amazon-apigateway-integration:
# APIG->Lambda requests are always POST
httpMethod: post
type: aws_proxy
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${YourLambda.Arn}/invocations
'/GetUserData':
get:
x-amazon-apigateway-integration:
# APIG->Lambda requests are always POST
httpMethod: post
type: aws_proxy
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${YourLambda.Arn}/invocations
YourLambda:
Type: AWS::Serverless::Function
Properties:
...
Events:
login:
Type: Api
Properties:
Path: '/Login'
Method: post
RestApiId: {Ref: YourApi}
register:
Type: Api
Properties:
Path: '/Register'
Method: post
RestApiId: {Ref: YourApi}
getUserData:
Type: Api
Properties:
Path: '/GetUserData'
Method: get
RestApiId: {Ref: YourApi}
Keep in mind, though, that there are pros and cons to consolidating routes into one Lambda function. This StackOverflow question/answer explores that, but I'd like to add a few more benefits to separated Lambda functions:
Clearer metrics on how often your routes are getting called - You get invocations/errors/etc. metrics in CloudWatch for each Lambda function out-of-the-box, so separating them can make it easy to see how often people are registering versus logging in, etc.
More granular alarming - You can set different latency/error/etc. thresholds for different routes, and if an alarm goes off, you know exactly which Lambda function it's for.