7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

G*Advent Calendar(Groovy,Grails,Gradle,Spock...) Advent Calendar 2015Advent Calendar 2015

Day 15

Grails 3.1のJSON Viewsを触ってみた

Last updated at Posted at 2015-12-15

これはG* Advent Calendar 2015の15日目の記事です。

今日はGrailsの次期バージョン 3.1の新機能であるJSON Viewsについて紹介してみます。この記事はGrails 3.1M3を元に書いていますので、リリース時には状況が変わっているかもしれませんが、そのへんはご了承を。

はじめに

JSON Viewsとは、Grails ViewsにおけるJSON実装です。JSONのレンダリングにはGroovyのJsonBuilderが使われています。Grails ViewsはGrailsに新たなビューのサポートを追加する仕組みで、Grails 3.0まではビューと言えばGSP(Groovy Servers Pages)というHTMLをレンダリングするビューしか基本的には存在しませんでしたが、このGrails ViewsによってGSP以外の様々なビューのサポートを追加できるようになっています。

ちなみにJSON以外の現時点でのGrails Viewsの実装としては、GroovyのMarkupTemplateEngineを使ったMarkup Viewsがあります。

プロジェクト準備

JSON Viewsをてっとり早く試してみるにはweb-apiプロファイルを使ってプロジェクトを作成します。

grails create-app sample-json-views --profile=web-api

プロファイルにweb-apiを指定することで、JSON Viewsに必要な依存関係がbuild.gradleに設定された形でプロジェクトが生成されます。生成されたbuild.gradleでJSON Viewsに関連する部分は以下です。

buildscript {
    ...
    dependencies {
        ...
        classpath "org.grails.plugins:views-gradle:1.0.0.RC2"
    }
}
...
apply plugin:"org.grails.plugins.views-json"
...
dependencies {
    ...
    compile "org.grails.plugins:views-json"
}

Gradleのプラグインをbuildscriptapply plugin:"org.grails.plugins.views-json"が設定され、プロジェクトの依存関係に"org.grails.plugins:views-json"が追加されています。

基本的な使い方

とりあえず適当なコントローラを作成します。

class HelloController {

    def index() {
        [name: 'yamada']
    }
}

nameというキーをもつモデルを単に返しています。GSPと同じでこのモデルがビューで参照できます。

ここでJSON Viewsのビューのファイルを作成します。ファイルはGSPと同じようにgrails-app/viewsディレクトリに格納します。ファイルの拡張子は.gsonです。

ここではgrails-app/views/hello/index.gsonを次のように実装します。

model {
    String name
}

json {
    message "Hello ${name}!"
}

modelのブロックにコントローラから受け取るモデルのデータを定義して、jsonのブロックでレンダリングのフォーマットを指定しています。

この状態でAPIをたたいてみると以下のようになります。

$ curl localhost:8080/hello
{"message":"Hello yamada!"}

jsonブロックの定義に従ってうまく表示されました。

ドメインクラスのモデルをレンダリングしてみる

適当なドメインクラスと、コントローラを作成します。

ドメインクラス:

class Person {
    String name
    Integer age
}

コントローラ:

import grails.rest.RestfulController

class PersonController extends RestfulController {

    static responseFormats = ['json']

    PersonController() {
        super(Person)
    }
}

この状態で適当なデータいれてAPIをたたいてみると以下のようになります。

$ curl localhost:8080/person/show/1
{"class":"grails.sample.json.views.Person","id":1,"age":20,"name":"yamada"}

デフォルトの挙動を変更するために、grails-app/views/person/show.gsonを次のように作成します。

model {
    Person person
}

json {
    name person.name
    age person.age
}

再度APIを叩いてみると...

$ curl localhost:8080/person/show/1
{"name":"yamada","age":20}

今度はjsonブロックで定義したnameageだけが表示されました。

テンプレートを使ってみる

GSPと同じでテンプレートが使えます。テンプレートはファイルのプレフィックスに_を付与します。

例えば_person.jsonを以下のように定義して、

model {
    Person person
}

json {
    name person.name
    age person.age
}

index.gson、show.gsonでこのテンプレートを使う場合は以下のようにします。

index.gson:

model {
    Collection<Person> personList
}

json g.render(template: 'person', collection: personList, var:'person')

show.gson:

model {
    Person person
}

json g.render(template: 'person', model: [person: person])

実行すると次のようになります。

$ curl localhost:8080/person
[{"name":"yamada","age":20}]

$ curl  localhost:8080/person/show/1
{"name":"yamada","age":20}

上記はg.renderを使っていますが、以下のようにも書けます。動作は変わりません。

index.json:

model {
    Collection<Person> personList
}

json tmpl.book(personList)

show.gson:

model {
    Person person
}

json tmpl.book(person)

まとめ

今までJSONのレンダリングは独自のカスタムマーシャラなんちゃらというクラスを実装したりなど、汎用的にいろいろとやろうとすると面倒くさいことも多かったのですがJSON Viewsによってだいぶ簡単に書けそうな印象です。

特に個人的にはURLのリンクなどはJSONに含む場合カスタムマーシャラなんかだと簡単にはg.linkなどリンク生成機能にアクセスできない、かつフロントエンドの知識をカスタムマーシャラに登場させる気持ち悪さがあったのですが、このへん全てビューに収まると非常にしっくりきます。

今日書いた内容はほぼ公式リポジトリの https://github.com/grails/grails-views に書いてある内容です。もう少し詳しく知りたい方は参照してみてください。

ではでは。

7
7
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
7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?