見出し画像

Amazon API GatewayとAWS Lambda、EJSを使用してHTMLを返すAPIを作成してみた

はじめに

パーソルホールディングス株式会社 グループデジタル変革推進本部 エンゲージメントプロダクト開発部 鈴木です。

今回はAmazon API GatewayとAWS Lambda、Node.js、EJSを組み合わせて、HTMLを返すAPIを作成してみます。

Node.jsを使用していますが、他の言語・テンプレートエンジン(例えばPythonとJinja2の組み合わせなど)でも同様の仕組みで実現可能なはずです。

全体の構成

API Gatewayの後にLambda関数を置きます。Lambda関数はHTMLを生成しそのHTMLをそのまま返します。

また、固定のHTMLを返すだけでは単純すぎて面白くないため、今回はURLのクエリパラメータで受け取った文字列を元にHTMLの一部を変更するようなLambda関数を作成します。


ライブラリをインストール

以下のコマンドでEJSをインストールします。

EJSはJavaScriptで使用できるテンプレートエンジンです。

$ npm install ejs

ディレクトリの構成

project-directory/
 ├ node_modules/
 ├ package.json
 ├ package-lock.json
 ├ index.mjs
 └ template.ejs

実際のコード

「御託はいいから、とっとと動くコード見せろ」

はい。

JavaScript

ファイルのパス: /index.mjs

import ejs from 'ejs';
import path from 'path';
import fs from 'fs';


export const handler = async function(event, context) {
  // 今回はクエリパラメータからタイトルとコンテンツを取得
  const title = event.queryStringParameters?.title;
  const content = event.queryStringParameters?.content;

  // ejsテンプレートを読み込み
  const templatePath = path.resolve('./template.ejs');
  const template = await fs.promises.readFile(templatePath);

  // ejsテンプレートにパラメータを渡してbodyを生成
  const body = ejs.render(template.toString(), {
    title: title,
    content: content
  });

  return {
    statusCode: 200,
    headers: {
      // HTML文書を返すため、HTML文書のMIMEタイプ text/html を指定します。
      'Content-Type': 'text/html'
    },
    body: body
  };
};

Content-Typeを指定している以下の箇所がポイントですね。正しく設定できていない場合、ブラウザでアクセスした際にHTMLの文字列が表示されてしまいます。

    headers: {
      // HTML文書を返すため、HTML文書のMIMEタイプ text/html を指定します。
      'Content-Type': 'text/html'
    },

テンプレートファイル(EJS)

今回はパラメータを元にbodyを変更するとともに、OGPも設定してみます。

ファイルのパス: /template.ejs

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <!-- パラメータを元にOGPを設定 -->
  <meta property="og:url" content="https://www.example.com"/>
  <meta property="og:type" content="website"/>
  <meta property="og:site_name" content="<%= title %>"/>
  <meta property="og:title" content="<%= title %>"/>
  <meta property="og:description" content="description test description test"/>
  <meta name="twitter:card" content="summary"/>
  <meta name="twitter:title" content="<%= title %>">
  <meta name="twitter:description" content="description test description test">

  <!-- パラメータを元にタイトルを設定 -->
  <title><%= title %> | ドキュメント</title>
</head>
<body>
  <div>
    <!-- bodyにパラメータを反映 -->
    <h1><%= title %></h1>
    <p><%= content %></p>
  </div>
</body>
</html>

API Gatewayの設定

API Gatewayの統合リクエスト設定画面で `Lambda プロキシ統合` にチェックを入れます。


動作確認

API Gatewayで発行されたURLにブラウザからアクセスしてみしょう。今回はクエリパラメータを元に動的にHTMLの内容を生成するプログラムになっているので、URLにクエリパラメータを追加して動作確認してみます。

例1

クエリパラメータにそれぞれ以下の値を指定した場合

  • title: title!title!title!

  • content: hogehgoe

例2

クエリパラメータにそれぞれ以下の値を指定した場合

  • title: AAABBB

  • content: CCCDDD

例3

せっかくOGPを動的に生成しているので、クエリパラメータの title に test-title を指定して、URLをツイートした場合の投稿してみましょう。

タイトルが正常に test-title となっているのがわかりますね。

まとめ

API GatewayとLambdaの組み合わせでjsonではなくHTMLを返すことができました。

本記事のソースコードはすべてGitHubにもアップロードしています。

https://github.com/jsuzuki20120311/comment-application-sample

API GatewayでHTMLを返さなければならないケースは少ないと思われますが、一応こういうことも出来なくはないということで、参考になれば幸いです。

※所属組織や業務内容は2023年3月時点のものです。

パーソルホールディングスは、グループビジョン「はたらいて、笑おう。」の実現に向け、グループ経営をともにリードする仲間を募集しています。
中途採用の詳細はこちら⇒募集職種一覧
パーソルホールディングス 採用サイトはこちら