メインコンテンツへスキップ
見出し画像

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月時点のものです。

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

    あなたへのおすすめ