LoginSignup
1
1

More than 1 year has passed since last update.

SAMとGoのテンプレートエンジンでSSR

Last updated at Posted at 2021-12-27

静的なテンプレートを読み込んでSSRを行うWebアプリケーションを作成します。

前提知識

  • AWS SAM と Golang を利用して Severless なWebアプリケーションを作成することができる。
  • Golang の html/template パッケージを利用してHTML形式の文字列を標準出力することができる。

(以後AWSとlangは省略して記述します)

Lambdaで静的なファイルを扱う

様々な方法があるかもしれませんが、今回は AWS Lambda Layer1 を利用します。
この機能を利用することで、 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}} に値を埋め込みます。

contents/index.html
<!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 を意識して記述するようにしましょう。

hello-world/main.go
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のテンプレートに記述します。

templete.yaml.diff
--- 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/

うまくいけば前述の完成イメージのような画面が表示されるはずです。
おつかれさまでした。


  1. https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-layers.html
    > Lambda レイヤーは、追加のコードやデータを含めることができる .zip ファイルアーカイブです。 

  2. https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/building-layers.html
    > カスタムレイヤーを構築するには、それを AWS Serverless Application Model (AWS SAM) テンプレートファイルで宣言し、BuildMethod エントリがある Metadata リソース属性セクションを含めます。 

  3. https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-layers.html
    > Lambda は、関数の実行環境を設定する際に、レイヤーの内容を /opt ディレクトリに抽出します。 

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1