shaunc
shaunc

Reputation: 5611

deploy multiple services using serverless to Apigateway with shared path

The documentation addresses shared paths:

service: service-b
provider:
  apiGateway:
    restApiId: xxxxxxxxxx
    restApiRootResourceId: xxxxxxxxxx
    restApiResources:
      /reports: xxxxxxxxxx

functions:
  ...

However, how can I reference the ID of the resource (the path, that is)? In the first service I have:

  Outputs:
    apiGatewayRestApiId:
      Value:
        Ref: ApiGatewayRestApi
      Export:
        Name: ${self:service}-${opt:stage, 'dev'}-apiGateway-restApiId
    apiGatewayRestApiRootResourceId:
      Value:
         Fn::GetAtt:
          - ApiGatewayRestApi
          - RootResourceId
      Export:
        Name: ${self:service}-${opt:stage, 'dev'}-apiGateway-rootResourceId
    apiGatewayResourceReports:
      Value: !Ref ApiGatewayResource/reports
      Export:
        Name: ${self:service}-${opt:stage, 'dev'}-apiGateway-reportPath

The first two work, and can be referred to with FN::ImportValue in the 2nd service. However, the third doesn't work. I presume the problem is that I have to explicitly create the resource ApiGatewayResource/reports rather than have it created as a side effect of the function definitions in the first service. But how should I do that? And won't it conflict with the function definitions?

Upvotes: 1

Views: 870

Answers (1)

shaunc
shaunc

Reputation: 5611

After some floundering, I hit upon the following: the first service should define the resource path, but leave the rest of the gateway definition implicit. And it should output the relevant ids:

provider:
  apiGateway:
    restApiResources:
      /reports: !Ref ReportPath

...
resources:
  Resources:
    ReportPath:
      Type: AWS::ApiGateway::Resource
      Properties:
        RestApiId: !Ref ApiGatewayRestApi
        ParentId:
          Fn::GetAtt: [ ApiGatewayRestApi, RootResourceId ]
        PathPart: 'reports'

  Outputs:
    apiGatewayRestApiId:
      Value:
        Ref: ApiGatewayRestApi
      Export:
        Name: ${self:service}-${opt:stage, 'dev'}-apiGateway-restApiId
    apiGatewayRestApiRootResourceId:
      Value:
         Fn::GetAtt:
          - ApiGatewayRestApi
          - RootResourceId
      Export:
        Name: ${self:service}-${opt:stage, 'dev'}-apiGateway-rootResourceId
    apiGatewayResourceReports:
      Value: !Ref ReportPath
      Export:
        Name: ${self:service}-${opt:stage, 'dev'}-apiGateway-reportPath

The 2nd service can reference all three ids:

provider:
  apiGateway:
    restApiId:
      'Fn::ImportValue': crane-mg-reports-${opt:stage, 'dev'}-apiGateway-restApiId
    restApiRootResourceId:
      'Fn::ImportValue': crane-mg-reports-${opt:stage, 'dev'}-apiGateway-rootResourceId
    restApiResources:
      /reports:
        'Fn::ImportValue': crane-mg-reports-${opt:stage, 'dev'}-apiGateway-reportPath

In both cases, the function definition can define paths using /reports prefix without conflict.

Upvotes: 2

Related Questions