Serverless-application-model: No integration defined for method when using Swagger

Created on 21 Nov 2016  路  14Comments  路  Source: aws/serverless-application-model

It complains about "No integration defined for method" when trying to use the transformation with Swagger file defined at AWS::Serverless::Api. Maybe we are trying it the wrong way but the idea was to have a swagger file with CORS definitions as well but with no x-amazon-apigateway-integration defined on the actual resource because we want CF to inject it using the Events property. A swagger file example would help us here.

Thanks!

Most helpful comment

I found my way to this issue after trying the same thing as @johanglarsson - defining a Swagger file without x-amazon-apigateway-integration and assuming the integration would be added from the Events properties in my CF file.

@sanathkr clarified the actual behaviour: "When you use a Swagger file, CloudFormation does not inject integrations". That's clear, but it's still rather unfortunate. Is there any intention to support this in the future?

Ideally I'd like to have a Swagger file that simply defines the API and doesn't include any provider-specific extensions. The API Gateway and Lambda configuration details would be confined to the CF file and would not be visible to someone consuming the Swagger file because they want to use the API.

All 14 comments

When you use a Swagger file, CloudFormation does not inject integrations. Your swagger file is passed to API Gateway without any modifications. You should explicitly specify the integrations yourself.

I can update the spec to reflect this information. Or, you can do it yourself thru a pull-request :-)

@sanathkr I've got a related clarifying question here... I've ended up with "No integration defined for method" also with the following setup in my template:

  • An API resource referring to a swagger file

    • The swagger file defines a few related paths e.g.



      • GET /api/myresource


      • POST /api/myresource


      • GET /api/myresource/search/{query}



  • An AWS::Serverless::Function with an API event and

    • Path: /api/myresource/{proxy+}

    • Method: ANY

    • RestApiId: referring to the API noted above

My intent is that the Lambda here will be service ALL requests to /api/myresource/* but I'm assuming the "No integration defined for method" is occurring when I attempt to create the stack because some kind of validation isn't sophisticated enough to tell that Path: /api/myresource/{proxy+} and Method: ANY will provide the integration for the three more specific paths from the swagger file.

Does this sound right? If this is known limitation, I'd be happy to submit a PR to clarify.

I hope this is a bug (and will open a separate issue to track if so) because:

  • I'd like to use the swagger definition to describe the surface area of my API...
  • ... but not dictate the implementation thereof i.e. a 1 to 1 mapping of swagger endpoints to Lambda functions
  • ... instead I'd like to let a single lambda microservice handle several related endpoints.

    • The implementation of the lambda might be a small Express or ASP.NET Core app for example

Do you have x-amazon-apigateway-integration defined in your Swagger? Specifying RestApiId here does not inject integrations into your Swagger. It will simply set the appropriate permissions for APIGateway to invoke your Lambda function. When you specify your own Swagger file, SAM expects you to manage the API configurations.

@sanathkr I had naively hoped that the transformation logic would match up the Method/Path of the Function with the endpoints defined in the swagger template. No such luck ;-). I do now have the x-amazon-apigateway-integration specified and it works. Thanks!

However, it's inconvenient to use a swagger file to attempt to refer to resources created by a SAM template:

  • You can embed the swagger template in the Body property to allow CF template functions to refer to the AWS::Serverless::Function but.. then it's embedded and trickier to manage with swagger tools
  • Or you need to somehow update/sync the swagger file (one approach I tried is here on SO )

Ideally, I'd like to be able to use CF functions in the x-amazon-apigateway-integration section of a swagger file whether it's embedded or linked via BodyS3Location

@jamesandersen Embedding is the only option you can use CF construct in your Swagger. External swagger files are directly passed to APIGateway and CloudFormation has little control over the contents of it

Our use case is common to many adopters of Swagger/OpenAPI: Maintain one Swagger definition to support both server and client side tooling such as deployment (SAM) or documentation generation and client proxy code generation.

For this the swagger definition should be as provider-agnostic as possible so inlining/embedding into a Cloudformation template is not an option. So my hope is that SAM will consider adding _CF_ functionality to handle the replacement of CF references like @jamesandersen described.

Until that happens I'll use a script to handle the replacement of these variables since we need Travis to deploy our APIs for us. Another hope is that the serverless project decides to support Swagger in their AWS integration.

Another workaround as mentioned in https://github.com/awslabs/serverless-application-model/issues/8#issuecomment-285616807, is to simply concatenate the two templates (SAM and Swagger) prior to packaging and deployment. This provides the most flexibility to use both Swagger tools and SAM without having to hard-code any values in the Swagger template. I.e. we can refer to them using the ${} syntax as long as the Api resource is listed last in the SAM template and is using !Sub |- to substitute the actual values in the concatenated Swagger body.

I found my way to this issue after trying the same thing as @johanglarsson - defining a Swagger file without x-amazon-apigateway-integration and assuming the integration would be added from the Events properties in my CF file.

@sanathkr clarified the actual behaviour: "When you use a Swagger file, CloudFormation does not inject integrations". That's clear, but it's still rather unfortunate. Is there any intention to support this in the future?

Ideally I'd like to have a Swagger file that simply defines the API and doesn't include any provider-specific extensions. The API Gateway and Lambda configuration details would be confined to the CF file and would not be visible to someone consuming the Swagger file because they want to use the API.

As a workaround, you can remove x- keys from your swagger file. That's what we do and just serve vanilla JSON to the client.

@sanathkr

I facing the same error "No integration defined for method" even with "x-amazon-apigateway-integration" in the swagger file. Do you see anything wrong with the below definition?

 /service_name:
    x-amazon-apigateway-any-method:
      x-amazon-apigateway-auth:
        type: aws_iam
      consumes:
        - application/json
      produces:
        - application/json
      responses: 
        '200': 
          description: OK
      x-amazon-apigateway-integration:
        post:
          requestTemplates:
            application/json:
              schema:
                type: object
                properties:
                  property1: 
                    type: string
                  property2:
                    type: string
          httpMethod: POST
          type: aws_proxy
          uri: xxxxx

Appreciate your feedback as I am stuck here for a while.

I am doing a PoC on SAM templates in order to create some reference implementations as part of the wider Microservices initiatives. So I would like to resolve all issues before moving in to next stage.

Thanks

Best regards,
Bala

Can you paste the Swagger template with proper code formatting?

Checkout this example which should give you a good starting point of how to use Swagger - https://github.com/awslabs/serverless-application-model/tree/master/examples/2016-10-31/api_swagger_cors

@sanathkr corrected the formatting above, missed the triple backticks as I am new to github. Apologies for that.

Hi, It will be great help to users if there was native support for integration with Swagger. For projects, a simple CD pipeline would look like -

  • Define API in swagger for internal and external consumers
  • Define lambda functions in CF template with reference to path defined in swagger
  • Deploy
    If I understand correctly, The second step actually requires that Swagger definitions link to functions via x-amazon-apigateway-integration which makes it tricky IMHO.
    Not much has changed in 1.5 years since this issue was opened so I guess its not a priority. It would be great if it was made simple though 馃槂

Unfortunately, this is a technical limitation outside the realm of SAM. For now you will need to make do with the provided workarounds https://github.com/awslabs/serverless-application-model/issues/8#issuecomment-290212883

Was this page helpful?
0 / 5 - 0 ratings