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