サーバレスだとJSONを返却するのが一般的なのかなと思っていますが、htmlも返却することができます。
で、テンプレートエンジンがないとhtmlを作成するのが苦行になってしまうので、Thymeleafが使えないものかと試してみました。
前提
基本的に以下に従って環境が構築されている前提です。
(Mavenのアーキタイプからプロジェクトを作っていればokです。)
https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-create-first-java-maven
まずはシンプルにhtmlを返却する例
public class Function {
@FunctionName("html")
public HttpResponseMessage<String> html(@HttpTrigger(name = "html", methods = {
"get" }, authLevel = AuthorizationLevel.FUNCTION) HttpRequestMessage<String> req) {
String html = "<html><head><title>たいとる</title></head><body><h1>ぼでー</h1></body></html>";
HttpResponseMessage<String> res = req.createResponse(200, html);
res.addHeader("Content-Type", "text/html");
return res;
}
}
自前でhtmlを組み立てて、HttpResponseMessage型で返却します。
このとき、addHeaderでContent-Typeをtext/htmlにしておかないと、ブラウザにただの文字列と認識されてしまいます。
このぐらい簡単なhtmlならいいんですが、複雑になったり動的な要素がでてくると、つらみがあるのでThymeleafを使いたいんです。
Thymeleafを使う
まずは、pom.xmlのdependencyにthymeleafを追加します。
バージョンは現時点で最新のものにしています。
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.9.RELEASE</version>
</dependency>
続いてソース。
public class Function{
@FunctionName("thymeleaf")
public HttpResponseMessage<String> thymeleaf(@HttpTrigger(name = "thymeleaf", methods = {
"get" }, authLevel = AuthorizationLevel.FUNCTION) HttpRequestMessage<String> req) {
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setTemplateMode(TemplateMode.HTML);
templateResolver.setPrefix("template/");
templateResolver.setSuffix(".html");
TemplateEngine templateEngine = new TemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
Context context = new Context();
context.setVariable("message", "hogehoge");
String html = templateEngine.process("test", context);
HttpResponseMessage<String> res = req.createResponse(200, html);
res.addHeader("Content-Type", "text/html");
return res;
}
}
普段はSpringと一緒に使っているのであまり意識したことがなかったのですが、TemplateResolverはいくつか種類があります。
今回はClassLoaderTemplateResolverを利用します。
また、Thymeleaf側に値を渡すにはContextオブジェクトを作ってやる必要があります。
SpringでいうModelみたいなものだと思っています。
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Thymeleaf</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="${message}">Thymeleaf!!</p>
</body>
</html>
htmlはこんな感じでつくりました。
src/main/resources/templateに配置しています。
あとは起動なり、デプロイなりして動作確認できます。
所感
今回はメソッド内でThymeleaf関連のインスタンスを生成していますが、コンストラクタで実施して、インスタンス変数にした方がいいのかもしれません。
ただ、アクセスのたびにコンストラクタが実行されるのであれば意味ないんですが・・・。
サーバレスだと、このあたりの動作がよくわからないのでいずれ検証しなければ、と思っています。
また、ここまでやるんだったらSpring Bootとかでサクッと作ればいいじゃん、という気もしています。
サーバレスだとAuto Scaling機能があるので、その恩恵にあずかることができるという点はメリットなんですかね。