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

Proposal: Less server serverless applications #857

Open
rhboyd opened this issue Mar 15, 2019 · 3 comments
Open

Proposal: Less server serverless applications #857

rhboyd opened this issue Mar 15, 2019 · 3 comments

Comments

@rhboyd
Copy link

rhboyd commented Mar 15, 2019

I would like to be able to use SAM to directly proxy requests from API Gateway to DynamoDB. It feels like Lambda sits at the center of SAM and almost all of the features are geared towards shuttling data through Lambda with as little friction as possible. If I wanted to create an API that allowed a user to POST some data, which was mapped to a DynamoDB PutItem request, then a lambda processed the stream of changes to DynamoDB, I wouldn't be able to easily do this today with SAM. I would have to create a function that sits behind the API and accepts the item, (maybe processes it), puts it in dynamo, then returns a status code to the client. This can take about 100ms per request and I'm capped at 1000 concurrent executions before my clients start to get error messages. By allowing a direct APIG<->DDB integration, the client gets a response in ~10m, I can batch updates to my Lambda function, and I can build a more event-driven architecture.

I think an awesome approach would be something like:

AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: 'API Gateway to data store'
Resources:
  StreamProcessor:
    Type: 'AWS::Serverless::Function'
    Properties:
      CodeUri: '.'
      Handler: 'routes/root.handler'
      Runtime: 'nodejs8.10'
      Events:
      Events:
        DynamoDB1:
          Type: DynamoDB
          Properties:
            Stream:
              'Fn::GetAtt':
                - Table1
                - StreamArn
            StartingPosition: TRIM_HORIZON
            BatchSize: 100
  Table1:
      Type: AWS::Serverless::SimpleTable
      Properties:
        PrimaryKey:
          Name: id
          Type: String
        ProvisionedThroughput:
          ReadCapacityUnits: 5
          WriteCapacityUnits: 5
        Events:
          PUT:
            Type: 'Api'
            Properties:
              Path: '/test'
              Method: 'post'
          UPDATE:
            Type: 'Api'
            Properties:
              Path: '/test'
              Method: 'update'

When a user performs a POST request the "id" field from the request body is mapped to the partition key, remaining fields in the body can be mapped to other items, then API Gateway puts the item directly in the Table and returns a response to the user.

@keetonian
Copy link
Contributor

This is an interesting idea. Would be happy to work with someone to implement this. Leaving this up for +1's.

@rhboyd
Copy link
Author

rhboyd commented Mar 26, 2019

@keetonian I have a solution that I'm speaking to the API Gateway team about this week. I'd love to be able to add it to SAM

@rhboyd
Copy link
Author

rhboyd commented Mar 26, 2019

My goal was to make the API Integrations mimic the boto3 sdk calls so if you wanted an API that listed route53 hostedzones, it would look like

GetMethod:

Type: AWS::ApiGateway::Method

'Fn::Transform':

  - Name: SimpleAPI

Properties:

  AuthorizationType: NONE

  RestApiId:

    Ref: RestAPI

  ResourceId:

    Ref: SimpleProxyResource

  HttpMethod: GET

  Integration:

    Credentials:
      Fn::GetAtt:

        - DDBReadRole

        - Arn

    Service: route53

    Action:

     Name: GetHostedZone

     Parameters:

      - Id: "myhostedzonename"

    ResponseMaps:

      # This would map the DelegationSet and HostedZone from the response to an apig response body that looks like

      # {

      #   "myset": [response.DelegationSet],

      #   "hz": [response.HostedZone],

      # }

      Success:

        - DelegationSet: "myset"

        - HostedZone: "hz"

      # this does the same for the InvalidInput exception that may be thrown

      InvalidInput:

        - Message: "error-message"

      # this is behavior to perform for any other exception the service may return

      Failure: #TODO

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants