Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Grails 3でWeb APIを簡単に作ろう!
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Kazuki YAMAMOTO
April 17, 2015
Programming
2.4k
6
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Grails 3でWeb APIを簡単に作ろう!
G* Workshop G*なWeb API での資料です
https://jggug.doorkeeper.jp/events/22473
Kazuki YAMAMOTO
April 17, 2015
More Decks by Kazuki YAMAMOTO
See All by Kazuki YAMAMOTO
今こそッ、始めようGrailsブートキャンプ!!!! / Grails Bootcamp for JGGUG
yamkazu
0
340
Grails 3で生まれ変わったGrailsの今 / Spring in Summer 2015
yamkazu
1
450
Other Decks in Programming
See All in Programming
脅威をエンジニアリングの糧にして――現場編 / Turning Threats into Engineering Fuel — Field Edition
nrslib
0
270
Java × distroless で 軽量なコンテナイメージを / Java on Distroless
contour_gara
0
530
Oxlintのカスタムルールの現況
syumai
6
1.1k
AI駆動開発で崩れていくコードベースを立て直す
kyoko_nr_nr
1
450
Copilot CLI の継戦能力を高める コンテキスト管理
nozomutu
1
1.2k
PHPで使える日時の表現と、その知り方 #frontend_phpcon_do
o0h
PRO
0
230
Skillsは効率化、Agentsは"自分の拡張"——Builder時代のエージェント編成(CC Night 2026)
wemra
1
120
A2UI という光を覗いてみる
satohjohn
1
130
net-httpのHTTP/2対応について
naruse
0
470
技術記事、AIに書かせるか、自分で書くか? 〜それでも私が自分の手で書く理由〜 / #QiitaConference
jnchito
2
1.4k
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
4.9k
Inside Stream API
skrb
1
680
Featured
See All Featured
Ruling the World: When Life Gets Gamed
codingconduct
0
250
What does AI have to do with Human Rights?
axbom
PRO
1
2.2k
HDC tutorial
michielstock
2
700
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
1
180
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.5k
Practical Orchestrator
shlominoach
191
11k
Music & Morning Musume
bryan
47
7.2k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
360
Embracing the Ebb and Flow
colly
88
5.1k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
118
120k
Principles of Awesome APIs and How to Build Them.
keavy
128
17k
Transcript
Grails 3でWeb APIを簡単に作ろう! 2015/4/17 #jggug
山本 和樹 yamkazu
祝 Grails 3 リリース
Grails 3 ✓ Gradleでビルドシステムを一新 ✓ Spring Boot上でアプリケーショ ンを再構築
今日はWeb API
GrailsにおけるWeb API ✓ Grails 2.3からREST関係のサポートが強化 ✓ @Resouce ✓ RestfulController ✓
Renderers
@Resource
@Resource ✓ Domainクラスにアノテーションを指定 ✓ REST対応コントローラの生成 ✓ URLマッピングへの設定の追加
import grails.rest.Resource @Resource(uri = '/books') class Book { String
title }
Endpoints HTTP Method URI Controller Action GET /books index POST
/books save GET /books/${id} show PUT /books/${id} update DELETE /books/${id} delete
データフォーマットの指定 ✓ クエリパラメータを使う ✓ 拡張子を使う ✓ メディアタイプを使う
クエリパラメータを使う http://api.example.com/books?format=json
拡張子を使う http://api.example.com/books.json
メディアタイプを使う GET /books Host: api.example.com Accept: application/json
DEMO: 1
各社サポートのデータフォーマット Twitter JSON Github JSON Flickr JSON, XML Amazon XML
出典: Web API: The Good Parts
XMLとJSONのトレンド http://www.google.com/trends/explore?q=xml+api#q=xml%20api%2C%20json%20api&cmpt=q XML JSON
LSUDsとSSKDs ✓ LSUDs(large set of unknown developers) ✓ 未知のたくさんの開発者 ✓
FacebookやTwitterをはじめ、パブリックにAPIをドキュメントともに 公開し、誰でもが登録して使えるようにしたもの ✓ SSKDs(small set of known developers) ✓ 既知の小数の開発者 ✓ 一方でSSKDsをターゲットとしたAPIとは、たとえば自社サービスのス マートフォンクライアント向けのAPIなど、APIを利用する開発者が限 られている http://thenextweb.com/dd/2013/12/17/future-api-design-orchestration-layer/ http://techblog.netflix.com/2014/03/the-netflix-dynamic-scripting-platform.html http://techblog.netflix.com/2012/07/embracing-differences-inside-netflix.html
RestfulController
RestfulController ✓ Domainクラスを指定するだけで 簡単にRESTfulなコントローラ を作成できる
import grails.rest.RestfulController class BookController extends RestfulController<Book> { static
responseFormats = ['json', 'xml'] BookController() { super(Book) } }
class UrlMappings { static mappings = { … '/books'(resources:
'book') } }
DEMO: 2
$ grails url-mapping-report
レンダリングの カスタマイズ
レンダリングの流れ Controller Renderer Converter Marshaller render as JSON/XML marshalObject render
respond
レンダリングするプロ パティを指定する
import grails.rest.render.json.JsonRenderer beans = { bookRenderer(JsonRenderer, Book) { includes
= ['title'] } }
DEMO: 3
レスポンスレンダリン グを細かく制御する
import grails.converters.JSON class BootStrap { def init =
{ servletContext -> JSON.registerObjectMarshaller Book, { Book book, JSON converter -> converter.build { id book.id title book.title } // MapでもOK //[id: book.id, title: book.title] } } … }
DEMO: 4
ユーザがプロパティを指定可能にする http://api.example.com/books?fields=title
class BookController extends RestfulController<Book> { … @Override def show() {
respond queryForResource(params.id), includes: includeFields } private List<String> getIncludeFields() { params.fields?.split(',') as List<String> ?: Collections.emptyList() } }
注意 CustomMarshallerを登録している場合は 自分でincludesを制御しなければならない
DEMO: 5
レスポンスグループを定義する http://api.example.com/books?detail=short http://api.example.com/books?detail=full { "id": 1, "title": "My Book" }
{ "id": 1, "title": "My Book", "isbn": "…", …}
class BootStrap { def init = { servletContext ->
JSON.createNamedConfig('short') { it.registerObjectMarshaller Book, { Book book, JSON converter -> [id: book.id, title: book.title] } } JSON.createNamedConfig('full') { it.registerObjectMarshaller Book, { Book book, JSON converter -> [id: book.id, title: book.title, isbn: book.isbn] } } … } … }
import grails.rest.render.RenderContext import org.grails.plugins.web.rest.render.json.DefaultJsonRenderer class MyJsonRenderer<T> extends DefaultJsonRenderer<T> {
MyJsonRenderer(Class<T> targetType) { super(targetType) } @Override protected void renderJson(T object, RenderContext context) { def namedConfiguration = context.arguments.detail ?: 'short' JSON.use(namedConfiguration) { renderJson(object as JSON, context) } } }
DEMO: 6
エンベロープを使いたい { books: [ { "id": 1, "title": "Groovy"}, {
"id": 2, "title": "Grails"} ] }
import grails.converters.JSON class MyJSON extends JSON { String key
@Override void render(Writer out) throws ConverterException { … if (key) { writer.object() writer.key(key) value(target) writer.endObject() } else { value(target) } … } … }
class MyJsonRenderer<T> extends DefaultJsonRenderer<T> { String key @Override
protected void renderJson(T object, RenderContext context) { … JSON.use(namedConfiguration) { def converter = object as MyJSON converter.key = key converter.prettyPrint = context.arguments.pretty renderJson(converter, context) } } … }
DEMO: 7
ページネーションしたい { "books": [ { "id": 1, "title": "Groovy"}, {
"id": 2, "title": "Grails"} ], "paging": { "total-count": 2, "current-max": 10, "current-offset": 0 } } http://api.example.com/books? max=10&offset=0&order=desc&sort=title
class MyJSON extends JSON { Map paging @Override
void render(Writer out) throws ConverterException { … if (paging) { writer.key('paging') value(paging) } … } … }
DEMO: 8
Versioning
バージョンの指定 ✓ URLに埋め込む ✓ Accept-Versionヘッダを使う ✓ メディアタイプを使う
URLに埋め込む http://api.example.com/v1/books
Accept-Versionヘッダを使う GET /books Host: api.example.com Accept-Version: v1
メディアタイプを使う GET /books Host: api.example.com Accept: application/vnd.example.v1+json
// sample/v1/BookController.groovy package sample.v1 class BookController extends RestfulController<Book> {
static String namespace = 'v1' … } // sample/v2/BookController.groovy package sample.v2 class BookController extends RestfulController<Book> { static String namespace = 'v2' … }
class UrlMappings { static mappings = { '/v1/books'(resources: 'book',
namespace: 'v1') '/v2/books'(resources: 'book', namespace: 'v2') … } }
DEMO: 9
Testing!
テスト ✓ Integrationテストを使うとサーバ立ち上 がってテストできる ✓ 適当なHTTPのクライアント使ってテスト ✓ TestRestTemplateがオススメ
def "GET /books/{id}"() { when: def entry = template.getForEntity("${baseUrl}/v2/books/${book.id}", Map)
then: entry.statusCode == HttpStatus.OK entry.body.title == 'test book' entry.body.isbn == '1234' }
DEMO: 10
まとめ ✓ @Resouce,RestfulController,Render erのカスタマイズで簡単に柔軟に Web APIが作れる ✓ フルスタックなのでDBの連携も簡単
参考書籍 http://www.amazon.co.jp/dp/4873116864 http://www.amazon.co.jp/dp/4774166278
参考URL ✓ Best Practices for Designing a Pragmatic RESTful API
✓ http://www.vinaysahni.com/best-practices- for-a-pragmatic-restful-api ✓ GrailsGoodness ✓ http://mrhaki.blogspot.com/search/label/ GrailsGoodness%3AREST
おまけ
web-micro
Enjoy Grails 3!