Contenu connexe Similaire à ホットペッパービューティーにおけるモバイルアプリ向けAPIのBFF/Backend分割 (20) Plus de Recruit Lifestyle Co., Ltd. (20) ホットペッパービューティーにおけるモバイルアプリ向けAPIのBFF/Backend分割2. ⾃⼰紹介
• Nawate Ippei
• リクルートライフスタイル
• 2016/04に新卒⼊社
• ⼊社してからずっとホットペッパービューティー
• 仕事内容
• 2016/04 ~ 2018/01 Androidエンジニア
• 2018/01 ~ サーバサイドエンジニア
https://twitter.com/sakuna63
https://github.com/sakuna63
8. BFFとは何か?
• BFF = Backends For Frontends
• マイクロサービスアーキテクチャの1つ
• FrontendとAPI Serviceの間に位置するBackendサーバ
• 個々のサービスが提供するAPIを集約し、Frontendに特化したレスポンスを返す
API Service
API Service
API Service
JSON
HTML
CSS, JS
BFF for Web
BFF for App
Search
Engine
Mobile App
Browser
28. 分割⽅針の振り返り
処理分担の基準について
• 基本的に、この基準で迷いなく開発できている 👍
• ⼀点悩んだところがあったので次のスライドで紹介
• BFFの開発スピードが早くなるかはこれから検証 🧐(保守・運⽤が始まったばかりなので)
BackendのAPI粒度(REST)について
• 参照系のBackend API(GET)の四分の⼀(24本中6本)がBFF API間で再利⽤できている 👍
• 逆に更新系の Backend API(POST, PUT, DELETE)はBFF APIと1:1で対応することがほとんど
29. 分割⽅針の振り返り
処理分担の基準について
• 基本的に、この基準で迷いなく開発できている 👍
• ⼀点悩んだところがあったので次のスライドで紹介
• BFFの開発スピードが早くなるかはこれから検証 🧐(保守・運⽤が始まったばかりなので)
BackendのAPI粒度(REST)について
• 参照系のBackend API(GET)の四分の⼀(24本中6本)がBFF API間で再利⽤できている 👍
• 逆に更新系の Backend API(POST, PUT, DELETE)はBFF APIと1:1で対応することがほとんど
54. BFFの技術選定の振り返り
• Kotlin x Springは違和感なく開発できている 😄
• 「KotlinだからSpringが活かせない」ということは全くない
• 「SpringだからKotlinが活かせない」とういことも全くない
• 個⼈的に気に⼊ってるポイント
• SpringはNonnull/Nullableがしっかりアノテートされているので、
KotlinのNull安全性が活きる 💪
• Spring公式提供の拡張関数群も充実
• 今後は、spring-fu/kofuのようなDSLにも期待
63. Backendのアプリケーション層実装例
@Usecase
@AllArgsConstructor
public class ReservationUsecase {
/**
* 予約一覧を返却する
*/
@Nonnull
public GetReservationResponse getReservations(...) {
//...
// GetReservationResponse = レスポンス構造を表すレスポンスDTO(View)
// Usecase(アプリケーション層)の時点でViewのインスタンスを返却する
return GetReservationResponse.builder()
.totalCount(count)
.reservations(reservationDtos)
.build();
}
• アプリケーション層の時点でView(Json)と対応するDTOを返す
71. BFFのアプリケーション層実装例
fun getMessageBox(userId: String, salonId: String): Mono<HairMessageBox> =
clientSalonRepository.getById(salonId)
.flatMap { clientSalon ->
salonRepository.getById(salonId)
.map { it.toDto() } // サロンが掲載中なら掲載情報を使って返却する
// 非掲載(掲載情報の取得に失敗した)ならサロンボードの登録情報を使って返却する
.onErrorResume { Mono.just(clientSalon.toDto()) }
}
// メッセージの検索と、未読数の取得を行う
.flatMap { messageRepository.getMessagesBySalonId(userId, salonId) }
.map { (salon, response) ->
HairMessageBox(
total = response.total,
salon = salon,
messages = response.messages.map { it.toDto() }
)
}
• Serviceの実装例、複数のAPI(Repository)を呼び出して結果を集約していく
74. • e.g. Spring Bootのアップデート
• アプリチームにこれを任せるのはスキル的に難しそう
• 技術的なサポート体制構築が必要になる
BFF開発体制構築の課題(1/2)
アーキテクチャレベルの開発課題への対応が難しい
78. • こういった前提を踏まえると
「参照のためのDBリソースを増やす = リードレプリカのスケールアウト」
がBFF/Backend構成のキモなのではないか?と思える。
• ちなみに、ホットペッパービューティーではOracle DBを利⽤しているため
スケールアウトが難しい 😅(※ インスタンス課⾦のため)
• Backendレスポンスをキャッシュするなど、別の負荷対策が重要になってくる
余談:BFF/Backend構成はリードレプリカのスケールアウトがキモ?