Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DartによるBFF構築・運用 〜 Dart Frog × Melos 〜

Ryotaro Onoue
November 10, 2023

DartによるBFF構築・運用 〜 Dart Frog × Melos 〜

FlutterKaigi 2023 登壇資料

Ryotaro Onoue

November 10, 2023
Tweet

More Decks by Ryotaro Onoue

Other Decks in Programming

Transcript

  1. スピーカー名
    DartによるBFF構築・運用 〜
    Dart Frog × Melos 〜
    もぐもぐ / K9i

    View full-size slide

  2. 自己紹介

    View full-size slide

  3. もぐもぐ
    ↓こんなの

    View full-size slide

  4. もぐもぐ
    - Ryotaro Onoue
    - なんでもぐもぐにしたのか覚えてません
    - 食べるのは好きです
    - ゆめみのFlutterエンジニア
    - 2023年4月に新卒として入社
    - Flutter/Dart歴 3年

    View full-size slide

  5. もぐもぐ
    - 地震関連のアプリ開発してます
    - 今年中にアプリストアでリ
    リース予定

    View full-size slide

  6. K9i
    - Kota Hayashi
    - K9iはK8s(Kubernetes)とかL10n(Localization)と同じ感じ
    - Kota->Tako->🐙
    - K9iはケーナインアイだがいいづらいので、林呼び推奨
    - ゆめみのFlutterリードエンジニア
    - 1社目:Androidなど(この時期に趣味でFlutterをはじめた)
    - 2社目:Flutter
    - 3社目:今年の5月からゆめみ
    - Flutterは4年目くらい

    View full-size slide

  7. K9i
    - RiverpodのChangelogに稀に生息

    View full-size slide

  8. 会社の紹介

    View full-size slide

  9. 株式会社ゆめみ
    - 公式アカウントの大喜利で有名😅

    View full-size slide

  10. ゆめみFlutterギルド
    - イベントやっとります

    View full-size slide

  11. アジェンダ

    View full-size slide

  12. アジェンダ(1/3)
    1. Dartバックエンドの世界
    a. Dartのおさらい
    b. Dartバックエンドフレームワークの紹介
    c. BFFとは
    2. プロジェクトの背景
    a. ゆめみ参入の経緯
    b. バックエンドの構成変更
    c. Flutter向けBFFの方針
    前半

    View full-size slide

  13. アジェンダ(2/3)
    3. 技術スタックの紹介
    a. Flutterチーム担当領域のプロジェクト構成
    b. Dart Frog解説
    c. Melos解説
    4. 実践した感想
    a. Dockerのつらみ
    b. [TODO]
    後半

    View full-size slide

  14. アジェンダ(3/3)
    5. Liveデモ
    a. [TODO]
    6. まとめ
    後半

    View full-size slide

  15. 1. Dartバックエンドの世界

    View full-size slide

  16. Dartのおさらい

    View full-size slide

  17. Dartとは
    - Googleが開発
    - 2011年10月10日に登場

    View full-size slide

  18. Dartのこれまで(超ダイジェスト)
    - JavaScriptの代替となることを目的に作られた
    - 2011年末までにVMがChromeに統合される予定だった
    - 普及は進まず2015年にはChrome統合を断念
    - Skyフレームワーク(Flutterの前身)がJavaScriptの変わりとなる言語と
    探していたところDartと出会う
    - 2015年にSkyがDartをはじめて導入
    - 以降Flutterとともに成長し今に至る

    View full-size slide

  19. Dartバックエンドという選択肢
    - Flutterの普及に伴いバックエンドもDartで開発したい欲求
    - 言語を統一することで様々なメリット
    - 同じメンバーがフロントエンドもバックエンドも開発
    - コードの共有・再利用
    - ツール・ライブラリの共通化
    - etc…

    View full-size slide

  20. Dartバックエンド
    フレームワークの紹介

    View full-size slide

  21. Aquaduct
    - 概要
    - 懐かしかったので紹介(知ってたら古参?)
    - Stable Kernelが2018年に開発
    - 2021年に開発中止されリポジトリはPublic archive
    - Conduct
    - AquaductのFork
    - 活発に開発されてはなさそう?(最終更新半年前)

    View full-size slide

  22. Serverpod
    - Serverpod社が開発するFlutter向けのアプリサーバー
    - トップページに「The missing server for Flutter」とありFlutterを
    強く意識している
    - 2021年に発表され、2023年1月31日に1.0になった
    - CLIでプロジェクトを作成するとFlutterアプリとバックエンドが両方作成さ
    れる
    - 後述するDart Frogなどに比べ多機能な印象

    View full-size slide

  23. Shelf
    - Dartチームによって開発されているサーバーフレームワーク
    - 0.1.0は2014年に公開
    - Shelf本体は軽量
    - 複数のShelf用パッケージを組み合わせて使うモジュール方式
    - shelfのリポジトリだけでも複数のパッケージが存在

    View full-size slide

  24. Dart Frog
    - VGV(Very Good Ventures)が開発しているサーバーフレームワーク
    - 開発元がFlutter界隈で有名なので注目されている
    - 2022年に発表され、2023年8月2日に1.0.0になった
    - Shelfをベースに構築されている、Shelf同様軽量
    - こちらも複数パッケージを組み合わせるモジュール方式
    - Shelfをより便利に使えるような機能がある
    - 技術スタック紹介の章で説明

    View full-size slide

  25. BFFとは
    - BFF(Backend For Frontend)
    - 初めて名前を聞くと言う人もいるかも?
    - フロントエンド(アプリ含む)とバックエンドの中間に置かれるサーバー
    - ???

    View full-size slide

  26. BFFの例1:バックエンドが複数

    View full-size slide

  27. BFFの例2:フロントエンドが複数

    View full-size slide

  28. BFFとは
    - メリット
    - APIの集約
    - 複数のバックエンドを一つのAPIでフロントエンドに提供
    - 特定のフロントエンドに特化
    - WebにはGraphQL、アプリにはREST
    - 開発言語も対応するフロントエンドと揃えたりできる
    - デメリット
    - 開発コスト
    - 複雑・冗長

    View full-size slide

  29. 2. プロジェクトの背景

    View full-size slide

  30. ゆめみの参入の経緯

    View full-size slide

  31. 参入プロジェクト
    - 介護・看護分野の企業と労働者のマッチングサービス
    - PMF(プロダクトマーケットフィット)の段階
    - フロントエンドは3種類存在
    - 企業用Webフロントエンド
    - 労働者用Webフロントエンド
    - 労働者用モバイルアプリ(これを担当)

    View full-size slide

  32. 参入前のプロジェクトのメンバー
    - バックエンド、PMなど:顧客企業の方がフルタイム稼働
    - ゆめみはクライアントワーク
    - Webフロント:ゆめみのフロントメンバー(別チーム)が日中稼働
    - モバイルアプリ:副業メンバーが夜間など不規則な稼働

    View full-size slide

  33. 参入前の課題
    - モバイルアプリの開発メンバーが不規則な稼働
    - クライアント企業の方とコミュニケーションがとりづらい
    - 思うようにモバイルアプリ開発が進んでいなかった
    - Flutter・Dart得意なメンバー不在
    - 全体的に負債の塊
    - ゆめみのFlutterギルド参入で課題を解決したい
    - 今年8月〜

    View full-size slide

  34. バックエンドの構成変更

    View full-size slide

  35. バックエンドの構成変更
    - プロジェクト参入次点でバックエンドの構成変更が進行中
    - PMF期に生じた負債の解消

    View full-size slide

  36. 元々の構成

    View full-size slide

  37. 元々の構成
    旧バックエンドは元々モバイルアプリ
    用に作られたが、Webからも使われ
    るようになってしまう
    特定のフロントエンドのための分岐と
    うで複雑に

    View full-size slide

  38. 目的とする構成

    View full-size slide

  39. 目的とする構成
    フロントエンドごとに BFFを作り、特定
    のフロントエンドのためのロジックを
    移譲
    旧バックエンドは廃止

    View full-size slide

  40. Flutter向けBFFの方針

    View full-size slide

  41. Flutterチームの担当

    View full-size slide

  42. Flutter向けBFFの方針
    - 実は作り途中のBFFがあったが…
    - 色々と課題…
    - 廃止されるまでは旧バックエンドも部分的に使う
    - Dartで統一
    - Jsonをやり取りするクラスをクライアントと共通化
    - せっかく新規に作るので気になる技術を試す
    - Dart Frog、Melos
    - 賛否有りそうだけど大事

    View full-size slide

  43. Flutter向けBFFの方針

    View full-size slide

  44. Flutter向けBFFの方針 旧バックエンドを当分は直接利用
    いずれは消える

    View full-size slide

  45. Flutter向けBFFの方針 初期リリースでは一部のエンドポイン
    トラップ(とりあえず動かすため)

    View full-size slide

  46. 3. 技術スタックの紹介

    View full-size slide

  47. Flutterチーム担当領域の
    プロジェクト構成

    View full-size slide

  48. リポジトリ・パッケージ構成

    View full-size slide

  49. 主な利用技術
    - Melos
    - マルチパッケージ構成の管理に利用
    - Dart Frog
    - BFFの実装に利用
    - Freezed、JsonSerializable
    - クライアントとBFFで共有する通信用の型で利用
    - 一般的だと思うので解説しません🙏

    View full-size slide

  50. マルチパッケージとは
    - 複数のDartパッケージでプロジェクトを構成する手法
    - 機能やレイヤーごとのディレクトリを作るのではなく、パッケージに切
    り出す
    - パッケージごとにリポジトリを作ると管理が大変なため、1つのリポジトリで
    複数パッケージを管理するのが一般的
    - モノレポともいう

    View full-size slide

  51. マルチパッケージ利点
    - 大規模なアプリで機能・レイヤーごとにパッケージを分ける
    - 関心の分離
    - 意図しない依存を防ぎやすい
    - 共有コードをパッケージに切り出せる
    - 今回やりたかったこと

    View full-size slide

  52. Melosとは
    - Dartでのマルチパッケージを支援するコマンドラインツール
    - Invertaseが開発しており、有名パッケージの開発にも使われている
    - Riverpod、FlutterFireなどが利用
    - Melosの開発にもMelosが使われている
    - 注意:マルチパッケージならMelos必須というわけではない
    - 使ってないリポジトリも
    - Flutter News Toolkit、I/O Flip

    View full-size slide

  53. Melosのはじめかた
    - グローバルにインストール
    - dart pub global activate melos
    - プロジェクトのルートにmelos.yamlを作る
    - melosのコマンドが使えるようになる

    View full-size slide

  54. Melosの機能
    - Commands
    - Filter
    - Scripts

    View full-size slide

  55. Commands
    - モノレポをやりやすくするいくつかのコマンドがある
    - bootstrap / clean
    - exec
    - list
    - publish
    - run
    - version

    View full-size slide

  56. Commands
    - モノレポをやりやすくするいくつかのコマンドがある
    - bootstrap / clean
    - exec
    - list
    - publish
    - run
    - version
    これらを紹介

    View full-size slide

  57. bootstrap / clean
    - 複数パッケージに対してpub get
    - pubspec_overrides.yamlの用意
    - リポジトリ内の依存を相対パスでoverrideして開発中バージョンを使
    うようにする
    - 問題に気づきやすくなるなど利点がある
    - cleanはbootstrapの逆

    View full-size slide

  58. exec
    - モノレポ内の複数のパッケージに対して同じコマンドを実行
    - これがないと一々ディレクトリ移動してbuild_runner実行みたいにな

    - 後述するfilter機能と組み合わせる

    View full-size slide

  59. list
    - モノレポ内のパッケージをリスト表示
    - 依存関係などを簡単に確認

    View full-size slide

  60. publsh
    - モノレポ内のパッケージをpub.devに公開しやすくするコマンド
    - アプリ作る分には使わない

    View full-size slide

  61. run
    - 後述するScripts機能を実行するコマンド

    View full-size slide

  62. version
    - Conventional Commitsの作法に従っている場合に自動でバージョニン
    グができる
    - 「feat: hoge」みたいなcommit
    - !をつけると破壊的変更としてメジャーバージョンがあがるなどのルー
    ルがある(feat!: hoge)
    - tagで前回からの差分を判断
    - 手動バージョニングにも使える

    View full-size slide

  63. Filter
    - Commandsの対象パッケージを絞り込む機能
    - melos bootstrap --no-privateなら--no-private部分
    - いくつかのフィルターがある
    - scope:特定の文字列を含むパッケージのみ
    - depends-on:特定のパッケージに依存してるパッケージのみ
    - 他にも色々

    View full-size slide

  64. Scripts
    - melos.yamlにスクリプトを定義しておきrunコマンドで実行できる
    - よく使うものを登録しておき、CIからも使うと良い感じ

    View full-size slide

  65. Dart Frog解説

    View full-size slide

  66. Dart Frog(再掲)
    - VGV(Very Good Ventures)が開発しているサーバーフレームワーク
    - 開発元がFlutter界隈で有名なので注目されている
    - 2022年に発表され、2023年8月2日に1.0.0になった
    - Shelf上に構築されており、Shelf同様軽量
    - こちらも複数パッケージを組み合わせるモジュール方式
    - Shelfをより便利に使えるような機能がある
    - 技術スタック紹介の章で説明

    View full-size slide

  67. Dart Frogのはじめかた
    - グローバルにインストール
    - dart pub global activate dart_frog_cli
    - DartのコマンドラインツールなのでMelosと同じ
    - dart_frog create my_project
    - 最低限のDart Drogのコード
    - dart_frog devですぐ動く

    View full-size slide

  68. Dart Frogの基本機能・特徴
    - ホットリロード対応
    - ファイルベースルーティング
    - 便利なクラス
    - Middleware
    - DI
    - テストの容易性

    View full-size slide

  69. ファイルベースルーティング
    - ディレクトリ構成がそのままルーティングに対応する
    - ”/”と”/hello”のエンドポイントに対応させる場合
    - 画像のどちらか
    - 競合したらビルド失敗等で分かる

    View full-size slide

  70. エンドポイントの追加方法
    - もちろん手動でファイルを追加すればできるが
    - コマンドで追加も可能
    - dart_frog new route "/hello"

    View full-size slide

  71. 追加直後のエンドポイント
    - RequestContextを受け取ってResponseを返す関数

    View full-size slide

  72. エンドポイントの追加方法
    - もちろん手動でファイルを追加すればできるが
    - コマンドで追加も可能
    - dart_frog new route "/hello"
    - dart_frog_cliのコマンドはMasonで実現されている
    - Masonはテンプレートからコードを生成するDartツール
    - ファイルベースルーティングなのはテンプレートからの生成との
    相性が良いからかも?

    View full-size slide

  73. 便利なクラス
    - Dart FrogはShelfのクラスをラップして便利にしている
    - 先程のRequestContext

    View full-size slide

  74. RequestContext

    View full-size slide

  75. RequestContext
    - 内部的にshelfのRequest

    View full-size slide

  76. body、jsonなどよく使うであろうメソッ
    ドが事前に用意されている

    View full-size slide

  77. Middleware
    - ディレクトリごとに配置でき、サブディレクトリ含めて前処理を行える

    View full-size slide

  78. Middleware
    - handlerのuseにMiddleware(requestLogger)を渡す
    - 用途
    - ロガー
    - 共通のエラー処理
    - DI

    View full-size slide

  79. Middlewareのチェイン
    - useはMiddlewareを受
    け取りHandlerを返すの
    でチェインできる

    View full-size slide

  80. 補足:Shelfのリソースを活用

    View full-size slide

  81. DI
    - providerというMiddlewareでDIできる

    View full-size slide

  82. DI
    - middlewareでこうして

    View full-size slide

  83. DI
    - 利用側はRequestContextから取得

    View full-size slide

  84. テストの容易性
    - プロジェクト初期化次点でmock_tailが追加されている

    View full-size slide

  85. テストの容易性

    View full-size slide

  86. テストの容易性
    RequestContextはmocktailでモッ

    View full-size slide

  87. テストの容易性
    onRequest関数をテストすれば良い

    View full-size slide

  88. テストの容易性
    expectで確認!で完了

    View full-size slide

  89. もぐもぐタイム

    View full-size slide

  90. 4. 実践した感想

    View full-size slide

  91. サンプルコード
    - 実際のソースコードを見せることはできないので、簡素化したサンプルプ
    ロジェクトを作成しました
    - GitHub Repository Search APIの検索結果をBFFでキャッシュします
    - https://github.com/YumNumm/dart-frog-github-repository-se
    arch
    - 後でライブデモをするので そこで詳しくお話します

    View full-size slide

  92. サンプルコード

    View full-size slide

  93. 1. バックエンド と BFF のクライアントを同じように実
    装できた
    - アプリがBFFを叩く部分 と BFFがバックエンドAPIを叩く部分で同じパッ
    ケージを使った
    - 実装が似ているのでキャッチアップしやすい
    - retrofitを利用してクライアントを実装しました

    View full-size slide

  94. 2. API型定義の取り方
    - 実際の案件では、 Flutter App と BFF のリポジトリが別
    - Flutter Appは BFFのリポジトリにある 型定義へ依存している
    - どうするねん!

    View full-size slide

  95. 2. API型定義の取り方

    View full-size slide

  96. 2. API型定義の取り方
    - bff_api_typesをpub.devで公開すれば良いんじゃ!?
    → インシデント確定演出
    - git submoduleで置いて、path packageとして扱う
    → 微妙
    - pubspec.yamlのgit packageとして扱う
    → git経由の依存関係 よござんす👍

    View full-size slide

  97. API型定義の取り方
    - bff_api_typesをpub.devで公開すれば良いんじゃ!?
    → インシデント確定演出
    - git submoduleで置いて、path packageとして扱う
    → チョット汚い
    - pubspec.yamlのgit packageとして扱う
    → よござんす👍
    CI環境どうする!?
    - actions/checkoutでAppのコードをクローンしている
    - BFFのレポジトリはクローンできない

    View full-size slide

  98. 2. API型定義の取り方 - GitHub Deploy Keyのすゝめ
    - Deploy Keyとは?
    - 単一リポジトリへのアクセス(R, R/W)を許可するSSHキー
    - サーバ上でプロジェクトを起動するためのもの
    - publicな部分をリポジトリに privateな部分をサーバに配置
    - ユーザに紐づかないため、管理が楽
    cf. https://docs.github.com/ja/authentication/connecting-to-github-with-ssh/managing-deploy-keys

    View full-size slide

  99. 2. API型定義の取り方 - GitHub Deploy Keyのすゝめ
    - GitHub Actions内で SSHのprivate keyを展開
    - SSHできる用意をしてあげる
    - flutter pub get ヨシ👍

    View full-size slide

  100. 3. Docker を使う
    - Docker とは?
    - 仮想マシン(VM)とは違い、コンテナという単位でアプリケーションを実
    行できる
    - Dockerfileを書くことでコンテナビルド方法をコードで記述できる
    (IaC: Infrastracture as Code)
    - クラウドでもローカルでも実行できる
    - 実行環境依存のものを減らすことができる
    https://aws.amazon.com/jp/docker/
    より

    View full-size slide

  101. 3. Docker を使う
    - プロジェクトでAWS Fargate上でデプロイする必要があった
    - 環境に依存せずにローカルでデバッグできるようにしたかった

    View full-size slide

  102. OrbStackのススメ (余談)
    - Docker DesktopとWSLの代替品
    - macOSでDocker ContainerとLinux マシンを動かすことができるApp
    - Docker Desktopを使うよりも高速・軽量・シンプル
    https://orbstack.dev/
    - 個人利用であれば無料、
    商用利用は$8/month per user
    - macOS専用

    View full-size slide

  103. 3. Dart FrogのDockerfile 生成
    - dart_frog build で build/Dockerfileが生成される
    - buildコマンドを実行するためには dart_frog が実行できることが前
    提 (ホスト環境に依存してはいけない)
    - build/* をリポジトリに含めると、差分がすごいことになるので含めた
    くない
    → 自分でDockerfile書きますわ

    View full-size slide

  104. バイナリをビルドするための Dartコンテナ
    バイナリを実行するためのコンテナ
    builder
    scratch

    View full-size slide

  105. バイナリをビルドするための Dartコンテナ
    バイナリを実行するためのコンテナ
    builder
    scratch
    ローカルで依存しているライブラリの pubspec.yamlと
    pubspec_overrides.yaml
    をコピー
    ローカルで依存しているライブラリの全体をコピー

    View full-size slide

  106. バイナリを実行するためのコンテナ
    バイナリをビルドするための Dartコンテナ
    builder
    scratch
    builderで生成されたバイナリをコピーして
    実行する

    View full-size slide

  107. 5. LIVEデモ

    View full-size slide

  108. LIVEデモ
    - 実際のソースコードを見せることはできないので、簡素化したサンプルプ
    ロジェクトを作成しました
    - GitHub Repository Search APIの検索結果をBFFでキャッシュします
    - GitHub Personal Access Tokenセット済み -> レートリミット緩和
    - 仕様
    - GET /api/v1/repository/search : リポジトリ検索
    - param: query={検索文字列}
    - https://github.api.yumnumm.dev にデプロイ済み

    View full-size slide

  109. LIVEデモ
    GitHub Repository Search API BFF, App

    View full-size slide

  110. LIVEデモ - dart_frog create
    - dart_frog create hoge でプロジェクトを作成できる
    - dart_frog dev で実行
    - localhost:8080でアクセスできます
    - localhost:8181でDevToolへアクセスできます
    demo/1 Branch

    View full-size slide

  111. LIVEデモ - melos bootstrap
    - melos bootstrap で pubspec_overrides.yamlが生成される
    - melos clean でpubspec_overrides.yamlが消える
    - melos.yamlで記述したbuild_runnerスクリプトを実行できる
    demo/2 Branch
    - melos bootstrap で pubspec_overrides.yamlが生成される
    - melos clean でpubspec_overrides.yamlが消える
    - melos.yamlで記述したbuild_runnerスクリプトを実行できる

    View full-size slide

  112. LIVEデモ - Dart Frog BFF
    - dart_frog new route hoge でエンドポイントを作成できる
    - dart_frog dev で開発サーバを起動
    - http://localhost:8080/ でアクセスできる
    - http://localhost:8181/ でDevToolへアクセスできる
    - api/v1/repository/search の中身を実装していく
    demo/2 Branch

    View full-size slide

  113. LIVEデモ - Dart Frog × Docker
    - docker compose up -d /-build でコンテナを起動
    - [OrbStackを利用している場合] http://orb.local でコン
    テナ一覧を見ることができる
    -
    main Branch

    View full-size slide

  114. LIVEデモ - Application
    - 実際にFlutterアプリからアクセスしてみましょう
    - App: https://gh-repo-search.yumnumm.dev/
    - BFF: https://github.api.yumnumm.dev/
    (どちらも 2023/11/11 には閉鎖します )
    main Branch

    View full-size slide

  115. 6. まとめ

    View full-size slide

  116. 1章まとめ:Dartバックエンドの世界
    - Dart 12年の歴史
    - Chrome統合が失敗しオワコン化?
    - Sky(現Flutter)に採用され復活
    - Flutterの盛り上がりによりDartバックエンドの機運が高まる
    - ServerPod、Dart Frogなどが盛り上がる

    View full-size slide

  117. 2章まとめ:プロジェクトの背景
    - Flutterチームが夜間稼働でコミュニケーションなどに課題
    - ゆめみ参戦
    - PMF期に複雑化したバックエンドの構成変更
    - 3つのフロントエンドそれぞれのBFF越しに共通バックエンドを叩く構
    成にする
    - Dart Frog x MelosのBFFつくるぞい

    View full-size slide

  118. 3章まとめ:技術スタックの紹介
    - マルチパッケージ管理ツールMelosを使ってアプリとBFFでパッケージ共

    - Melos解説
    - 複数パッケージに対してコマンド実行などが便利
    - Dart Frog解説
    - ファイルベースルーティングとMasonによるコード生成
    - Shelfのクラスをラップした便利クラス
    - テストもやりやすい

    View full-size slide

  119. 4章まとめ:実践した感想
    - バックエンドとBFFのClient実装がほぼ同じ
    - BFF API 型定義をApp側と共有することで 保守性向上
    - モノレポでローカル依存が多いならではの Dockerfileのつらみ

    View full-size slide

  120. 5章まとめ:ライブデモ
    - 実際のプロダクトにBFFを取り込む過程を紹介
    - melos, dart_frog を利用することで、高速に開発を進めることができて
    いる
    - Dockerを利用してローカルで開発を行うこともできます

    View full-size slide

  121. 告知
    - この後同じルームでゆめみスポンサーセッション🥳
    通称:モリモリ山トリオ

    View full-size slide

  122. Links
    - https://ja.wikipedia.org/wiki/Dart
    - https://zenn.dev/mjhd/articles/680a19ae893c1e
    - https://github.com/stablekernel/aqueduct
    - https://serverpod.dev/
    - https://pub.dev/packages/shelf
    - https://dartfrog.vgv.dev/
    - https://github.com/felangel/mason
    - https://blog.codemagic.io/writing-your-backend-in-dart
    /
    -

    View full-size slide

  123. Links
    - https://zenn.dev/overflow_offers/articles/20220418-wha
    t-is-bff-architecture
    - https://melos.invertase.dev/
    - https://www.conventionalcommits.org/ja/v1.0.0/
    - スライド内のサンプルプログラム
    - GitHub API BFF+App:
    https://github.com/YumNumm/dart-frog-github-reposi
    tory-search

    View full-size slide