Mehran
Mehran

Reputation: 16831

How to split the API Gateway services in a serverless project

I'm dealing with the CloudFormation limitation of 200 resources per stack. It seems the solution is to split my service (serverless.yml file) into multiple files. I have tried automated approaches and they don't work for me. So, I'm looking into manual ones. But I don't know how.

This is a sample file that I have:

service:                        serverless-test

provider:
  name:                         aws
  runtime:                      nodejs12.x
  endpointType:                 REGIONAL

plugins:
- serverless-aws-alias

functions:
  authorizerFunc:
    handler:                    code.authorizer

  users:
    handler:                    code.users
    events:
      - http:
          path:                 /user
          integration:          lambda
          authorizer:           authorizerFunc
          method:               get
          cors:                 true
          request:
            passThrough:        WHEN_NO_TEMPLATES
            template:
              application/json: '{ "action": "list_users" }'
      - http:
          path:                 /user
          integration:          lambda
          authorizer:           authorizerFunc
          method:               post
          cors:                 true
          request:
            passThrough:        WHEN_NO_TEMPLATES
            template:
              application/json: '{ "action": "create_user", "payload": $input.body }'

  posts:
    handler:                    code.posts
    events:
      - http:
          path:                 /post
          integration:          lambda
          authorizer:           authorizerFunc
          method:               get
          cors:                 true
          request:
            passThrough:        WHEN_NO_TEMPLATES
            template:
              application/json: '{ "action": "list_posts" }'
      - http:
          path:                 /post
          integration:          lambda
          authorizer:           authorizerFunc
          method:               post
          cors:                 true
          request:
            passThrough:        WHEN_NO_TEMPLATES
            template:
              application/json: '{ "action": "create_post", "payload": $input.body }'

Can someone please help me split this file into 2 or 3? Feel free to split it in any way you like (as long as the resulting files have fewer resources individually). It's just that the JS code should remain untouched. Also, please pay close attention to the serverless-aws-alias plugin. That is a crucial part of my service. Of course, the intention is that the deployment of multiple files should be identical to deploying this single file.

Upvotes: 1

Views: 927

Answers (1)

dege
dege

Reputation: 2954

From what I understand you should be able to handle this by spliting the gateway.

Would recommend to first create a serverless.yml with the deployment of shared parts, API Gateway and authorizer

service: api-gw

provider:
  name: aws
  runtime: nodejs12.x
  stage: dev
  region: eu-west-2

functions:
  authorizerFunc:
    handler: handler.handler

plugins:
  - serverless-aws-alias

resources:
  Resources:
    MyApiGW:
      Type: AWS::ApiGateway::RestApi
      Properties:
        Name: MyApiGW

  Outputs:
    apiGatewayRestApiId:
      Value:
        Ref: MyApiGW
      Export:
        Name: MyApiGateway-restApiId

    apiGatewayRestApiRootResourceId:
      Value:
        Fn::GetAtt:
          - MyApiGW
          - RootResourceId
      Export:
        Name: MyApiGateway-rootResourceId

The remaining parts would split depending on the amount of resources:

service: service-users

provider:
  name: aws
  runtime: nodejs12.x
  region: eu-west-2
  apiGateway:
    restApiId:
      'Fn::ImportValue': MyApiGateway-restApiId
    restApiRootResourceId:
      'Fn::ImportValue': MyApiGateway-rootResourceId
    websocketApiId:
      'Fn::ImportValue': MyApiGateway-websocketApiId

plugins:
  - serverless-aws-alias

functions:
  users:
    handler:                    handler.handler
    events:
      - http:
          path:                 /user
          integration:          lambda
          authorizer:
            arn: authorizerFuncARN
          method:               get
          cors:                 true
          request:
            passThrough:        WHEN_NO_TEMPLATES
            template:
              application/json: '{ "action": "list_users" }'
      - http:
          path:                 /user
          integration:          lambda
          authorizer:           
            arn: authorizerFuncARN
          method:               post
          cors:                 true
          request:
            passThrough:        WHEN_NO_TEMPLATES
            template:
              application/json: '{ "action": "create_user", "payload": $input.body }'

There's also an explanation here: https://serverless.com/framework/docs/providers/aws/events/apigateway#easiest-and-cicd-friendly-example-of-using-shared-api-gateway-and-api-resources

You should also consider export your authorizer arn into something that you can reuse later in the other serverless yamls, maybe ssm?

Upvotes: 1

Related Questions