むろっちのStacking

日々の中で学んだIT知識をメモして置く場所

API Gateway & lambda FunctionでRedirectするEndpointを作成するサンプル

Lambda + API GatewayAPI Gateway宛に来たリクエストをRedirectするEndpointをAWS-CDKで作成してみた

構成


全体図

f:id:murochi:20200607175000p:plain
構成

API

f:id:murochi:20200607175718p:plain

API Gatewayとカスタムドメインマッピングは含まない

コード


流れ

  • redirect用Functionをを作成①
  • aws-cdkのstackクラス実装②
  • cdkのentryPoint作成③
# Directory構成

./bin
├── redirect.ts  //cdkのエントリポイント ③

./lib
├── redirect
│   ├── index.ts // stack Classの実装 ②
│   └── resources
│       └── main.js //lambda用 ①

redirect用Functionを作成 ①


  • queryString、pathをredirect先に引き継ぐ形
// main.js

const qs = require('querystring');

exports.handler = async (event) => {
    const {
        multiValueQueryStringParameters: qsParams,
        pathParameters,
    } = event;
    
    const queryString = qs.stringify(qsParams);
    const path = pathParameters ? pathParameters.proxy : '';
    let redirectURL;
    
    if (qsParams) {
        redirectURL = `https://anotherdomain.com/${path}?${queryString}`;
    } else {
        redirectURL = `https://anotherdomain.com/${path}`;
    }
    
    const response = {
        statusCode: 301,
        headers: {
            Location: redirectURL
        }
    };
    return response;
};

aws-cdkのstackクラス実装②


  • 上記で作成したコードはresources/main.jsに配置
// redirect/index.ts

import * as apigateway from "@aws-cdk/aws-apigateway";
import * as lambda from "@aws-cdk/aws-lambda";
import * as s3 from "@aws-cdk/aws-s3";
import * as cdk from "@aws-cdk/core";

export class RedirectService extends cdk.Construct {
  constructor(scope: cdk.Construct, id: string) {
    super(scope, id);

    const bucket = new s3.Bucket(this, "RedirectLambdaHandlerBucket", {
      removalPolicy: cdk.RemovalPolicy.DESTROY
    });

    const handler = new lambda.Function(this, "RedirectHandler", {
      runtime: lambda.Runtime.NODEJS_12_X,
      code: lambda.AssetCode.asset("lib/redirect/resources"),
      handler: "main.handler"
    });

    bucket.grantReadWrite(handler);

    const api = new apigateway.RestApi(this, "redirect-api", {
      restApiName: "redirect-api"
    });

    const redirectIntegration = new apigateway.LambdaIntegration(handler, {
      requestTemplates: { "application/json": '{ "statusCode": "200" }' }
    });

    api.root.addMethod("ANY", redirectIntegration);
    api.root.addProxy({
      anyMethod: true,
      defaultIntegration: redirectIntegration
    });
  }
}

export class RedirectStack extends cdk.Stack {
  constructor(app: cdk.App, id: string, props?: cdk.StackProps) {
    super(app, id, props);
    new RedirectService(this, "RedirectService");
  }
}

cdk Entry Point作成③


#!/usr/bin/env node
import * as cdk from "@aws-cdk/core";
import { RedirectStack } from "../lib/redirect";

const ACCOUNT = "123456890"; // dummy
const app = new cdk.App();

new RedirectStack(app, "RedirectStack", {
  env: {
    region: "ap-northeast-1",
    account: ACCOUNT
  }
});

app.synth();

実行

npx cdk -a 'npx ts-node bin/redirect.ts' deploy