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