狠狠撸

狠狠撸Share a Scribd company logo
Rails and JSON API
In 2019
Akinori Musha (@knu)
JSON API In 2019
? JSON:API
? OpenAPI
JSON:API
JSON:API
? RESTfulなAPIにおいて、RESTが規定していないがぼんやり定式化してきたプラクティスを
規格として取りまとめているもの
https://jsonapi.org/
? JSONをベースとした要求?応答フォーマットを策定
? HALなどの発展系、決定版
? 履歴
? 2018年12月 1.1RC
? 2015年 5月 1.0最終版
? 2013年 5月 最初のドラフト
RESTとは
? 2000年、Apache HTTP ServerプロジェクトのcofounderでHTTP/1.1の策定に
も関わったRoy Fieldingが博士号論文で提唱
? REpresentational State Transferの頭字語
? REpresentational State = 表現可能な状態 = いわゆるリソース
? Transfer = 転送
? HTTPに屋上屋を架したメタRPCプロトコル(SOAPやXMLRPC)、HTTPを単
なるトランスポート?トンネルとして使ってきた用法に対するアンチテーゼ
? HTTP原理主義
JSONとは
? 2001年、Douglas CrockfordがWebベースのアプリケーションを開発する際に「発見」したデータ交換フォーマット
? The JSON Saga
?
? 単なるJavaScriptのオブジェクトリテラルではHTMLドキュメントに埋め込む際にまずいと気づいた
? キーを必ずクオートする
? ES3では予約語をキーにできなかった(ES5で可能になった)
? Pythonのdictionaryの記法とも一致していた
? eval("{a:42}")してみると分かるが、ブロック内にラベルa:と式42があると解釈されてしまう、という理由もある
? 文字列リテラルに冗長な  を許す
? </script> を </script> とするなどして無効化できるように
? evalできるという手軽さから始まったが、安全を確認性するのが大変
? 専用パーサーが必要(JSON.parse)
RESTとは
? 4つの原則
? Addressability
すべての操作対象はURI(ユニバーサルにユニークな名前)で示される
? Statelessness
セッション等の状態管理はせず、個々の操作が独立している
? Connectedness
情報の関連はURIのリンクで示す
? Uniform Interface
HTTPメソッドを共通語彙とし、あらゆる操作をGET, POST, PUT, DELETE等で表す
OpenAPI
OpenAPI Speci?cation
? 2017年に出た、RESTful APIの仕様を記述するための言語
(JSON|YAML)
? https://www.openapis.org/
? Swagger Speci?cation (~2.0)の後継
? SwaggerはRESTful APIを構築するためのフレームワーク?
ツール(2011年~)
OpenAPI Speci?cation (3.0)
? 履歴
? 2018-10-08 OpenAPI Speci?cation 3.0.2
? 2017-12-06 OpenAPI Speci?cation 3.0.1
? 2017-07-26 OpenAPI Speci?cation 3.0.0
? 2016-01-01 OpenAPI Initiative発足
? 2014-09-08 Swagger Speci?cation 2.0
? 2014-03-14 Swagger Speci?cation 1.2
? 2012-08-22 Swagger Speci?cation 1.1
? 2011-08-10 Swagger Speci?cation 1.0
OpenAPI Speci?cation (3.0)
? エンドポイントと要求?応答のデータスキーマなどを包括的に記述できる
? JSON:API、HALとは直行した概念
? JSON Schemaを取り込んでスキーマ定義言語として利用している
? 完全に同期?追随しているわけではない(JSON Schemaは長きに渡りドラフトを重ね
ていて、手戻りも多い)
? JSON Hyper Schemaとは少しかぶっている
? OpenAPI自身が独自にエンドポイント情報の記述言語を持っている
? OpenAPIはクエリーパラメータやパス内パラメータについてもbody同様に統一的な
文法で記述できるように進化
JSON Schema
JSON Schema
? JSONデータのスキーマの記述言語
https://json-schema.org/
? それ自体がJSONで記述される
? 以下の仕様の総称
? JSON Schema Core
? JSON Schema Validation
? JSON Hyper-Schema
? Relative JSON Pointers
? 履歴
? 2018-03-19 draft-07
JSON Schema
? JSON Schema Core
? JSON Schemaの基盤仕様
スキーマバージョンの宣言、ネスト、内部?外部参照などについて規定されている
$schema, $ref, $idなど
その他の具体的な語彙はここでは規定されていない
? JSON Schema Validation
? JSON Schemaの仕様の本体
データ型、バリデーションルールを記述するための語彙が定義されている
日付、時刻、メールアドレス、URIなどもデータ型として定義されている(JSON表現自体はString)
JSON Schema
? JSON Hyper-Schema
? ハイパーメディア(リンク)を記述するための語彙が定義され
ている
? Relative JSON Pointers
? JSONドキュメント内の特定のキーを参照するための記法
$refで # 以降に記述するアンカーで使われる
搁补颈濒蝉で闯厂翱狈:础笔滨
搁补颈濒蝉で闯厂翱狈:础笔滨
? OpenAPI 3.0で記述してみたい
? 闯厂翱狈:础笔滨でやってみたい
OpenAPI 3.0で記述してみたい
? committee gemを使ってみた
シンプルに要求?応答バリデーションだけを追加するRackミ
ドルウェア集
OpenAPI 3.0対応が早く、そちらに寄せていく動きも好ましい
? swagger-blocksのようなRubyのDSLは地雷…
OpenAPI 3.0対応が見えない
闯厂翱狈:础笔滨でやってみたい
? JSONシリアライザーの選択が大事
? jbuilder
? ActiveModel::Serializers
? fast_jsonapi
? rabl
JSONシリアライザーの比較
? jbuilder
? DSLがいまいち
? 速くもない
? ActiveModel::Serializers
? 良くも悪くもデファクトスタンダード
? プロジェクトが動いていない
? 0.10.xで燃え尽きた?
JSONシリアライザーの比較
? fast_jsonapi
? Net?ix製、速くてよさそう
? JSON:APIに寄せたデフォルト
? AMSに近い使い心地
? 登場は新しいが、さほど開発が活発というわけではない
? rabl
? モデルに対するserializer、ではなくビューテンプレート、コンポーネント型
? 筆者が使い慣れている
Rabl
? RubyによるDSLというのは他と同じ
? Railsのビューとして動く
? JSONを生成するテンプレート (*.json.rabl)
? 他のシリアライザーは基本的にモデルとJSON表現が1:1だが、Rablはコンテキ
ストに応じて自由にテンプレートを選び、適宜partialで取り込める
? OpenAPIのcomponentsでモデルを定義して$refで参照、というモデルと
相性も良いはず
? rabl-railsを使うと結構速い
rabl-rails
? rabl本家もRailsに対応しているが、テンプレートエンジンと
してrablを使いつつ、コンパイルと展開のステージを分けて
性能を大幅に上げるrabl-railsというgemがある
? これはその仕組み上、インスタンス変数をそのまま使えない
など書き方が少し変わる
? rabl本家のWikiなどの例を読み替え?書き換える必要が出
てくる
rablとlayout
? rablはRailsのビューとして動く、ということはJSON:APIに沿ったガワを
layoutとして作れば、返したいdataを記述するだけで自動的に応答が作れて
便利…!
? と思いきや、rablのDSL実装とRubyの構文上の制約からテンプレート内に
yieldを置くと文法エラーになってしまう
? つまりrablでlayoutを書くことはできない…
? erbやhamlを使えばできるが書き心地は良くない
? layoutはせいぜい片手で足りる程度なので目をつぶろう…
実例
実例
? committeeとrablで作ってみました
? https://github.com/knu/jsonapi-example
? 応答バリデーション
? 開発環境のみで有効化
? テスト環境ではrequest specで明示的にassertionを入れる
有効化してしまうとHTTPステータスの時点でこけてしまって追いづらい
? プロダクション環境ではテストを通っているはずなので冗長、漏れの部分でハードエラーになっても困る
検知だけできる機能 が準備中なので、実装されたら使うとよさそう
? JSONビューはガワlayout、エンドポイントのテンプレート、componentに対応したpartial、とOpenAPI定義
に沿って作成
? 細かいところでは、JSON:APIのMIME type (application/vnd.api+json)を使うようにした
感想
OpenAPIは、Swagger 2.0から移行できないツールが多そうだ
が、一から使う分には使い勝手良い
JSON:APIについては、準拠がどのくらいうれしいかはわからない
一方、実装はJSON:API対応をうたうシリアライザか、rablのよう
に柔軟性の高いものを使わないと面倒
JSON Schemaで丁寧に書いて実装と両方メンテナンスするのは
つらい…

More Related Content

Rails and JSON API in 2019