Play FrameworkでJSONレスポンスをビューで生成!Twirlテンプレート活用ガイド
生徒
「Play FrameworkでAPIを作りたいのですが、HTMLではなくJSON形式のデータを返すにはどうすればいいですか?」
先生
「通常、PlayではJavaコード内でJacksonライブラリを使ってJSONを生成しますが、実はビュー(Twirlテンプレート)を使ってJSONを組み立てることもできるんですよ。」
生徒
「えっ、HTMLを作るのと同じようにJSONも作れるんですか?それなら複雑な構造も直感的に書けそうですね!」
先生
「その通りです!データの形をテンプレートで定義できるので、柔軟なレスポンスが作れます。具体的な方法を一緒に見ていきましょう!」
1. ビューでJSONを生成するメリットとは?
Play Frameworkの開発において、JSONレスポンスを生成する方法はいくつかあります。最も一般的なのは、コントローラ内でJavaのオブジェクトを直接JSONに変換する方法です。 しかし、あえてTwirlテンプレート(ビュー)を使ってJSONを生成することには、特定のメリットがあります。
たとえば、特定の条件下でのみ特定のフィールドを表示したい場合や、既存のHTMLテンプレートと似たような構造でデータを返したい場合に、
慣れ親しんだ@if文や@for文といったTwirlの構文を使って、視覚的に分かりやすくJSONの構造を記述できるのが大きな利点です。
APIのレスポンス形式を「ドキュメント」のように管理したい場合にも役立ちます。
2. JSON用テンプレートファイルの作成ルール
TwirlテンプレートでJSONを扱う場合、ファイルの拡張子に注目しましょう。
通常、HTMLを表示する場合は index.scala.html という名前を使いますが、JSONを生成する場合は index.scala.json という拡張子を使用します。
拡張子を .json にすることで、Play Frameworkはそのテンプレートの出力形式(Content-Type)が application/json であることを自動的に認識します。
これにより、ブラウザやクライアントに対して「これはJSONデータですよ」と正しく伝えることができるようになります。
3. 単純なオブジェクトをJSONで返すサンプル
まずは、基本的な変数をJSON形式で出力する例を見てみましょう。 以下のコードは、ユーザーの名前と年齢を受け取ってJSONとして表示するテンプレートの例です。
@(name: String, age: Integer)
{
"status": "success",
"userData": {
"name": "@name",
"age": @age
}
}
HTMLの時と同じように、@を使ってJavaから渡された変数を埋め込みます。
文字列の場合はダブルクォーテーションで囲むのを忘れないようにしましょう。
4. JavaコントローラからJSONビューを呼び出す方法
次に、Javaのコントローラ側でこのテンプレートを呼び出す処理を記述します。 通常のビューの呼び出しとほぼ同じですが、戻り値の処理に注目してください。
package controllers;
import play.mvc.*;
import views.json.*;
public class ApiController extends Controller {
public Result getUserJson() {
String userName = "山田太郎";
int userAge = 25;
// views.json.ファイル名.render(...) で呼び出す
return ok(views.json.user.render(userName, userAge));
}
}
コントローラ側で ok() メソッドにテンプレートの結果を渡すだけで、適切なHTTPレスポンスが生成されます。
5. リストデータをfor文でループさせる手法
API開発で最も多いのが、複数のデータ(配列)を返すケースです。
Twirlの @for 文を使えば、JavaのリストをJSONの配列形式に変換するのも簡単です。
@(items: List[String])
{
"count": @items.size(),
"items": [
@for((item, index) <- items.zipWithIndex) {
"@item"@if(index < items.size() - 1){,}
}
]
}
JSONの配列では、最後の要素の後にカンマ , があるとエラーになる場合があります。
そのため、zipWithIndex を使って現在の番号を確認し、最後以外の場合だけカンマを付けるという工夫がよく使われます。
6. 複雑な条件分岐を含むレスポンスの生成
特定の権限がある場合だけ詳細なデータを返したい、といったロジックもビューの中に記述できます。 Java側で加工済みのデータを渡すのも良いですが、表示上の制御はビューで行うと見通しが良くなります。
@(isAdmin: Boolean, data: String)
{
"title": "システム情報",
"content": "@data"
@if(isAdmin) {
, "secretCode": "ABC-12345"
, "debugInfo": "Server-01"
}
}
このように、カンマを if 文の内側に含めることで、管理者の時だけフィールドを増やすといった動的なJSON生成が可能になります。
7. 自作クラスをJSONテンプレートで活用する
StringやIntegerだけでなく、自分で定義したJavaのモデルクラス(例:Productクラスなど)をリストで渡して、詳細な情報を出力するのも実戦的な使い方です。
public class Product {
public String id;
public String name;
public int price;
public Product(String id, String name, int price) {
this.id = id;
this.name = name;
this.price = price;
}
}
このクラスのリストをビューに渡し、それぞれの情報をプロパティとして出力します。 大規模なアプリケーションでは、このように役割を分担することで開発がスムーズに進みます。
8. エスケープ処理に関する注意点
TwirlはデフォルトでHTMLエスケープを行いますが、.json 拡張子のテンプレートでは、JSONに適した処理が行われます。
しかし、文字列の中に改行コードやダブルクォーテーションが含まれている場合は注意が必要です。
もしデータに特殊文字が含まれる可能性がある場合は、Java側であらかじめ StringEscapeUtils などを使ってエスケープしておくか、
Jacksonの機能を使って安全な文字列に変換してからビューに渡すのが、セキュリティ面でも安心な設計となります。
9. デバッグと動作確認のコツ
JSONレスポンスが正しく生成されているか確認するには、ブラウザの「開発者ツール」を活用しましょう。 「ネットワーク」タブでAPIの通信を選択し、「レスポンス」の内容が意図したJSON形式になっているかチェックします。
もしJSONの形式が崩れている(カンマが余計に付いている、括弧が閉じられていない等)場合は、ブラウザ上でエラーとして表示されるため、
テンプレートの @for 文や @if 文の境界線を注意深く確認してみてください。
10. まとめ的なアドバイス:使い分けの判断
Play Frameworkにおいて、JSON生成をJavaで行うか、ビューで行うかは開発チームの好みによります。 データ構造が完全に固定されている場合はJavaで自動変換するのが楽ですが、 「フロントエンドの要求に合わせて細かくレスポンスの見た目を調整したい」という場合には、今回紹介したビューでの生成が非常に強力な味方になります。
Twirlテンプレートの柔軟性を活かして、美しくメンテナンスしやすいAPI開発を目指しましょう。 まずは簡単なデータの出力から試して、徐々に複雑な構造に挑戦してみてくださいね!