InsideFrontEnd 参加レポート2(JsonSchema編)
InsideFrontEnd 参加レポート2(JsonSchema編)
はじめに。
2017/02/25に開催されたInsideFrontEndの参加レポートになります。
本当投稿で2つ目となります。
前回の投稿はこちらの記事を参照下さい。
http://takahiro-fujii.hatenablog.com/entry/2017/02/28/222958
レポート : JSON Schema in Web Frontend
www.slideshare.net
今回はYahooの穴井さんのセッションのレポートをさせていただきます。
お題はJson Schemaの話です。今回、Json Schemaのケーススタディが聞けたのは非常に収穫でした。
Json Schemaの話はあちこちで出ていますが、
実は"実際にこういう風に使っている"というケーススタディの共有は、まだあまりないように感じます。
今回のセッションでは、リッチラボというyahooからスピンアウトした
リッチ広告を提供する企業(リッチラボ)におけるJson Schemaの活用法についてです。
主なトピックについて
・Json Schema / Json Hyper Schemaの活用
・FrontEndとBackEnd APIの意思疎通
・入力フォームについて
(他にもシステム構成についての説明などもありました。)
Json Schema / Json Hyper Schemaの活用について
FroneEnd App <-> BackEnd App 間で、Json Hyper Schemaを活用しているということでした。
Json Hyper Schemaって??
こちらをみて頂くと記載がありますが、
http://json-schema.org/documentation.html
The latest Internet-Draft at the IETF is v5, published 2016-10-13. (Due to a change in authorship the I-D numbering has been reset). The specification is split into three parts, Core, Validation, and Hyper-Schema
Json Schemaの3つある仕様のうちの1つ。Hyperはhyper-mediaのhyperです。
{ "id" : "b94318c0-cc7f-11e3-9c1a-094jkd00c9a66" "name" : "Takahiro Fujii", "email" : "hogehoge@***.com" }
Json Schema Core
{ "$schema": "http://json-schema.org/draft-04/hyper-schema", "type" : "object", "difinitions" : { "id" : { "type" : "string", "format": "uuid" }, "name" : { "type" : "string" }, "email" : { "type" : "string", "format" : "email" } }, "properties" : { "name" : { "$ref" : "#/definitions/name" }, "age" : { "$ref" : "#/definitions/age" }, "email" : { "$ref" : "#/definitions/email" } } }
Json Hyper-SchemaはURIの紐付けの部分の定義が記載されています。
英語で、ぱっと見読むのめんどくさそうな感じですが、そもそもそんなに難しい話ではないので、
一度腰を据えて読んでみるのがいいと思います。
http://json-schema.org/latest/json-schema-hypermedia.html#rfc.section.5
Json Schema Core + Hyper-Schema
{ "$schema": "http://json-schema.org/draft-04/hyper-schema", "type" : "object", "difinitions" : { ... }, "properties" : { ... }, "links": [{ "title": "Get User infomation", "description": "Get users resource information by id", "href": "/users/:id", "method": "GET", "rel": "self" },{ "title": "Create User infomation", "description": "Create users resource", "href": "/users", "method": "POST", "rel": "create", "schema": { "type": "object", "properties": { ... } } }] }
linksの中の各要素については、公式ドキュメントを読んでみてください。
24スライド目を見たらわかると思いますが、
1つ目のオブジェクトがRest apiのgetの仕様にあたる部分、
2つ目がcreateの仕様にあたる部分になります。
このセッションでは、あるアプリのFrontEndとBackEndを作成する際に、
Json Hyper-Schemaを定義し、それを元に、
- APIドキュメントの自動生成
- HTTPクライアントの自動生成
- モックの自動生成
を行い、お互いが(FrontEndとBackEnd)がお違いを気にせずに(疎な関係で)開発を進めることができる。
という実例を紹介されていました。
APIドキュメントの自動生成
APIドキュメントの自動生成(+多分json schemaの作成)
GitHub - interagent/prmd: JSON Schema tools and doc generation for HTTP APIsを使っているそうです。
有名ですね。が、使っていないので、使って見ました笑
mkdir -p schemata prmd init user > schemata/user.json
これで、user resourceのrestful apiのサンプルjson schemaが生成されます。
最初からこれを例にして話をしてもよかったかもしれません。笑
あとはgithubのusageにそって進めていくと、、
markdownを生成
prmd doc schema.json > schema.md
schema.mdが簡単に作れます。
開いてみると、こんな感じでapiドキュメントが生成されます。
非常に簡単です。
モックの自動生成
モックの生成は、自作のライブラリを使っているようです。
https://github.com/richlab-corp/schema-to-db-json
さっそく、先ほど作ったschema.jsonを食わせてみます。
# Generate db.json from JSON Hyper-Schema schema-to-db-json schema.json > db.json
次のようなdb.jsonが作られました。
tf:tmp fujiitakahiro$ cat db.json { "apps": [ { "created_at": "2017-01-01T00:00:00+09:00", "id": "01234567-0123-0123-0123-0123456789ab", "name": "ABCDEFGHIJ", "updated_at": "2017-01-01T00:00:00+09:00" } ], "users": [ { "created_at": "2017-01-01T00:00:00+09:00", "id": "01234567-0123-0123-0123-0123456789ab", "name": "ABCDEFGHIJ", "updated_at": "2017-01-01T00:00:00+09:00" } ] }
次にjson-serverを立ち上げます。
tf:tmp fujiitakahiro$ json-server --watch db.json \{^_^}/ hi! Loading db.json Done Resources http://localhost:3000/apps http://localhost:3000/users Home http://localhost:3000 Type s + enter at any time to create a snapshot of the database Watching...
mockを返してくれるAPIが立ち上がりました!
簡単。
これでFrontEndはこのmock apiを使って開発が進められますね。
HTTPクライアントの自動生成
golangはherokuが作っているやつを使っているみたいです。
github.com
jsは自作中とのこと。
個人的にはクライアントライブラリはあったら便利かなぁ位なので、いいかなと。
クライアントライブラリの管理はbackend側がやるんでしょうか。
それか、一緒にメンテしていく感じなのかな。小さい規模なら特に問題なさそう。
ということで、簡単にmock apiを立ち上げて開発を進めていることがわかります。
さらに、仕様のドキュメントを作る過程が開発の過程の一部になることで、
プレゼンでもおっしゃってましたが、
仕様と実装がシンクする
というメリットがでてきますね…!いけてる。
FrontEndとBackEnd APIの意思疎通
プレゼンの中で、"合意"という言葉を使われていたのが気になりました。
おそらく、CDCのようなことなのかな、と思いました。
実際にはどのように合意をするのか結構気になります。
(自分に時間がなくあまりここらへんは聞けませんでした、、
(Pull requestのapproveが合意ってことなのかな
CDC
https://martinfowler.com/articles/consumerDrivenContracts.html
pull requestのapproveが合意だとすると、規模が大きくなってきたときに、
修正の妥当性をどのように担保していくのか、というのが気になりました。
お互いがjson schemaを元にテストを書く感じなのかな。
それか、pactやspring cloud contractのような仕組みを使うのか。
pact
techlife.cookpad.com
spring cloud contract
Spring Cloud Contract
入力フォームについて
リッチ広告は設定項目が非常に多く、複雑なフォームが多いらしい。
設定値が複雑だったり、入力値の検証だったり、動的に入力項目が変わったり、、
大変そう・・
react-jsonschema-form
というmozillaが作っているReact Componentを利用しているとのこと
知らなかった。。。
- validationをjson schemaベースでやってくれる
- カスタマイズが柔軟
というメリットがあげられていました。
バリデーションがjson schemaでやってくれるのいいし、
あとはreact componentはカスタマイズが本当に大事だと思う。
どんなにバリデーションの所がいけてても、出したいUIに変えられなかったら使えないですし。
react-jsonschema-formはここで試せます。
validationはかなりいけているので、どれくらい柔軟にカスタマイズできるのか、
近いうちに試してみようと思います。
まとめ
まずは、Json Schemaを使われている事例を聞けたのが何よりも参考になりました。
早く、課題をクリアして、Json SchemaをFrontEndとBackEndをつなぐのに使いたいなと思いました。
また、質問したところ、Json Schemaを直接BackEnd側のバリデーションで使っていないということでしたが、
ここは是非実現したいところです。
特に、自分が今携わっている環境だと、APIのConsumerが複数いることが多かったり、フロントエンド意外にAPIを直接呼ぶような(Gateway API経由とかで)が割とあります。
そうすると、validationを複数の箇所でそれぞれ実装してしまうと、何かのタイミングでvalidationがずれて、後で問題になる、、
みたいなことが起きやすいイメージがあります。
Json Schemaは少なくともFrontEnd / BackEndを疎にして開発を高速化するのに役立ちますが、
それだけではなく、1ResourceのValidationの定義を一箇所にまとめることができれば、特に中規模、大規模の開発においては大きな威力を発揮する、、と思います。(実現するにあたっての課題はあると思いますが
あとは、更新する場合は穴井さんもおっしゃってましたが、versioningするのが開発のスピード落とさない為にはいい、、と思いますが、
これも同じくおっしゃっていたように、あまり多段でversion管理しまくるのも厳しいので、そういうのを防ぐ仕組みの元でしか出来ない方法なのかな、、とも思います。
schema-to-db-jsonは便利だった!個人的な開発でまずは使ってみたい。
課題があるけど使って見たい、、と思わせるJson Schema。
事例が聴けてよかった。次は自分達の事例が話せるといいな。