aws / chalice

Python Serverless Microframework for AWS
Apache License 2.0
10.52k stars 1.01k forks source link

APIGateway configuration #564

Open ehault opened 6 years ago

ehault commented 6 years ago

I may have missed but I couldn't find any way to configure APIGateway, and particularly the schemas.

Since schemas are usually very close to models, it would be nice to be able to associate a schema to a route inside app.py, rather than packaging and doing it in sam.json

This is the only step i need to truly have a one command deploy of my chalice app.

Thoughts?

kyleknap commented 6 years ago

Chalice does not have support for this. I can see it being useful though. Marking as a feature request.

ehault commented 6 years ago

I will try to come up with a proper request document tomorrow (how it could be used, the expected effects and so on, as well as how to achieve the same result through bash scripting and the deploy process)

ehault commented 6 years ago

Add schema validation to chalice core concepts

Chalice is a simple yet powerful tool allowing one to very quickly deploy an api on AWS serverless architecture. Yet, one of the core APIGateway concept (requestValidators) is not implemented, and is one of its most time saving feature.

This document tries to walk through an interface design for such a feature, and provide equivalent (yet painful) work arounds in order to facilitate development.

This could be extended in the future for other APIGateway configuration settings.

It is understood that some part of the generation are standard, those are not covered, but a link is given in the resource showing a complete swagger file with request validation.

This document only covers the body validation, but it is understood that param validations would be very close.

Interface


# this will populate the APIGateway.models (so the #/definitions for schema $refs)

# with the users_schemas looking something like:
# {
#  "type": "object",
#  "properties": {
#    "users": {
#       "type": "array"
#    }
#  },
#  "required": ["users"]
# }
app.schemas = [
   {"usersSchema": "/path/to/json/file/users_schemas.json"},
]

# this will associate a validator of type at top level if it doesn't exist
#   "x-amazon-apigateway-request-validators" : {
#     "bodytrueparamsfalse" : {
#       "validateRequestBody" : true,
#       "validateRequestParameters" : false
#    }
# as well as, in the method definition:
#    "x-amazon-apigateway-request-validator" : "bodytrueparamsfalse",
#    "parameters": [
#      {
#        "in": "body",
#        "name": "usersSchema",
#        "required": true,
#        "schema": {
#          "$ref": "#/definitions/usersSchema"
#        }
#      }
# note that chalice.Validator could take a number of arguments like validatorName (would
# replace bodytrueparamsfalse), requestParamaters and so on
# If possible, the schema would be expended and validated during the deploy
@app.route('/users', methods=['POST'], validators=chalice.Validator(body="usersSchema", required=True), cors=True)
def create_users():
    payload = app.current_request.json_body
    users = [User.from_dict(u) for u in payload['users']] # this assumes the 'users' key exists, hence the schema
    created_users = api.create_users(users)
    return [u.to_dict() for u in created_users]

Workaround

There is currently a way to do that manually, this section explain how to achieve a similar (yet slightly different) result.

package

chalice package <packagename>

with whatever you want

edit swagger file

Here, edit /sam.json and add:

"definitions": {
    "usersSchema": <schema>
}
"x-amazon-apigateway-request-validators" : {
  "usersPost" : {
    "validateRequestBody" : true,
    "validateRequestParameters" : false
  },
}
"x-amazon-apigateway-request-validator" : "usersPost",
"parameters": [
  {
    "in": "body",
    "name": "usersSchema",
    "required": true,
    "schema": {
      "$ref": "#/definitions/usersSchema"
    }
  }
],

flip it like it's hot

cfn-flip <packagename>/sam.json  > template.yml

create bucket

aws s3 mb s3://<bucketname> --region <region>

with whatever and you want

repackage

aws cloudformation package --template-file template.yml --output-template-file serverless-output.yml --s3-bucket <bucketname>

deploy

aws cloudformation deploy --template-file serverless-output.yml --stack-name <stackname> --capabilities CAPABILITY_IAM

with whatever you want

You now should have your API deployed and validated through the schema supplied

Resources

Transform chalice template to standard CF template

https://github.com/awslabs/aws-cfn-template-flip

Add request validator to swaggerfile (sam.json)

http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-validation-sample-api-swagger.html

Deploy a chalice package manually

http://docs.aws.amazon.com/lambda/latest/dg/serverless-deploy-wt.html#serverless-deploy

ehault commented 6 years ago

@kyleknap if you could give me your thoughts on this so I can improve it that would be great ^^^

Logerfo commented 1 year ago

I might be wrong, but I think this would be particularly useful to validate webhook secret tokens like this one at gateway site, avoiding the lambda call if unsuccessful.