Deploying multiple Serverless Framework apis to the same AWS API Gateway

By default, each Serverless project you deploy will create a new API Gateway. In most cases this works fine, but for larger projects you may need to split your apis across multiple smaller Serverless projects, each with their own serverless.yml that can be deployed independently.

The Serverless docs describe how to do this here. In each additional Serverless project where you want to add additional apis to an existing API Gateway, you need to specify 2 additional properties in your Serverless.yml, apiGateway and restApiRootResourceId:

provider:
  name: aws
  apiGateway:
    restApiId: xxxxxxxxxx # REST API resource ID. Default is generated by the framework
    restApiRootResourceId: xxxxxxxxxx # Root resource, represent as / path

apiGateway – this is the 11 character id for your API Gateway that you want to add resources to. You can get this from the console and it’s the prefix in your api gw url, e.g. https://aaaaaaaaaaa.execute-api.us-west-1.amazonaws.com/dev

The id for the root resource is where in your api path structure you want to add your new resource to, either the id of the root / or one of the existing paths beneath the root.

This id value I don’t think is visible in the console, but you can get it a list of all the resources in your API Gateway including the ids of each of the existing resources, with:

aws apigateway get-resources --rest-api-id aaaaaaaaaaa --region us-west-2

It will give a response that looks like:

{
    "items": [
        {
            "id": "bbbbbb",
            "parentId": "aaaaaaaaaa",
            "pathPart": "example1",
            "path": "/example1",
            "resourceMethods": {
                "GET": {}
            }
        },
        {
            "id": "aaaaaaaaaa",
            "path": "/"
        }
    ]
}

In this example I have a root / with id = aaaaaaaaa and a resource bbbbbb for /example1.

In this case if I pass aaaaaaaaaa as the value for restApiRootResourceId then my new resource will be added to /, or passing bbbbbb it will be added as a resource under /example1

Serverless Framework: AWS Lambdas with scheduled events and parameters

To configure an AWS Lambda to get triggered by a CloudWatch event, you can use the ‘schedule’ event in your config:

functions:
  your-function-name:
    handler: your.Handler
    timeout: 30
    events:
      - schedule:
          rate: rate(12 hours)
          input:
            puzzles : "2"
            targetGivens : "20"

You can also pass parameters from the CloudWatch event when your Lambda is invoked by listing them under ‘input’ (this is optional if your Lambda doesn’t take any parameters).

There schedule config is covered in the docs here, but there doesn’t seem to be any official docs for input, but I found this in a reply to a question here.

Serverless Framework API Gateway CORS config

If you deploy a Serverless Framework Java Lambda to AWS and attempt to call it locally while developing your frontend, you’ll run into a CORS error like this:

Access to XMLHttpRequest at 'https://abc.execute-api.us-west-1.amazonaws.com/some/api' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Posts suggest to set a cors option under the event in your serverless.yaml like this:

events:
  - http:
    path: handlerPath
    method: post
    cors:
      origin: '*'

… but in current versions of Serverless this results in an error like this:

Serverless:   at 'functions['example'].events[0].httpApi': unrecognized property 'cors'

From this post, it mentions the cors options has moved up into the provider section:

provider:
  name: aws
  runtime: java8
  lambdaHashingVersion: 20201221
  httpApi:
    cors: true

This is in the docs here.

This works great!

What does this option do? It looks like it sets these options in API Gateway: