静的なテンプレートを読み込んでSSRを行うWebアプリケーションを作成します。
前提知識
- AWS SAM と Golang を利用して Severless なWebアプリケーションを作成することができる。
- Golang の html/template パッケージを利用してHTML形式の文字列を標準出力することができる。
(以後AWSとlangは省略して記述します)
Lambdaで静的なファイルを扱う
様々な方法があるかもしれませんが、今回は AWS Lambda Layer
1 を利用します。
この機能を利用することで、 HTMLやCSS等の静的なデータをLambdaのzipファイルに含めることができます。
SAMでは、SAMのテンプレートファイル内に設定を記述することでLambda Layerを構築することができます2。
構築
早速SAMでLambda Layerを利用したアプリケーションを構築してみましょう。
今回は以下のような単純なページを作成していきます。
手順
まずはいつも通りSAMのプロジェクトを作成します。
$ sam --version
SAM CLI, version 1.36.0
$ for var in 1 1 4 sam_ssr 1; do echo $var; done | sam init
次に静的なテンプレートを作成します。
今回は {{.Title}}
と {{.Body}}
に値を埋め込みます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>{{.Title}}</title>
</head>
<body>
<h1>{{.Title}}</h1>
<div>{{.Body}}</div>
</body>
</html>
次にレンダリング用のコードを作成します。
Lambda は、関数の実行環境を設定する際に、レイヤーの内容を /opt
ディレクトリに抽出します3。したがって、テンプレートを読み込む処理は /opt
を意識して記述するようにしましょう。
package main
import (
"html/template"
"strings"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
)
type Template struct {
Title string
Body string
}
func handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
parsedObject, err := template.ParseFiles("/opt/index.html")
if err != nil {
panic(err)
}
template := Template{"title_string", "body_string"}
writer := new(strings.Builder)
err = parsedObject.Execute(writer, template)
if err != nil {
panic(err)
}
return events.APIGatewayProxyResponse{
Body: writer.String(),
Headers: map[string]string{
"Content-Type": "text/html; charset=utf-8",
},
StatusCode: 200,
}, nil
}
func main() {
lambda.Start(handler)
}
これでLambdaで実行される処理を記述することができました。
次に、Lambda Layerに含めるファイルを処理するためのMakefileを作成します。
今回は単純にMakefileが存在するディレクトリから、成果物のディレクトリへコピーする処理を書きました。
.PHONY: build-HelloWorldFunctionLayer
MAKEFILE_PATH:=$(dir $(abspath $(lastword $(MAKEFILE_LIST))))
build-HelloWorldFunctionLayer:
cp -r $(MAKEFILE_PATH)/* $(ARTIFACTS_DIR)/
最後に、Lambda Layer用の設定をSAMのテンプレートに記述します。
--- a/sam_ssr/template.yaml
+++ b/sam_ssr/template.yaml
@@ -29,6 +29,16 @@ Resources:
Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
Variables:
PARAM1: VALUE
+ Layers:
+ - !Ref HelloWorldFunctionLayer
+
+ HelloWorldFunctionLayer:
+ Type: AWS::Serverless::LayerVersion
+ Properties:
+ Description: HelloWorldFunction layer.
+ ContentUri: contents/
+ Metadata:
+ BuildMethod: makefile
Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
最終的なディレクトリ構成は以下の通りです。
.
├── Makefile
├── README.md
├── contents
│ ├── index.html # 追加
│ └── makefile # 追加
├── hello-world
│ ├── go.mod
│ ├── go.sum
│ ├── main.go # 修正
│ └── main_test.go
└── template.yaml # 修正
実行
早速実行してみましょう。
$ sam build && sam local start-api
# => http://127.0.0.1:3000/hello/
うまくいけば前述の完成イメージのような画面が表示されるはずです。
おつかれさまでした。
-
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-layers.html
> Lambda レイヤーは、追加のコードやデータを含めることができる .zip ファイルアーカイブです。 ↩ -
https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/building-layers.html
> カスタムレイヤーを構築するには、それを AWS Serverless Application Model (AWS SAM) テンプレートファイルで宣言し、BuildMethod エントリがある Metadata リソース属性セクションを含めます。 ↩ -
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-layers.html
> Lambda は、関数の実行環境を設定する際に、レイヤーの内容を /opt ディレクトリに抽出します。 ↩