frricks / network-gateway

A network gateway implemented in go

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

About

In Todays' why would you go with RPC style for API Gateway? While it's a great tool for avoiding backend server maintenance, API Gateway provides a very convoluted and unintuitive interface for creating APIs. Defining an API is not hard, they really took something simple and made it more difficult. Many of API Gateway's features are unnecessary unless you're re-mapping a legacy API, so it can be much simpler to (ab)use API Gateway's scaling capabilities while effectively ignoring its other features.

With this package you just define a struct full of methods, and public methods will be exposed via HTTP. This is similar to Dropbox's V2 API.

Setup

Create an API Gateway route of POST /{method}, pointing to your Lambda function, then use the mapping template below to relay the request. Note that the parameter name of "{method}" is important.

Then create your Lambda function. This package implements the apex.Handler, so an implementation may look something like this:

package main

import (
  "github.com/tj/go-gateway"
  "github.com/apex/go-apex"
)

type Math struct{}

type AddInput struct {
	A int `json:"a"`
	B int `json:"b"`
}

func (m *Math) Add(in *AddInput) (int, error) {
	return in.A + in.B, nil
}

func (m *Math) Sub(in *AddInput) (int, error) {
	return in.A - in.B, nil
}

func main() {
  apex.Handle(gateway.New(&Math{}))
}

Deploy the API and you'll be able to invoke /Add or /Sub with the request body { "a": 5, "b": 10 }. Note that snake-case is also supported, so /add or /sub work here as well. If you'd like to separate by resource, simply deploy functions to /pets/{method}, /books/{method} and so on.

Mapping the idea (In Lambda function)

#set($allParams = $input.params())
{
"body" : $input.json('$'),
"params" : {
#foreach($type in $allParams.keySet())
    #set($params = $allParams.get($type))
"$type" : {
    #foreach($paramName in $params.keySet())
    "$paramName" : "$util.escapeJavaScript($params.get($paramName))"
        #if($foreach.hasNext),#end
    #end
}
    #if($foreach.hasNext),#end
#end
},
"context" : {
    "account-id" : "$context.identity.accountId",
    "api-id" : "$context.apiId",
    "api-key" : "$context.identity.apiKey",
    "authorizer-principal-id" : "$context.authorizer.principalId",
    "caller" : "$context.identity.caller",
    "cognito-authentication-provider" : "$context.identity.cognitoAuthenticationProvider",
    "cognito-authentication-type" : "$context.identity.cognitoAuthenticationType",
    "cognito-identity-id" : "$context.identity.cognitoIdentityId",
    "cognito-identity-pool-id" : "$context.identity.cognitoIdentityPoolId",
    "http-method" : "$context.httpMethod",
    "stage" : "$context.stage",
    "source-ip" : "$context.identity.sourceIp",
    "user" : "$context.identity.user",
    "user-agent" : "$context.identity.userAgent",
    "user-arn" : "$context.identity.userArn",
    "request-id" : "$context.requestId",
    "resource-id" : "$context.resourceId",
    "resource-path" : "$context.resourcePath"
    }
}

Reference request

The request received by go-gateway looks something like the following:

{
  "body": {
    "a": 5,
    "b": 5
  },
  "params": {
    "path": {
      "method": "Add"
    },
    "querystring": {},
    "header": {
      "Accept": "*/*",
      "CloudFront-Forwarded-Proto": "https",
      "CloudFront-Is-Desktop-Viewer": "true",
      "CloudFront-Is-Mobile-Viewer": "false",
      "CloudFront-Is-SmartTV-Viewer": "false",
      "CloudFront-Is-Tablet-Viewer": "false",
      "CloudFront-Viewer-Country": "CA",
      "Content-Type": "application/json",
      "Host": "whatever.execute-api.us-west-2.amazonaws.com",
      "User-Agent": "curl/7.43.0",
      "Via": "1.1 fc8d4c3a573bbd496e96047052c4d3f1.cloudfront.net (CloudFront)",
      "X-Amz-Cf-Id": "RW7zWvoOaoxsxWM_OPEadaqJf_rTQg5Pkfu4SMAruaULcqYH0K9MUA==",
      "X-Forwarded-For": "70.66.179.182, 54.182.214.52",
      "X-Forwarded-Port": "443",
      "X-Forwarded-Proto": "https"
    }
  },
  "context": {
    "account-id": "",
    "api-id": "whatever",
    "api-key": "",
    "authorizer-principal-id": "",
    "caller": "",
    "cognito-authentication-provider": "",
    "cognito-authentication-type": "",
    "cognito-identity-id": "",
    "cognito-identity-pool-id": "",
    "http-method": "POST",
    "stage": "prod",
    "source-ip": "70.66.179.182",
    "user": "",
    "user-agent": "curl/7.43.0",
    "user-arn": "",
    "request-id": "55066e03-19f7-11e6-8e97-231379f58d27",
    "resource-id": "cppmxl",
    "resource-path": "/public/{method}"
  }
}

About

A network gateway implemented in go


Languages

Language:Go 100.0%