serverfull-gateway

command module
v1.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 18, 2023 License: Apache-2.0 Imports: 7 Imported by: 0

README

Serverfull-Gateway - An AWS API Gateway Stand-In For Serverfull

GoDoc Build Status codecov.io

Status: Incubation

Overview

This project is a compliment to Serverfull and implements a subset of the features offered by the AWS API Gateway Proxy for AWS Lambda. It is built on our other project, transportd, which bundles our HTTP performance and resiliency tooling into a service.

Generally speaking, if you have access to AWS Lambda then it is probably best to use AWS Lambda and the AWS API Gateway Proxy event mapping features that are provided by AWS. This tool is a bit specialized and was conceived to enable:

  • Teams who want to adopt a serverless style of development but without full access to a serverless/FaaS provider such as those who are developing on bare metal or private cloud infrastructures.

  • Teams who are ready to migrate away from AWS Lambda but aren't ready to rewrite large portions of existing code such as those who are either changing cloud providers or moving to EC2 in order to fine-tune the performance characteristics of their runtimes.

We hope to keep the scope of this project small. Our goals for functionality are:

  • Have the gateway, all routes, and input/output validation driven by valid OpenAPI specifications.

  • Adapt between HTTP callers and Lambda functions.

  • Provide reasonable compatibility with AWS API Gateway features as they relate to managing request/response content and linking to AWS Lambda.

We don't intend to add features outside of these goals except as they might be included from transportd.

Quick Start

Everything is driven by an OpenAPI specification. We use extensions to configure the server:

openapi: 3.0.0
# General runtime configuration for the server. For details,
# see the `Runtime Settings` in in the transpord documentation.
x-runtime:
  httpserver:
    address: ":9090"
  logger:
    level: "INFO"
    output: "STDOUT"
  stats:
    output: "DATADOG"
    datadog:
      address: "statsd:8126"
      flushinterval: "10s"
  signals:
    installed:
      - "OS"
    os:
      signals:
        - 2 # SIGINT
        - 15 # SIGTERM
x-transportd:
  backends:
    - app
  app:
    host: "http://app:8080" # Location of the serverfull instance.
    pool:
      ttl: "24h"
      count: 1
info:
  version: 1.0.0
  title: Sample specification
  description: Used for demonstration
  contact:
    name: n/a
    email: na@localhost.com
  license:
    name: Apache 2.0
    url: 'https://www.apache.org/licenses/LICENSE-2.0.html'
paths:
  /:
    post:
      x-transportd:
        backend: app
        enabled:
          - lambda # lambda is the transportd plugin that this project provides.
        lambda:
          arn: "sample" # The name of the lambda as configured in serverfull
          async: false # Fire and forget or wait for a response
          # Go template strings are used to map gateway input to lambda input
          request: '{"value": "#!.Request.Body.inputValue!#"}'
          # Template strings are also used to map lambda output to gateway output
          success: '{"status": 200, "body": {"v":"#!.Response.Body.someValue!#"}}'
          error: '{"status": 500, "bodyPassthrough": true}'
          # See "Templates" for more details
          authenticate: false # Toggle to enable AWS authentication for requests.
          session: # Optional AWS session authentication configuration.
            region: "us-west-2" # Required AWS region for requests (if auth enabled).
            sharedprofile: # Optional profile configuration.
              file: "" # Blank for AWS default location
              profile: "" # Name of the AWS profile defined in the file.
            static: # Optional static credentials
              id: "" # AWS access key ID.
              secret: "" # AWS secret key.
              token: "" # Optional temporary access token.
            assumerole: # Optional assume role credentials.
              role: "" # ARN of the role to assume.
              externalid: "" # Optional cross-account role identifier.
      description: Sample endpoint.
      requestBody:
        required: true
        description: The request body.
        application/json:
          schema:
            type: string
      responses:
        "200":
          description: "Success"

With a configured OpenAPI document:

TRANSPORTD_OPENAPI_SPECIFICATION_FILE="api.yaml" go run main.go

Using The Docker Image

We provide a docker image of the latest build that you can add your specification to:

FROM atlassian/severfull-gateway
COPY api.yaml .
ENV TRANSPORTD_OPENAPI_SPECIFICATION_FILE="api.yaml"

The base container is defined in this project's Dockerfile and uses the scratch base internally.

Configuration

There are a suite of options provided by the transportd service that are documented with that project. This project adds a plugin for transportd that adds the following option block to each path:

lambda:
          arn: "sample" # The name of the lambda as configured in serverfull
          async: false # Fire and forget or wait for a response
          # Go template strings are used to map gateway input to lambda input
          request: '{"value": "#!.Request.Body.inputValue!#"}'
          # Template strings are also used to map lambda output to gateway output
          success: '{"status": 200, "body": {"v":"#!.Response.Body.someValue!#"}}'
          error: '{"status": 500, "bodyPassthrough": true}'

Templates

Request Templates

Lambda functions only receive the POST body of a request to the Invoke API. A good consumer facing API, however, is going to use the breadth of features offered by the OpenAPI specification to define inputs such as putting values in query parameters or URL segments. To bridge the gap we offer a request template configuration that maps incoming HTTP requests to Lambda input payloads. We use the Go template syntax which has its own rich documentation around the format. The two elements of the template feature that we customize in this project are 1) the template delimiters and 2) the content injected into the templates.

Because the { and } characters are so common in JSON we have adjusted them to be the #! pair for open and !# pair for close. Anything within these pairs of characters will be interpreted as template text. When generating a request template, the purpose is to generate a shape that can be serialized to JSON. The shape we inject is:

{
    "Request": {
        "URL": {
            "string": "map[string]string"
        },
        "Query": {
            "string": ["string"]
        },
        "Header": {
            "string": ["string"]
        },
        "Body":{}
    }
}

The shape for errors is the same except that the Body attribute is actually an AWS error body in the form of:

{
    "errorMessage": "string",
    "errorType": "string",
    "stackTrace": ["string"]
}

rather than the response from the Lambda.

Response Templates

Lambda functions have a limited set of response codes they can return and don't come with a rich set of headers. To help with these, we provide the ability to template both success and error responses. The shape injected into success responses is:

{
    "Request": {
        "URL": {
            "string": "string"
        },
        "Query": {
            "string": ["string"]
        },
        "Header": {
            "string": ["string"]
        },
        "Body":{}
    },
    "Response": {
        "Status": 200,
        "Header": {
            "string": ["string"]
        },
        "Body": {}
    }
}

Contributing

License

This project is licensed under Apache 2.0. See LICENSE.txt for details.

Contributing Agreement

Atlassian requires signing a contributor's agreement before we can accept a patch. If you are an individual you can fill out the individual CLA. If you are contributing on behalf of your company then please fill out the corporate CLA.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL