Skip to content

Instantly share code, notes, and snippets.

@ruselknow
Forked from crypticmind/README.md
Created October 17, 2019 22:36
Show Gist options
  • Save ruselknow/29a07aa79880f4a2713ab8c15ff13e31 to your computer and use it in GitHub Desktop.
Save ruselknow/29a07aa79880f4a2713ab8c15ff13e31 to your computer and use it in GitHub Desktop.

Revisions

  1. @crypticmind crypticmind revised this gist Jun 18, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion setup.sh
    Original file line number Diff line number Diff line change
    @@ -15,7 +15,7 @@ awslocal lambda create-function \
    --runtime nodejs8.10 \
    --handler lambda.apiHandler \
    --memory-size 128 \
    --zip-file fileb://apiHandler.zip \
    --zip-file fileb://api-handler.zip \
    --role arn:aws:iam::123456:role/irrelevant

    [ $? == 0 ] || fail 1 "Failed: AWS / lambda / create-function"
  2. @crypticmind crypticmind revised this gist Jun 18, 2018. 3 changed files with 56 additions and 0 deletions.
    20 changes: 20 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,20 @@

    ## About

    Example on how to run locally an AWS Lambda via API Gateway using [localstack](https://github.com/localstack/localstack).

    Based on...
    1. https://stackoverflow.com/questions/44547574/create-api-gateway-in-localstack/48682628
    1. https://ig.nore.me/2016/03/setting-up-lambda-and-a-gateway-through-the-cli/

    ## Usage

    1. Build a zip containing `lambda.js`, name it `api-handler.zip`
    1. Launch localstack in whatever way you can. See sample `docker-compose.yml`.
    1. Run `setup.sh`

    ## Pending

    1. ~~Catch any URL `/api/whatever`~~.
    1. Pass all HTTP verbs. Only `GET` is configured here. Other verbs require their own integration as `ANY` [is not supported yet](https://github.com/localstack/localstack/issues/667).
    1. No query parameters yet.
    18 changes: 18 additions & 0 deletions docker-compose.yml
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,18 @@
    version: '2.1'

    services:
    localstack:
    image: localstack/localstack
    ports:
    - "4567-4583:4567-4583"
    - "${PORT_WEB_UI-4566}:${PORT_WEB_UI-8080}"
    environment:
    - SERVICES=${SERVICES-lambda,apigateway }
    - DEBUG=${DEBUG- }
    - DATA_DIR=${DATA_DIR- }
    - PORT_WEB_UI=${PORT_WEB_UI- }
    - LAMBDA_EXECUTOR=${LAMBDA_EXECUTOR-docker-reuse }
    - KINESIS_ERROR_PROBABILITY=${KINESIS_ERROR_PROBABILITY- }
    - DOCKER_HOST=unix:///var/run/docker.sock
    volumes:
    - "/var/run/docker.sock:/var/run/docker.sock"
    18 changes: 18 additions & 0 deletions lambda.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,18 @@
    'use strict'

    const apiHandler = (payload, context, callback) => {
    console.log(`Function apiHandler called with payload ${JSON.stringify(payload)}`);
    callback(null, {
    statusCode: 201,
    body: JSON.stringify({
    message: 'Hello World'
    }),
    headers: {
    'X-Custom-Header': 'ASDF'
    }
    });
    }

    module.exports = {
    apiHandler,
    }
  3. @crypticmind crypticmind created this gist Jun 18, 2018.
    81 changes: 81 additions & 0 deletions setup.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,81 @@
    #!/bin/sh

    API_NAME=api
    REGION=us-east-1
    STAGE=test

    function fail() {
    echo $2
    exit $1
    }

    awslocal lambda create-function \
    --region ${REGION} \
    --function-name ${API_NAME} \
    --runtime nodejs8.10 \
    --handler lambda.apiHandler \
    --memory-size 128 \
    --zip-file fileb://apiHandler.zip \
    --role arn:aws:iam::123456:role/irrelevant

    [ $? == 0 ] || fail 1 "Failed: AWS / lambda / create-function"

    LAMBDA_ARN=$(awslocal lambda list-functions --query "Functions[?FunctionName==\`${API_NAME}\`].FunctionArn" --output text --region ${REGION})

    awslocal apigateway create-rest-api \
    --region ${REGION} \
    --name ${API_NAME}

    [ $? == 0 ] || fail 2 "Failed: AWS / apigateway / create-rest-api"

    API_ID=$(awslocal apigateway get-rest-apis --query "items[?name==\`${API_NAME}\`].id" --output text --region ${REGION})
    PARENT_RESOURCE_ID=$(awslocal apigateway get-resources --rest-api-id ${API_ID} --query 'items[?path==`/`].id' --output text --region ${REGION})

    awslocal apigateway create-resource \
    --region ${REGION} \
    --rest-api-id ${API_ID} \
    --parent-id ${PARENT_RESOURCE_ID} \
    --path-part "{somethingId}"

    [ $? == 0 ] || fail 3 "Failed: AWS / apigateway / create-resource"

    RESOURCE_ID=$(awslocal apigateway get-resources --rest-api-id ${API_ID} --query 'items[?path==`/{somethingId}`].id' --output text --region ${REGION})

    awslocal apigateway put-method \
    --region ${REGION} \
    --rest-api-id ${API_ID} \
    --resource-id ${RESOURCE_ID} \
    --http-method GET \
    --request-parameters "method.request.path.somethingId=true" \
    --authorization-type "NONE" \

    [ $? == 0 ] || fail 4 "Failed: AWS / apigateway / put-method"

    awslocal apigateway put-integration \
    --region ${REGION} \
    --rest-api-id ${API_ID} \
    --resource-id ${RESOURCE_ID} \
    --http-method GET \
    --type AWS_PROXY \
    --integration-http-method POST \
    --uri arn:aws:apigateway:${REGION}:lambda:path/2015-03-31/functions/${LAMBDA_ARN}/invocations \
    --passthrough-behavior WHEN_NO_MATCH \

    [ $? == 0 ] || fail 5 "Failed: AWS / apigateway / put-integration"

    awslocal apigateway create-deployment \
    --region ${REGION} \
    --rest-api-id ${API_ID} \
    --stage-name ${STAGE} \

    [ $? == 0 ] || fail 6 "Failed: AWS / apigateway / create-deployment"

    ENDPOINT=http://localhost:4567/restapis/${API_ID}/${STAGE}/_user_request_/HowMuchIsTheFish

    echo "API available at: ${ENDPOINT}"

    echo "Testing GET:"
    curl -i ${ENDPOINT}

    echo "Testing POST:"
    curl -iX POST ${ENDPOINT}