Last active
August 10, 2017 15:59
-
-
Save justinsoliz/95aadf1ce9ce4114915ed2552dcd260d to your computer and use it in GitHub Desktop.
express + aws serverless proxy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Show hidden characters
{ | |
"presets": [ "es2015", "flow" ], | |
"plugins": ["transform-object-rest-spread"] | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"parser": "babel-eslint", | |
"extends": [ | |
"eslint:recommended", | |
"plugin:flowtype/recommended" | |
], | |
"env": { | |
"browser": false, | |
"node": true, | |
"mocha": true, | |
"es6": true, | |
"jest": true | |
}, | |
"parserOptions": { | |
"ecmaVersion": 6, | |
"sourceType": "module", | |
"ecmaFeatures": { | |
"experimentalObjectRestSpread": true | |
} | |
}, | |
"rules": { | |
"quotes": [2, "single", { "avoidEscape": true, "allowTemplateLiterals": true }] | |
}, | |
"plugins": [ "flowtype" ] | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import express from 'express'; | |
const app = express(); | |
app.get('/', (req, res) => { | |
res.setHeader('X-API-Version', '1.0.0'); | |
res.status(200).json({ success: true }); | |
}); | |
app.get('/health-check', (req, res) => { | |
res.setHeader('X-API-Version', '1.0.0'); | |
res.status(200).json({ healthCheck: true }); | |
}); | |
export default app; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import request from 'supertest'; | |
import app from '../index'; | |
import { version } from './package.json'; | |
describe('Health check', () => { | |
it('should complete health check with correct version', () => { | |
return request(app).get('/health-check') | |
.expect(200) | |
.then(res => { | |
expect(res.headers['x-api-version']).toEqual(version); | |
}); | |
}); | |
it('should complete health check', () => { | |
return request(app).get('/health-check') | |
.expect(200); | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import awsServerlessExpress from 'aws-serverless-express'; | |
import app from './'; | |
const server = awsServerlessExpress.createServer(app); | |
exports.handler = (event, context) => | |
awsServerlessExpress.proxy(server, event, context); | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
provider "aws" { | |
region = "${var.aws_region}" | |
} | |
# API Gateway | |
resource "aws_api_gateway_rest_api" "demo_api" { | |
name = "demo_api" | |
} | |
resource "aws_api_gateway_deployment" "demo_api_deployment" { | |
depends_on = [ | |
"aws_api_gateway_method.demo_method", | |
"aws_api_gateway_integration_response.api_demo_integration_response" | |
] | |
rest_api_id = "${aws_api_gateway_rest_api.demo_api.id}" | |
stage_name = "demo" | |
variables = { | |
"version" = "1.0.0" | |
} | |
} | |
resource "aws_api_gateway_method" "demo_method" { | |
rest_api_id = "${aws_api_gateway_rest_api.demo_api.id}" | |
resource_id = "${aws_api_gateway_resource.demo_proxy_resource.id}" | |
http_method = "ANY" | |
authorization = "NONE" | |
} | |
resource "aws_api_gateway_resource" "demo_proxy_resource" { | |
rest_api_id = "${aws_api_gateway_rest_api.demo_api.id}" | |
parent_id = "${aws_api_gateway_rest_api.demo_api.root_resource_id}" | |
path_part = "{proxy+}" | |
} | |
resource "aws_api_gateway_integration" "demo_integration" { | |
depends_on = [ | |
"aws_api_gateway_resource.demo_proxy_resource" | |
] | |
rest_api_id = "${aws_api_gateway_rest_api.demo_api.id}" | |
resource_id = "${aws_api_gateway_resource.demo_proxy_resource.id}" | |
http_method = "${aws_api_gateway_method.demo_method.http_method}" | |
integration_http_method = "POST" | |
type = "AWS_PROXY" | |
uri = "arn:aws:apigateway:${var.aws_region}:lambda:path/2015-03-31/functions/${aws_lambda_function.demo_api_gateway_lambda.arn}/invocations" | |
} | |
resource "aws_api_gateway_method_response" "200" { | |
rest_api_id = "${aws_api_gateway_rest_api.demo_api.id}" | |
resource_id = "${aws_api_gateway_resource.demo_proxy_resource.id}" | |
http_method = "${aws_api_gateway_method.demo_method.http_method}" | |
status_code = "200" | |
response_models = { | |
"application/json" = "Empty" | |
} | |
} | |
resource "aws_api_gateway_integration_response" "api_demo_integration_response" { | |
depends_on = [ | |
"aws_api_gateway_method.demo_method", | |
"aws_api_gateway_method_response.200" | |
] | |
rest_api_id = "${aws_api_gateway_rest_api.demo_api.id}" | |
resource_id = "${aws_api_gateway_resource.demo_proxy_resource.id}" | |
http_method = "${aws_api_gateway_method.demo_method.http_method}" | |
status_code = "${aws_api_gateway_method_response.200.status_code}" | |
response_templates = { | |
"application/json" = "" | |
} | |
} | |
# Lambda | |
resource "aws_lambda_permission" "apigw_lambda" { | |
statement_id = "AllowExecutionFromAPIGateway" | |
action = "lambda:InvokeFunction" | |
function_name = "${aws_lambda_function.demo_api_gateway_lambda.arn}" | |
principal = "apigateway.amazonaws.com" | |
source_arn = "arn:aws:execute-api:${var.aws_region}:${var.aws_account}:${aws_api_gateway_rest_api.demo_api.id}/*/*/*" | |
} | |
resource "aws_lambda_function" "demo_api_gateway_lambda" { | |
s3_bucket = "terraform-packages" | |
s3_key = "api.zip" | |
function_name = "api_gateway_demo_lambda_function" | |
role = "${aws_iam_role.demo_api_gateway_lambda_role.arn}" | |
handler = "lib/lambda_handler.handler" | |
runtime = "nodejs4.3" | |
timeout = "15" | |
environment = { | |
variables = { | |
NODE_ENV = "production" | |
} | |
} | |
} | |
# IAM | |
resource "aws_iam_role" "demo_api_gateway_lambda_role" { | |
name = "demo-api-gateway-lambda-role" | |
assume_role_policy = <<POLICY | |
{ | |
"Version": "2012-10-17", | |
"Statement": [ | |
{ | |
"Action": "sts:AssumeRole", | |
"Principal": { | |
"Service": "lambda.amazonaws.com" | |
}, | |
"Effect": "Allow", | |
"Sid": "" | |
} | |
] | |
} | |
POLICY | |
} | |
resource "aws_iam_role_policy_attachment" "lambda_iam_policy_basic_execution" { | |
role = "${aws_iam_role.demo_api_gateway_lambda_role.id}" | |
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "demo_api", | |
"version": "1.0.0", | |
"description": "", | |
"main": "index.js", | |
"private": true, | |
"scripts": { | |
"start": "babel-node ./lib/server.js", | |
"test": "jest -i --coverage ./test/**/*.spec.js", | |
"compile": "babel lib -d ./.build/lib", | |
"lint": "eslint lib/**/*.js test/**/*.js --cache" | |
}, | |
"author": "", | |
"license": "ISC", | |
"devDependencies": { | |
"babel-cli": "^6.5.1", | |
"babel-core": "^6.5.2", | |
"babel-jest": "^19.0.0", | |
"babel-preset-es2015": "^6.5.0", | |
"eslint": "^3.0.0", | |
"jest": "^19.0.2", | |
"supertest": "^3.0.0" | |
}, | |
"dependencies": { | |
"aws-serverless-express": "^2.2.0", | |
"cors": "^2.7.1", | |
"express": "^4.13.4" | |
}, | |
"jest": { | |
"automock": false, | |
"testEnvironment": "node" | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import axios from 'axios'; | |
import { version } from './package.json'; | |
import { apiHost } from './config'; | |
describe('Health Check Regression Tests', () => { | |
let client; | |
beforeEach(() => { | |
client = axios.create({ baseURL: `http://${apiHost}` }); | |
}); | |
it('should return correct api version', () => { | |
return client.get('/health-check').then(res => { | |
expect(res.status).toEqual(200); | |
expect(res.headers['x-api-version']).toEqual(version); | |
}); | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import app from './index'; | |
const port = 8000; | |
app.listen(port, (err) => { | |
if (err) { | |
console.log('error', err); | |
} else { | |
console.log('info', '==> 🌎 Listening on port %s. Open up http://localhost:%s/ in your browser.', port, port) | |
} | |
}); | |
export default app; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment