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
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
460
Other Decks in Programming
See All in Programming
Laravel Boostに学ぶ、AIにPHPを書かせる技術 〜OSSの実装から蒸留するエージェント制御の王道〜
kentaroutakeda
3
720
「人を評価する AI」の設計と実装
ryoyanara
0
210
仕様駆動開発へのトライを機に チームに適合する手法を模索し続けている話
freee
PRO
0
560
琵琶湖の水は止められてもNet--HTTPのリトライは止められない / You might be able to stop the water flow of Lake Biwa but you can't stop Net::HTTP retries
luccafort
PRO
0
770
Jindong: Introducing Declarative Haptics in Compose Multiplatform
l2hyunwoo
0
120
jsmini JavaScript Engine を作ってみた話
yosuke_furukawa
PRO
0
330
AWS CDK を「作」ってみた 〜フルスクラッチで見えた CDK の裏側〜 / aws-cdk-from-scratch
gotok365
3
2.8k
5分で問診!Composer セキュリティ健康診断
codmoninc
0
1k
進化を続けるGo toolsの現在地 / The Current State of Ever-Evolving Go Tools
hond0413
0
240
How I Won Prize Money at a Hackathon Using Codex and Symphony Alpha
yasei_no_otoko
0
110
わからない話を追いかけたら、プログラミング言語を作る側にいた
ydah
3
520
AI時代のPHPer生存戦略 ~「言語、もうなんでもよくない?」に本気で向き合う~
vivion
0
800
Featured
See All Featured
The SEO Collaboration Effect
kristinabergwall1
1
520
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.3k
How to Ace a Technical Interview
jacobian
281
24k
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
370
The World Runs on Bad Software
bkeepers
PRO
72
12k
Thoughts on Productivity
jonyablonski
76
5.3k
Un-Boring Meetings
codingconduct
0
390
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.8k
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
210
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
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!