Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support swagger file to serve APIs (external & internal) #101

Closed
zaun opened this issue Aug 30, 2017 · 5 comments
Closed

Support swagger file to serve APIs (external & internal) #101

zaun opened this issue Aug 30, 2017 · 5 comments
Labels
type/feature Feature request

Comments

@zaun
Copy link

zaun commented Aug 30, 2017

I asked this on Stackoverflow too but not much of a response. I think aws-sam-local is still a little new.

I've got a simple project. The basic setup is like this...

project
 |- etc
 |   |- sam.yaml
 |   \- swagger.yaml
 |- src
 |   |- client
 |   |   \- Client files (VUE frontend)
 |   \- backend
 |       |- index.js
 |       \- package.json
 \- gulpfile.js

I run gulp and I end up with a build folder. It looks something like this...

build
 |- client
 |   |- index.html
 |   \- More static client files
 |- backend
 |   |- index.js
 |   |- package.json
 |   \_ node_modules
 |       \- Lots of stuff
 \- backend.zip

The build works great. I want to run it locally rather than uploading the ZIP to lambda and the client directory to S3 every time I make a change.

To do this I'm running aws-sam-local. Yes I have docker installed and running. From the project folder I run this...

sam local start-api -t etc/sam.yaml -s ../build/client/

Now I can go to my browser and visit http://localhost:3000/ to see things. As expected my static files (index.html) load up just fine. But when I try to access an API route http://localhost:3000/test I get a 404.

My sam.yaml

---
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: AWS SAM template with API defined in an external Swagger file along with Lambda integrations and CORS configurations
Resources:
  ApiGatewayApi:
    Type: AWS::Serverless::Api
    Properties:
      DefinitionUri: ../etc/swagger.yaml
      StageName: Prod
      Variables:
        LambdaFunctionName: !Ref LambdaFunction

  LambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: ../build/backend/
      Handler: index.handler
      Runtime: nodejs6.10
      Events:
        ProxyApiRoot:
          Type: Api
          Properties:
            RestApiId: !Ref ApiGatewayApi
            Path: /
            Method: ANY
        ProxyApiGreedy:
          Type: Api
          Properties:
            RestApiId: !Ref ApiGatewayApi
            Path: /{proxy+}
            Method: ANY

Outputs:
  ApiUrl:
    Description: URL of your API endpoint
    Value: !Join
      - ''
      - - https://
        - !Ref ApiGatewayApi
        - '.execute-api.'
        - !Ref 'AWS::Region'
        - '.amazonaws.com/Prod'

My swagger.yaml

---
swagger: 2.0
basePath: /prod
info:
  title: HACC
schemes:
- https
paths:
  /:
    x-amazon-apigateway-any-method:
      produces:
      - application/json
      responses:
        200:
          description: 200 response
          schema:
            $ref: "#/definitions/Empty"
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: 200
        uri: arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:<<accountId>>:function:${stageVariables.LambdaFunctionName}/invocations

        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
    options:
      consumes:
      - application/json
      produces:
      - application/json
      responses:
        200:
          description: 200 response
          schema:
            $ref: "#/definitions/Empty"
          headers:
            Access-Control-Allow-Origin:
              type: string
            Access-Control-Allow-Methods:
              type: string
            Access-Control-Allow-Headers:
              type: string
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: 200
            responseParameters:
              method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
        passthroughBehavior: when_no_match
        requestTemplates:
          application/json: "{\"statusCode\": 200}"
        type: mock
  /{proxy+}:
    x-amazon-apigateway-any-method:
      x-amazon-apigateway-auth:
        type: aws_iam
      produces:
      - application/json
      parameters:
      - name: proxy
        in: path
        required: true
        type: string
      responses: {}
      x-amazon-apigateway-integration:
        uri: arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:<<accountId>>:function:${stageVariables.LambdaFunctionName}/invocations
        httpMethod: POST
        type: aws_proxy
    options:
      consumes:
      - application/json
      produces:
      - application/json
      responses:
        200:
          description: 200 response
          schema:
            $ref: "#/definitions/Empty"
          headers:
            Access-Control-Allow-Origin:
              type: string
            Access-Control-Allow-Methods:
              type: string
            Access-Control-Allow-Headers:
              type: string
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: 200
            responseParameters:
              method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
        passthroughBehavior: when_no_match
        requestTemplates:
          application/json: "{\"statusCode\": 200}"
        type: mock
definitions:
  Empty:
    type: object
    title: Empty Schema

How can I get aws-sam-local to run my lambda API?

@zaun zaun changed the title Trying to get aws-sam-local to serve up my API [Q] Trying to get aws-sam-local to serve up my API Aug 30, 2017
@PaulMaddox
Copy link
Contributor

I think this is a combination of two things:

  1. SAM Local doesn't support API's defined as AWS::Serverless::Api or swagger yet (only functions with event sources of type 'Api')

  2. This bug and the static file hosting we added is preventing the /{proxy+} from working: Proxy resource with a greedy path variable creates incorrect key in pathParameters in event #65

@johnewart
Copy link
Contributor

I encountered this issue as well this week when working on something. I talked with @sanathkr and he's going to look at merging #83 and I'll start working on this.

@PaulMaddox
Copy link
Contributor

Hey @johnewart - just a heads up that #83 is now merged.

@sanathkr sanathkr changed the title [Q] Trying to get aws-sam-local to serve up my API Support swagger file to serve APIs (external & internal) Sep 21, 2017
@sapessi
Copy link
Contributor

sapessi commented Dec 7, 2017

We've just merged #222 - this adds support for Swagger definitions to load mounts in the router. I've tested this with inline Swagger templates.

@PaulMaddox
Copy link
Contributor

I've just released v0.2.3 to npm which includes this.
You can use npm update -g aws-sam-local to update.

@sanathkr sanathkr added the type/feature Feature request label Jan 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type/feature Feature request
Projects
None yet
Development

No branches or pull requests

5 participants