Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Hypermedia: The Missing Element to Building Adaptable Web APIs in Rails (増補日本語版)

3,350 views

Published on

RubyKaigi 2014での発表に、当日カットしたスライドを加えて「RESTful Web APIs 読書会」で話したものです。
http://www.circleaf.com/events/155

オリジナルバージョン http://www.slideshare.net/tkawa1/rubykaigi2014-hypermedia-the-missing-element

Published in: Technology
  • If you want to download or read this book, copy link or url below in the New tab ......................................................................................................................... DOWNLOAD FULL PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download EPUB Ebook here { http://bit.ly/2m6jJ5M } .........................................................................................................................
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • accessibility Books Library allowing access to top content, including thousands of title from favorite author, plus the ability to read or download a huge selection of books for your pc or smartphone within minutes DOWNLOAD THIS BOOKS INTO AVAILABLE FORMAT ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Full EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... ...................................ALL FOR EBOOKS................................................. Cookbooks, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy,
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Download or read that Ebooks here ... ......................................................................................................................... DOWNLOAD FULL PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Doc Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... .........................................................................................................................
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • accessibility Books Library allowing access to top content, including thousands of title from favorite author, plus the ability to read or download a huge selection of books for your pc or smartphone within minutes DOWNLOAD THIS BOOKS INTO AVAILABLE FORMAT ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Full EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... ...................................ALL FOR EBOOKS................................................. Cookbooks, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy,
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • (Unlimited)....ACCESS WEBSITE Over for All Ebooks ................ accessibility Books Library allowing access to top content, including thousands of title from favorite author, plus the ability to read or download a huge selection of books for your pc or smartphone within minutes ......................................................................................................................... DOWNLOAD FULL PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Full EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m6jJ5M }
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Hypermedia: The Missing Element to Building Adaptable Web APIs in Rails (増補日本語版)

  1. 1. HYPERMEDIA: THE MISSING ELEMENT to Building Adaptable Web APIs in Rails ハイパーメディア: RailsでWeb APIをつくるには、これが足りない Toru Kawamura @tkawa ! RubyKaigi 2014 RESTful Web APIs 読書会 #19 2014.10.09
  2. 2. @tkawa Toru Kawamura • フリーランス Ruby/Rails プログラマ • Technology Assistance Partner at SonicGarden Inc. • REST厨 (RESTafarian) inspired by Yohei Yamamoto (@yohei) • Sendagaya.rb 共同主催 • “RESTful Web APIs” 読書会主催
  3. 3. Web API
  4. 4. “Web” http://www.opte.org/the-internet/
  5. 5. http://pixabay.com/en/spider-web-net-grid-silk-drops-13516/ 「クモの巣」
  6. 6. https://www.flickr.com/photos/tamaki/260594564/ 「クモの糸」
  7. 7. • プライベート • 内部から使われる • SPAや専用の クライアントが使う • だいたい予想できる コントロールできる • パブリック • 外部から使われる • 汎用的な目的の クライアントが使う • 予想しづらい コントロールしづらい
  8. 8. – 「WebAPIのこれまでとこれから」by @yohei http://www.slideshare.net/yohei/webapi-36871915
  9. 9. 今回は「クモの巣」メインの 話です http://pixabay.com/en/spider-web-net-grid-silk-drops-13516/
  10. 10. Change
  11. 11. 変化は避けられない ! Web APIは変化に適応しなければならない
  12. 12. 2種類の Change バージョンが変わるバージョンが変わらない 互換性がない互換性がある クライアントを壊すクライアントを壊さない
  13. 13. 2種類の Change バージョンが変わるバージョンが変わらない 互換性がない互換性がある クライアントを壊すクライアントを壊さない 壊す Change 壊さない Change
  14. 14. 壊すChangeはよくない • ひどいユーザ体験を生む • クライアント開発者にコードの書き直し・ 再デプロイを強いる • もし     だったら…
  15. 15. なぜ起こる? バージョンが変わるバージョンが変わらない 互換性がない互換性がある クライアントを壊すクライアントを壊さない 壊す Change 壊さない Change
  16. 16. 人間が読める説明書から作られる クライアントがたくさんある GET /v1/statuses?id=#{id} GET /v1/statuses?id=#{id}
  17. 17. GET /v2/statuses/#{id} GET /v1/statuses?id=#{id} ×コードの書き直しが必要
  18. 18. 機械が読める説明書から作られる クライアントもある { "apiVersion": "1.0.0", "basePath": "http:// petstore.swagger.wordnik.com/api", "resourcePath": "/store", "produces": [ "application/json" ], "apis": [ { "path": "/store/order/{orderId}", "operations": [ { GET /v1/statuses?id=#{id} GET /v1/statuses?id=#{id} "method": "GET", "summary": "Find purchase order by ID", "notes": "For valid response try integer IDs with value <= 5. Anything above 5 or nonintegers will generate API errors", "type": "Order", "nickname": "getOrderById", "authorizations": {}, "parameters": [
  19. 19. GET /v2/statuses/#{id} GET /v1/statuses?id=#{id} ×コードの再生成が必要 { "apiVersion": "2.0.0", "basePath": "http:// petstore.swagger.wordnik.com/api", "resourcePath": "/store", "produces": [ "application/json" ], "apis": [ { "path": "/store/order/{orderId}", "operations": [ { "method": "GET", "summary": "Find purchase order by ID", "notes": "For valid response try integer IDs with value <= 5. Anything above 5 or nonintegers will generate API errors", "type": "Order", "nickname": "getOrderById", "authorizations": {}, "parameters": [
  20. 20. { uber: { version: "1.0", data: [{ url: "http://www.ishuran.dev/notes/1", name: "Article", data: [ { name: "articleBody", value: "First note's text" }, { name: "datePublished", value: null }, { name: "dateCreated", value: "2014-09-11T12:00:31+09:00" }, { name: "dateModified", value: "2014-09-11T12:00:31+09:00" }, { name: "isPartOf", rel: "collection", url: "/notes"
  21. 21. { uber: { 「密結合」が原因 version: "1.0", data: [{ url: "http://www.ishuran.dev/notes/1", name: "Article", data: [ • APIの変更がクライアントに反映されればよい { name: "articleBody", value: "First note's text" }, { name: "datePublished", value: null }, { name: "dateCreated", value: "2014-09-11T12:00:31+09:00" }, { name: "dateModified", value: "2014-09-11T12:00:31+09:00" }, { name: "isPartOf", rel: "collection", url: "/notes" • APIの説明を分割して各レスポンスに埋め込む のが良い方法 • APIについての多大な仮定は密結合を生む
  22. 22. バージョンが変わるバージョンが変わらない 互換性がない互換性がある クライアントを壊すクライアントを壊さない 壊す Change 壊さない Change 密結合による疎結合による
  23. 23. 例で見る疎結合: FizzBuzzaaS • by Stephen Mizell http://fizzbuzzaas.herokuapp.com/ http://smizell.com/weblog/2014/solving-fizzbuzz-with-hypermedia • サーバは与えられた100までの数の FizzBuzzを計算できる • サーバは次のFizzBuzzが何になるか知っ ている • クライアントは1から最後まで順番にす http://sef.kloninger.com/posts/ べてのFizzBuzzが欲しい 201205fizzbuzz-for-managers. html
  24. 24. 密結合なクライアント answer = HTTP.get("/v1/fizzbuzz?number=#{i}") puts answer end "/v2/fizzbuzz/#{i}" (1..1000) (1..100).each do |i| • すべてのURLとパラメータがハードコードされている • カウントアップのような、サーバロジックと同じこと をクライアントでも行っている
  25. 25. 疎結合なクライアント root = HTTP.get_root answer = root.link('first').follow puts answer while answer.link('next').present? answer = answer.link('next').follow puts answer end next リンクが重要 • ハードコードされたURLなし • URLや条件を変えてもクライアントは壊れ ない
  26. 26. • 実際にリンクをたど る代わりに、 埋め込みリソースを 使うことで リクエスト数を減ら すことが可能 http://techlife.cookpad.com/entry/2014/09/08/093000
  27. 27. 「APIコール」のメタファーは危険 • クライアントがあらかじめURLとパラメータを用意 してAPIを呼ぶ、というRPCのようなパラダイムから 離れよう • クライアントが次にすることは、レスポンスの中の リンクから選ぶこと == ハイパーメディア
  28. 28. これは想像上のものではなく すでにHTMLにある
  29. 29. HTMLのWeb • WebアプリやWebサイ トはずっと変わり続け ているが、ブラウザは 壊れていない • HTMLのWebでは、なぜ HTMLのリンクブラウザは壊れない? http://www.youtypeitwepostit.com/messages
  30. 30. HTMLの中のデータ • HTMLが表現する意味は 「ヒューマンリーダブルなドキュメント」 • 段落、リスト、表、セクション、… • これが人間にゆるく伝わればよい
  31. 31. HTMLの中のワークフロー • Webアプリはワークフ ロー(の提案)を含む • ワークフローは一連の 画面遷移で表現される — リンク と フォーム ”RESTful Web APIs” p.11 Figure 1-7
  32. 32. ハイパーメディアはワークフローを示す • 各画面は次に何ができる かの「メニュー」としてリ ンクやフォームを含む • ブラウザはその「メニュー」 の中から選んで次へ進む • これがハイパーメディア で、FizzBuzzaaSもやってい たこと 3 4
  33. 33. もしHTMLにリンクがなかったら? 代わりにワークフロー手順書がある? • 各WebアプリごとにURLやパラ メータをハードコードした専用 クライアントを作りたくなる • クライアントとサーバのコード が密結合して、変更できない Webアプリになってしまう • これが今のWeb APIがやってい ること メッセージWebアプリ利用の手順書 1. アドレスバーに /messages と入力し て GET 2. アドレスは /messages のまま、 title と body のパラメータに文字列を セットして POST 3. message-id を受け取って、アドレス バーに /messages/{message-id} と入 力して GET
  34. 34. クローラにはもう1つヒントが • クローラはリンクをたどる(submitできるフォームもある) • クローラはHTMLドキュメントの中にあるデータと その「意味」を理解している • どうやって? https://support.google.com/webmasters/answer/99170
  35. 35. Microdata
  36. 36. Microdata <div itemscope itemtype="http://schema.org/Person"> My name is <span itemprop="name">Bob Smith</span> but people call me <span itemprop="nickname">Smithy</span>. Here is my home page: <a href="http://www.example.com" itemprop="url">www.example.com</a> I live in Albuquerque, NM and work as an <span itemprop="title">engineer</span> at <span itemprop="affiliation">ACME Corp</span>. </div> • 構造化データをHTMLドキュメントに埋め込むしくみ • データを変えることなくドキュメントの構造を変えられる • データをURLに結びつけることで、大まかな「データの意 味」も表す(これもリンクの一種)
  37. 37. Microdata <div itemscope itemtype="http://schema.org/Person"> My name is <span itemprop="name">Bob Smith</span> but people call me <span schema.itemprop="org nickname">Smithy</span>. Here is my home page: <a href="http://www.example.com" itemprop="url">www.example.com</a> I live in Albuquerque, 標準語彙NM (and ボキャブラリー) work as an <span itemprop="at <span itemprop="by Bing, affiliation">Google, title">Yahoo! engineer</ACME Corp</and span> span>. Yandex </div> • 構造化データをHTMLドキュメントに埋め込むしくみ • データを変えることなくドキュメントの構造を変えられる • データをURLに結びつけることで、大まかな「データの意 味」も表す(これもリンクの一種) http://getschema.org/index.php/Main_Page
  38. 38. schema.org • フィールド名・カラム名は変わるが、標準名は変わらない • 変えたときに壊れないように、変わらない基盤としての 標準と結びつける • schema.org はコーポレートスタンダードの1つといえる Bing, Google, Yahoo! and Yandex • 現在700種類以上のデータタイプを定義
  39. 39. 変化に適応するために必要なもの data link form HTML - ✓ ✓ HTML +Microdata ✓✓ ✓ ✓ • APIには構造化データが必要 ✓✓: 「データの意味」を含む • 柔軟なワークフローにはリンクとフォームが必要
  40. 40. HTMLでWeb APIを作ることもできる var user = document.getItems('http://schema.org/Person')[0]; var name = user.properties['name'][0].itemValue; alert('Hello ' + name + '!'); • “Microdata DOM API” でHTMLからデータを抽出できる http://www.w3.org/TR/microdata/#using-the-microdata-dom-api • JavaScriptの実装: https://github.com/termi/Microdata-JS • MicrodataからJSONに変換する仕様もいくつかある • HTMLはリンクとフォームを持っているのが大きなアドバンテージ
  41. 41. でもきっとJSON Web APIが欲しいはず data link form HTML +Microdata ✓✓ ✓ ✓ JSON ✓ - - ✓✓: 「データの意味」を含む • リンクとフォームを埋めればいい (できればデータの意味も)
  42. 42. JSONでリンク・フォームを表す • リンクやフォームを表 現できるJSONベースの フォーマットを使う • 他にも Siren, Collection+JSON, Mason, Verbose など… data link form JSON ✓ - - JSON +Link header ✓ ✓ - HAL ✓ ✓ - JSON-LD ✓✓ ✓ - JSON-LD +Hydra ✓✓ ✓ ✓ UBER ✓ ✓ ✓ ✓✓: 「データの意味」を含む
  43. 43. JSONでデータの意味を表す: 「プロファイル」 • ALPSプロファイル • MicrodataをHTML以外のどんなフォーマットにも適用 可能にする • JSON-LDコンテキスト • ドキュメントとコンテキストの両方を同じ1つの フォーマットで扱える
  44. 44. A Solution
  45. 45. Hypermicrodata gem https://github.com/tkawa/hypermicrodata • サーバサイドでHTMLをJSONに変換 • Microdataだけではなく リンクとフォームもHTMLから抽出 • ベースのALPSプロファイルを用意して、データの意味 も表しやすい形でJSONベースのフォーマットを生成
  46. 46. class PeopleController < ApplicationController before_action :set_message, only: %i(show edit update destroy) include Hypermicrodata::Rails::HtmlBasedJsonRenderer ... end .person{itemscope: true, itemtype: 'http://schema.org/Person', itemid: person_url(@person), data: {main_item: true}} .media .media-image.pull-left = image_tag @person.picture_path, alt: '', itemprop: 'image' .media-body %h1.media-heading %span{itemprop: 'name'}= @person.name = link_to 'collection', people_path, rel: 'collection' Example in HAL (application/hal+json) { "image": "/assets/bob.png", "name": "Bob Smith", "isPartOf": "/people", "_links": { "self": { "href": "http://www.example.com/people/1" }, "type": { "href": "http://schema.org/Person" }, "collection": { "href": "/people" }, "profile": { "href": "/assets/person.alps" } } }
  47. 47. Hypermicrodata gemを使った Railsによる設計手順 1. リソース設計 2. 状態遷移図を描く 3. データの名前を対応するURLに結びつける 4. HTMLテンプレート(Haml, Slimなど)を書いて、Microdata でマークアップする (その後、必要ならschema.org定義にないプロファイルと説明を書く)
  48. 48. Example: Note API
  49. 49. 1. リソース設計 カラム名説明タイプ text noteの内容のテキストtext published_at noteの公開時間datetime (id, created_at, updated_at) (自動生成) $ rails g model Note text:text published_at:datetime model: Note controller: NotesController routing: resources :notes
  50. 50. 2. 状態遷移図を描く Railsの Collection & Member リソースパターンから始める (API ver.) item collection Collection Member create*† update*, delete* * 安全でない † 冪等でない
  51. 51. Collection of Note Note (text, published_at, created_at, updated_at, id) item collection create*† update*, delete*, publish* next, prev Home notes home * 安全でない † 冪等でない
  52. 52. 3. データの名前を対応するURLに 結びつける Collection of Note http://schema.org/ItemList Note http://schema.org/Article text http://schema.org/articleBody published_at http://schema.org/datePublished created_at http://schema.org/dateCreated updated_at http://schema.org/dateModified id (各noteは個別のURLを持つので不要) Home http://schema.org/SiteNavigationElement
  53. 53. item IANA ‘item’ & http://schema.org/hasPart collection IANA ‘collection’ & http://schema.org/isPartOf notes - create Activity Streams ‘create' update Activity Streams ‘update’ delete Activity Streams ‘delete’ publish Activity Streams ‘post’ IANA registered Link Relation: http://www.iana.org/assignments/link-relations/ Activity Streams Verbs: http://activitystrea.ms/registry/verbs/
  54. 54. 4. HTMLテンプレートとMicrodataを書く Collection of Note %div{itemscope: true, itemtype: 'http://schema.org/ItemList', itemid: notes_url, data: {main_item: true}} - @notes.each do |note| = link_to note.text.truncate(20), note, rel: 'item', itemprop: 'hasPart' /app/views/notes/index.html.haml GET /notes HTTP/1.1 Host: www.example.com Accept: application/vnd.amundsen-uber+json = form_for Note.new do |f| = f.text_field :text = f.submit rel: 'create' { "uber": { "version": "1.0", "data": [{ "url": "http://www.example.com/notes", "name": "ItemList", "data": [ { "name": "hasPart", "rel": "item", "url": "/notes/1" }, { "name": "hasPart", "rel": "item", "url": "/notes/2" }, { "rel": "create", "url": "/notes", "action": "append", "model": "note%5Btext%5D={text}" }, { "rel": "profile", "url": "/assets/note.alps"} ] }] } } Link Form
  55. 55. %div{itemscope: true, itemtype: 'http://schema.org/Article', itemid: note_url(@note), data: {main_item: true}} /app/views/notes/show.html.haml %span{itemprop: 'articleBody'}= @note.text %span{itemprop: 'datePublished'}= @note.published_at %span{itemprop: 'dateCreated'}= @note.created_at %span{itemprop: 'dateModified'}= @note.updated_at = form_for @note, method: :put do |f| = f.text_field :text = f.submit rel: 'update' = button_to 'Destroy', @note, method: :delete, rel: 'delete' = button_to 'Publish', publish_note_path(@note), rel: 'publish' unless @note.published? = link_to 'Next note', note_path(@note.next), rel: 'next' if @note.next = link_to 'Prev note', note_path(@note.prev), rel: 'prev' if @note.prev = link_to 'Collection of Note', notes_path, rel: 'collection', itemprop: 'isPartOf' GET /notes/1 HTTP/1.1 Host: www.example.com Accept: application/vnd.amundsen-uber+json Note { "uber": { "version": "1.0", "data": [{ "url": "http://www.example.com/notes/1", "name": "Article", "data": [ { "name": "articleBody", "value": "First note's text" }, { "name": "datePublished", "value": null }, { "name": "dateCreated", "value": "2014-09-11T12:00:31+09:00" }, { "name": "dateModified", "value": "2014-09-11T12:00:31+09:00" }, { "name": "isPartOf", "rel": "collection", "url": "/notes" }, { "rel": "update", "url": "/notes/1", "action": "replace", "model": "note%5Btext%5D={text}" }, { "rel": "delete", "url": "/notes/1", "action": "remove" }, { "rel": "publish", "url": "/notes/1/publish", "action": "append" }, { "rel": "next", "url": "/notes/2" }, { "rel": "profile", "url": "/assets/note.alps" } ] }] } }
  56. 56. %div{itemscope: true, itemtype: 'http://schema.org/Article', itemid: note_url(@note), data: {main_item: true}} %span{itemprop: 'articleBody'}= @note.text %span{itemprop: 'datePublished'}= @note.published_at %span{itemprop: 'dateCreated'}= @note.created_at %span{itemprop: 'dateModified'}= @note.updated_at = form_for @note, method: :put do |f| = f.text_field :text = f.submit rel: 'update' = button_to 'Destroy', @note, method: :delete, rel: 'delete' = button_to 'Publish', publish_note_path(@note), rel: 'publish' unless @note.published? = link_to 'Next note', note_path(@note.next), rel: 'next' if @note.next = link_to 'Prev note', note_path(@note.prev), rel: 'prev' if @note.prev = link_to 'Collection of Note', notes_path, rel: 'collection', itemprop: 'isPartOf' Note = button_to 'Publish', publish_note_path(@note), = link_to 'Next note', note_path(@note.next), = link_to 'Prev note', note_path(@note.prev), { "uber": { rel: 'publish' unless @note.published? rel: 'next' if @note.next rel: 'prev' if @note.prev "version": "1.0", "data": [{ "url": "http://www.example.com/notes/1", "name": "Article", "data": [ 条件の表現 publishできるが prevには行けない { "name": "articleBody", "value": "First note's text" }, { "name": "datePublished", "value": null }, { "name": "dateCreated", "value": "2014-09-11T12:00:31+09:00" }, { "{ rel": "name": "publish", "dateModified", "url": "value": "/"2014-notes/09-11T12:1/publish", 00:31+09:00" }, "{ action": "name": "isPartOf", "append" "rel": }, "collection", "url": "/notes" }, { "rel": "update", "url": "/notes/1", "action": "replace", { "rel": "model": "next", "note%5Btext%"url": 5D={text}" "/notes/}, 2" }, { "rel": "delete", "url": "/notes/1", "action": "remove" }, { "rel": "publish", "url": "/notes/1/publish", "action": "append" }, { "rel": "next", "url": "/notes/2" }, { "rel": "profile", "url": "/assets/note.alps" } ] }] } }
  57. 57. この設計手順の 3つのメリット
  58. 58. メリット 1: DRY • リンクとフォームをHTMLテンプレートに一度 書けば、JSON生成時にも再利用できる • Microdataマークアップもそのまま再利用できる • Bonus: HTMLのMicrodataはSEO効果を上げる (JSONにも可能性あり)
  59. 59. メリット 2: リンクとフォームを 意識できる • JSON Web APIを作るときには、状態遷移の重要 性を見落としやすい • APIをHTMLのWebアプリのように表現すること で、状態遷移に着目して適切にリンクとフォー ムを実装できる
  60. 60. メリット 3: 制約 • 「HTMLドキュメントをMicrodataでマークアップし て、それを一定のルールでフォーマットされた JSONに変換する」という制約 • この制約はよりよい設計のガイド • “Constraints are liberating” 「制約は自由をもたらす」
  61. 61. もしJSONだけを書くときは 注意すること • リンク・フォームを意識するために: • 状態遷移図を描きましょう • APIを疎結合に保つために: • model.to_json の代わりに Jbuilder/RABL のようなビューテンプレートや リプレゼンターを使いましょう • リンクとフォームを持ったJSONベースのフォーマットを使いましょう • さらに schema.org のような標準名を使うとベター
  62. 62. “WebアプリとWeb APIを分けて考えない” – 「Webを支える技術」@yohei
  63. 63. 結論: Web APIはHTML Webアプリと 同じように設計しよう • Web APIは特別なものではなく、ただ表現 フォーマットが違うだけ • 状態遷移図を描いて状態遷移を意識すること で、リンクやフォームを忘れずにすむ
  64. 64. 最後に • 残念ながら、JSONフォーマット、クライアント実 装やライブラリにはデファクトスタンダードがない • RESTの制約・原則を意識するともっとうまくでき る • ハイパーメディアはRESTの最も重要な要素の1つで 変化に適応できるWeb APIへの重要なステップ
  65. 65. よりよい、変化に適応できるWeb APIを作りましょう Thank you for your attention. References • L. Richardson & M. Amundsen “RESTful Web APIs” (O’Reilly) • 山本陽平 “Webを支える技術” (技術評論社) • Designing for Reuse: Creating APIs for the Future http://www.oscon.com/oscon2014/public/schedule/detail/34922 • API Design Workshop 配布資料 http://events.layer7tech.com/tokyo-wrk • https://speakerdeck.com/zdne/robust-mobile-clients-v2 • http://www.slideshare.net/yohei/webapi-36871915 • http://smizell.com/weblog/2014/solving-fizzbuzz-with-hypermedia • 山口 徹 “Web API デザインの鉄則” WEB+DB PRESS Vol.82

×