Microservices Meetup vol.5 (API Gateway & BFF) 行ってきた（速報）

ブログまとめ枠を逃して通常参加だったけど、最速目指してまとめます。

速報版です。誤字脱字、情報漏れは順次保管していきます。


Connpassイベントページ
https://microservices-meetup.connpass.com/event/52516/

Twiiterタイムライン
https://twitter.com/search?q=%23microserv

Togetterまとめ
https://togetter.com/li/1095919

@wenbose さんのまとめ
[Microservices Meetup vol.5 に行ってきたので雑にまとめる](http://qiita.com/wenbose/items/1ba93338f2be6ab676c9)


レポート
===


「APIのことはすべてシーマンが教えてくれた。」 by @charlier_shoe さん
---

https://www.slideshare.net/charlier-shoe/api-73960006

Oracle 早川さん

（到着遅れたので途中からです……orz）

### backend for frontend

* クライアント最適化した形式に変換

### API Platform Cloud Service（宣伝）

近日公開予定

* APIライフサイクルをサポートする機能群をすべて揃える
* 環境を選ばずに利用可能
    * オンプレ、クラウド
* Apiary機能統合

直接APIを作るものではなく、APIのライフサイクルをサポートするもの

* APIドキュメントをSwagger/API Blueprintで記述して
* ワンクリックで開発者ポータルに公開されてモックが生まれる
* 

Documentation-Driven Contracts

* MarkdownとJSON混ぜたような記法で記述するとドキュメントが出来る

### Oracle Code

開発者向けイベントやります！ 5月開催予定


「step by step BFF」 by @yosuke_furukawa さん
---

https://speakerdeck.com/yosuke_furukawa/step-by-step-bff

日本Node.jsユーザグループ会長
リクルートテクノロジーズ 古川さん

レガシーソフトウェア改善ガイド
Re-Architecte

モノリス的なアーキテクチャでスケールしないと感じたら、フロントエンドとバックエンドと分けて考える

### BFFとは

マイクロサービスがBackendsにあって、BFFがあって、Frontendsがある。

Sam Newmanさんが多分最初に提唱したっぽい。

#### ユースケース1つめ

APIまとめる君

複数のAPIをBFFで呼んでフロントエンドのほしい形にJSONにして返す

#### ユースケース2つめ

セッション管理

セッションストアとのやり取りをしたうえで、APIを呼ぶ


#### ユースケース3つめ

SSR

HTMLのレンダーをしてHTMLを返す


#### ユースケース4つめ

ファイルアップロード

大きいファイルを投げるのはAPIは使いにくい、FileChunkedUpload使いたい

BFFで受けっとったチャンクをS3などに1つのファイルに戻してから、バックエンドのAPIをファイルパスをパラメタにしてリクエストする


#### 5つめ

リアルタイム処理 WebSocket/LogPolling/SSE

フロントはWebSocketなど、バックエンドとPub/Subする


### BFF以前

* 90年代まで3層C/Sシステムだった
* 90年台半ばからはWEBシステム
* 2010年はSPA
* 2013年はSPA with Microservices

どんどんクライアント側にロジックが寄っている&サーバが薄くなっている

でもフロントエンドはUIに注力したい

この流れをバランスさせるためにBFFはあるのではないか？

BFFをNode.jsにすると、FrontendsとBFFをロジック共通化が図れる

### BFFとは

ドメイン特化のサービスとリッチなクライアントをつなぐ調停役


### Twitterの例

モバイルTwitterを移行したよ

Scalaでマイクロサービス作って、BFFをNode.jsで作成

* 最初はRails
* 途中からScala化してMicroServices化
* 最近Node.jsでモバイル用のフロントエンドを差替えた

WEBシステムの変遷を辿っているのが興味深い

### Netflix

Netflixはバケモノ

#### 内部APIを再設計した

デバイスが異常に多い＝APIも異常に多い

間に調停役BFFを置く（当時はクライアントアダプタコードと呼ばれていた）
デバイスごとに適切なレスポンスを返すBFFがいる

2012年の話

OSFA(One Size Fit All)しないほうが作りやすい＝1つで全てに対応しない

### リクルートテクノロジーズ

SSRをBFFでやってる

#### BFFを導入するとき

* フロントエンド、バックエンドを分業させてエンハンス速度を上げる
* レガシーなシステムをリアーキテクトする


#### BFFを導入しないとき

* フルスタックが多い
* モノリシックで速度を取る
* SEOいらない、リアルタイムいらない

#### step by step BFF

既存システムとフロントエンドの間にBFFを挟む（タダのProxyとして）


「Webサービスの初期開発とマイクロサービス・BFF」 by @shimpeiws さん
---

https://speakerdeck.com/shimpeiws/websahisufalsechu-qi-kai-fa-tomaikurosahisubff

アカツキ 高松さん

### ライブなエクスペリエンスを提供するサービス

リアルタイム性を求められる

### 技術要素

* SPA(React+Redux)
* Isomolphic Architecture
* Rails

など

### 開発初期の選択と集中と課題

#### 立ち上げ期

* フルスタック４人

アーキテクチャ、設計指針決定

#### 開発初期

* フルスタック５人

#### 開発中期

* 4チームに分割
    * ユーザ系、サービス基盤系、インフラ系……

専門性が必要な業務が増えてきた

* グロースハック
* MW,デプロイとか


### コード比率

* rails 15,000行
* JS/JSX 60,000行
* JS 25,000行


### 反省点

**「後から考えられるようにしておくのと、何も考えていないのは完全に別だし、やってはいけない」**

### 立ち上げ期

#### SPA + SSRは最初から確定していた

ちょっと要件重いかもという自覚はあったが要件として必要だった

##### Pros

ダイナミックなWEBフロントエンドを作りやすい
SPAの構成で一本化

##### Cons

開発工数はかかった
Node.jsのフロントサーバが増えて、デプロイ、管理が複雑化した

#### API設計を単純化

ドメイン設計に時間が掛けられなかった
画面ベッタリなAPIだと保守性下がるのでしたくない

細かい粒度で作るようにした

設計・実装が楽になった

クライアントサイドの実装に負荷がかかるようになってしまった

### ここでBFF！

レイヤーをたせるようにしておくのはリアーキテクチャしやすい

API関連のアーキテクチャの決定をペンディングすることが出来ていた

#### BFFに求めるもの

レスポンスが低下するのは避けたい
フロントエンドと密結合するため更新頻度が上がる

言語、フレームワークの選定大事


フロントエンドからのハンドリングが減った

BFF実装は難しくないけど複雑
ジェネレータとか使わないと面倒くさいかも


ウェルネスタイム
---

* 体側伸ばし
    * 片腕を伸ばして、もう片腕で手首をつかむ
    * 伸ばした腕側の体側を伸ばすように体を傾ける
    * 傾けたまま体をひねって、下を向くように
* ワイドスクワット
    * 足は肩幅以上に開く
    * 椅子にお尻が少しつくくらいに腰を落として立ち上がる
* ふくらはぎ伸ばし
    * かかとを付けて、足先を30度くらいに開く
    * かかとを付けたまま背伸び
    * 5秒キープ


「Railsで作るBFFの功罪」 by @shotat_jp さん
---

https://www.slideshare.net/RecruitLifestyle/railsbff

ホットペッパービューティ HPB
2007年からサービス

リクルートはココ数年でシステムの内製化を始めてる

１０年運用したシステムは密結合＆レガシーだった

### 課題

* View/Logicが混在
* そもそもMicroservices化いるのか？

### どうしたか

* バックエンドとBFFを切り離した
* サービスの分離（マイクロサービス化はしなかった）

Strangler Application
『マクロサービスアーキテクチャ』に書いてある

* API呼び出し回数が増えないようにする
* かといって全部入りAPIは作らない

* BFFからのAPI呼び出し回数は７回くらい

### 仕組み

* APIサーバはSpring Boot
    * 既存コードと同じJavaだったので
* DocはSwagger

* BFFはRails
    * 開発者が多い
    * Sinatraとかも考えたが主流から離れそうという懸念
* Node.js/Goの方が良いのではないかという検討はあった
    * 開発効率優先
    * パフォーマンス、SPAは優先度低かった

### BFFの役割

* 
* API Caching
* SSR

### Rails

* ActiveRecord削る
* 削りすぎないように注意した

### MVC + R

* One Repository : One EndPoint
* 

### 性能面

* API直列呼び出しは遅い
* NWは意外とボトルネックにならない
* フルレンダリングは重い

でもとりあえず十分な性能が出たので保留

### BFFのチューニング

RackをPumaにする
IO wait でスレッドを切り替える
CPUが振り切れてしまうのでこのケースでは効果が上がらなかった

BFFを薄くする
Rubyコードのチューニング
効果が大きかった

APIの並列リクエストを使う

APIキャッシュを使う
考えること多い

BFFの後ろにBatch専用のAPIGatewayを立てる
APIGatewayの多段化

120ms -> 75msに短縮

* スループット
    * BFF薄くする
* レスポンスタイム
    * 必要になるまでは後回しで良いかも



パネルディスカッション
---

### API GatewayとBFFの違いは何か

* API GatewayはBFFに包含される概念
    * 1つの使い方
    * 流量制御や認証もBFFでやると良さそう

### API Gateway製品のカバー範囲

* 製品名にAPI Gatewayって使われることが多い。自動でやってくれるとか。BFFっていうと自分たちでコード書かないと行けないイメージ。
* API Gatewayってどこまでやってくれる感じ？
    * OAuthなどのRESTに近い部分は含まれそう
    * WebSocketとかRESTと直接関係ない部分は当面含まれないのではないか

### KongなどのAPIまとめるようなことをしてくれるけど、Oracle API Cloudではやってくれる？

* Service Fallout?という返す情報に必要なAPIを更に呼ぶ機能がある？

### BFFがバックエンドに近いところをどこまで持つ

* BFFにロジックをどこまで持たせるか？ 指針などあるか
    * 前提としてバックエンドはRESTfulになってるとしてDDD的な意味でドメイン層になるのでビジネスロジックはすべて持つ
    * BFFでビジネスロジックの解決はしない
        * フロントエンドが要件を伝えてバックエンドがビジネスロジックを組む
    * バックエンドにSQLをパラメタとして投げるような設計はしない
* BFFがポストオーケストレーションみたいなことはしない？
    * ポストオーケストレーションはドメインロジックなのでBFFのしごとじゃない

### BFFの担当はフロント？バック？独立？

* フロントエンドエンジニアがやっている
* "for Frontend"なのでフロントエンドが責務を持つべき

### RPCかクエリか？（聞き損ねた）

* GitHubはRESTfulとGraphQLを提供している
    * RESTfulだけだと効率悪いからGraphQLを提供している
        * これはコンシューマに利用してほしいから
* RPCにするのかGraphQLにするのかという話は利用者が誰かによって判断

### フロントとバックエンドだけで分けた理由

* 速度が必要だった
* フロントに負荷が行くのはわかっていた
    * 今後GraphQLを入れるか、BFFを入れるかは検討していく


> 「マイクロサービスはバックエンドエンジニアにワクワクを与えてくれるアーキテクチャ、BFFはフロントエンドエンジニアにワクワクを与えてくれるものと思っている」





# 感想

* リアーキテクトの実例が出始めた（マジで感謝！）
* リアーキテクトのためにBFFを入れるところから段階的にすすめる手法に希望を感じた
* やっぱり最初は少数精鋭で始めるのが良さそう
* アーキテクチャレイヤー追加の余地を残すなどの冗長さは必要