Spring Data RESTを利用したAPIの設計と、作り直しまでの道のり

259 views

Published on

Spring Fest 2017での同名セッションの発表資料です。
http://springfest2017.springframework.jp/

Published in: Technology
  • Be the first to comment

Spring Data RESTを利用したAPIの設計と、作り直しまでの道のり

  1. 1. を利用した の設計と、作り直しまでの道のり Isao Takahashi 楽天株式会社 トラベルサービス開発・運用部 2017-11-24, Spring Fest 2017
  2. 2. 2 1. Spring Data RESTの紹介 2. 実際のプロジェクトに適用してみよう 1. Spring Data RESTを使ってみる 2. Spring Data RESTを使ってみた結果 3. Spring Data RESTは使えるのか? 4. まとめ
  3. 3. 3 自己紹介 高橋 勲 兼 コード書くこと全般 機能実装 リファクタリング 自動化
  4. 4. 4 皆さん、 使ってますか?
  5. 5. 5 皆さん、 使ってますか?
  6. 6. 6
  7. 7. 7 分で が作れる
  8. 8. 8
  9. 9. 9 分で が作れた
  10. 10. 10 の特徴 • と を定義したら が生える • 自前でロジックを書く必要が皆無 • 全部生える • 「特定の を公開しない」という設定もできるので安全 • の処理をよしなにやってくれる • 統一された フォーマット で やってくれる • ページングとかも超簡単
  11. 11. 11 いい感じ
  12. 12. 12 実際のプロジェクトで 使える
  13. 13. 13 今回のお題アーキテクチャ UI UI ビジネス ロジック API DB DB データ アクセス API ビジネス ロジック API データ アクセス API データ アクセス API DB FrontEndと BackEndを 分離 ビジネスロジックと データを 分離 1つのデータにつき 1つのアプリケーション のみアクセス可能
  14. 14. 14 今回のお題アーキテクチャ • いっぱい 作る • データ層側は基本的にはシンプルな のみ • 中間層 ビジネスロジック から 複数のデータ層 データアクセス にアクセスする • データアクセス 同士は が揃っていてくれるととてもうれしい • 規約 • のフォーマット •
  15. 15. 15 の特徴 再掲 • と を定義したら が生える • 自前でロジックを書く必要が皆無 • 全部生える • 「特定の を公開しない」という設定もできるので安全 • の処理をよしなにやってくれる • 統一された フォーマット で やってくれる • ページングとかも超簡単
  16. 16. 16 今回のお題アーキテクチャ UI UI ビジネス ロジック API DB DB データ アクセス API ビジネス ロジック API データ アクセス API データ アクセス API DB
  17. 17. 17 今回のお題アーキテクチャ データ アクセス API DB シンプルな CRUD操作だけ 提供する
  18. 18. 18 向いているのでは
  19. 19. 19 やってみよう
  20. 20. 20 お題データ構造 • お店(Shop)データ • 店名、フロア数を持つ • 複数の商品を販売できる • 商品(Item)データ • 名前を持つ • 複数の料金設定を持つ • 料金設定(Price)データ • 「商品を何個買うといくらになるか」の 料金データを持つ • いわゆる『まとめ買い』価格を表現できる = ¥190 = ¥100 = ¥150
  21. 21. 21 データの階層構造は、こんな感じ 2個で¥190 駄菓子屋 1階建て チョコ 飴 1個 ¥150 2個 ¥190 1個 ¥100
  22. 22. 22 のクラスにすると、こう public class Shop { private String name; private int floor; private List<Item> items; } public class Item { private String name; private List<Price> prices; } public class Price { private int unit; private BigDecimal amount; } 2個で¥190 駄菓子屋 1階建て チョコ 飴 1個 ¥150 2個 ¥190 1個 ¥100
  23. 23. 23 やりたいこと • ShopのCRUD • 「Shopが販売するItem」のCRUD • 「ItemごとのPrice」のCRUD
  24. 24. 24 で実装すると・・・ • ShopのCRUD • /shops [POST/GET] • /shops/{id} [GET/PUT/PATCH/DELETE] • 「Shopが販売するItem」のCRUD? • /items [POST/GET] • /items/{id} [GET/PUT/PATCH/DELETE] • 「ItemごとのPrice」のCRUD? • /prices [POST/GET] • /prices/{id} [GET/PUT/PATCH/DELETE]
  25. 25. 25 ん? 何か思ってたのと違う…
  26. 26. 26 こんな感じを期待していた • ShopのCRUD • /shops [POST/GET] • /shops/{id} [GET/PUT/PATCH/DELETE] • 「Shopが販売するItem」のCRUD • /shops/{id}/items [POST/GET] • /shops/{id}/items/{id} [GET/PUT/PATCH/DELETE] • 「ItemごとのPrice」のCRUD • /shops/{id}/items/{id}/prices [POST/GET] • /shops/{id}/items/{id}/prices/{id} [GET/PUT/PATCH/DELETE] URLから 階層構造が 読み取れる
  27. 27. 27 で 生えてくる たち • 全部がトップレベルリソース • リソース同士はrelationのリソース(/A/{id}/B/{id})で繋がる • そこには上位下位の関係性はない • ちょっとそれは「頭の中の階層構造」と違う・・・ Shop Item Price Shop Item Price Data REST上の構造 頭の中の構造
  28. 28. 28 他の問題も出てきた
  29. 29. 29 リソース横断の をしたい
  30. 30. 30 やりたいこと • ShopのCRUD • 「Shopが販売するItem」のCRUD • 「ItemごとのPrice」のCRUD • 「あるItem内のPrice全部」をまとめて更新したい
  31. 31. 31 リソース横断の をしたい • 「あるItem内のPrice全部」= 複数のリソースをいっぺんに更新したい 商品 個数 価格 チョコレート 1 150 飴 1 100 飴 2 190
  32. 32. 32 リソース横断の をしたい • 「あるItem内のPrice全部」= 複数のリソースをいっぺんに更新したい • 生えてくるエンドポイントは1つずつしか操作できない 商品 個数 価格 チョコレート 1 150 飴 1 100 飴 2 190
  33. 33. 33 リソース横断の をしたい • 「あるItem内のPrice全部」= 複数のリソースをいっぺんに更新したい • 生えてくるエンドポイントは1つずつしか操作できない • 「1つずつAPI callすればいいじゃん」 -> トランザクション管理の問題が発生 商品 個数 価格 チョコレート 1 150 飴 1 100 飴 2 190
  34. 34. 34 リソース横断の をしたい • カスタムエンドポイントを作る • e.g. /items/{id}/prices [PATCH] • Spring Data RESTと通常の@Controller(@RestController)はConflictしないので、 エンドポイントの追加は問題ない • でもこれ、Spring Data RESTのリソース概念と対立する・・・ -> 1つのAPIの中でI/F設計がブレる
  35. 35. 35 ビジネスロジックのモデル 側のモデル
  36. 36. 36 ビジネスロジックのモデル のモデル • Spring Data RESTで生えてくるエンドポイントのI/Fは 良くも悪くもDBのデータ構造そのまま • DBのスキーマ変更=APIのI/F変更 • 「パフォーマンスのためにDB設計変えたい」ってなったとき、 玉突きでビジネスロジックAPIも一緒に変更する必要がある データ アクセス API DB ビジネス ロジック API ここを変えたら こっちも 変えなきゃ
  37. 37. 37 ビジネスロジックのモデル のモデル • 案1. ビジネスロジックAPI側が頑張る • ビジネスロジックAPI側がDB設計の変更に追従する • 案2. データアクセスAPI(DB設計)側が譲歩する • DBのデータ構造を可能な限りビジネスロジック側に合わせる • パフォーマンスとか冗長性の排除とかは、諦める データ アクセス API DB ビジネス ロジック API
  38. 38. 38 ん~・・・ 一度立ち止まって考えてみる
  39. 39. 39 今回のお題アーキテクチャ データ アクセス API DB シンプルな CRUD操作だけ 提供する
  40. 40. 40 シンプルじゃない 操作がしたくなった
  41. 41. 41 今回のお題アーキテクチャ ビジネス ロジック API データ アクセス API DB ビジネスロジックと データを分離
  42. 42. 42 ビジネスロジックと データが分離できてない
  43. 43. 43 ダメじゃん
  44. 44. 44 アーキテクチャの再考 • いくつかの役割・機能をデータアクセスAPIに持たせる • 「ロジックと実データ構造の差異を吸収する」役割 • 「リソースまとめて更新」機能
  45. 45. 45 となると、 向いてないのでは
  46. 46. 46 との別れ • 得たもの • 自由 • 失ったもの • 時間 • 「Spring Data RESTがこうなってるから、○○はできない」 という言い訳
  47. 47. 47 が我々にもたらしていたもの • (良くも悪くも)制約 • 良いところ • 実装すべきコードがとても少ない • 制約により選択肢が狭まる → 迷わない • イマイチだったところ • 制約が強い → その周辺の設計(DB、ビジネスロジックAPI)に強く影響してしまう
  48. 48. 48 は 使えないコなの
  49. 49. 49 は使えないコなの • やりたいこととSpring Data REST Wayが合致すれば強い • 実際に使ってみたことで、合うもの/合わないものがはっきりと分かった • ちなみに、楽天トラベルの別プロジェクトでは絶賛本番稼働中 • 無理やり使おうとするのがダメだった • あえて制約を強くしているものに対して、抜け道を探しまくるのは良い手ではない
  50. 50. 50 まとめ • Spring Data RESTで簡単にRESTful APIを作れる • 用法用量を守って使いましょう • Spring Data RESTが輝ける場所で採用しましょう • たくさんの階層構造を持たないデータ • 「リソースごとの単純なCRUDしかしない」ようなデータ
  51. 51. 51 引用文献 GitHub •https://github.com/logos Qiita •http://help.qiita.com/ja/articles/others-brand-guideline いらすとや •http://www.irasutoya.com/p/terms.html フリー素材 ピクトグラム •https://free-pictograms.com/ Spring Data REST •https://projects.spring.io/spring-data-rest/ •Accessed on 2017-11-21

×
Save this presentationTap To Close