前提
- Laravel11を使用
- ウェブとアプリで類似の機能を持ったサービス展開
- GitHub ActionsなどのCI/CDの使用
- ウェブとスマホアプリで使用するデータベースは同じ
- 当然アプリとサーバのリポジトリは分かれるが、アプリ用サーバとウェブ用サーバの扱いに悩む
サーバを分けるor分けない
原則、開発の段階で分ける。理由は下記のとおり
- ウェブ側の実装を修正デプロイすると、アプリまでメンテナンスになる等、メンテナンスの範囲が分けられなくなる
- エラーや障害のトレース時にアプリ側からのリクエストなのか、ウェブ側からのリクエストなのか判別する必要が出たりして、追いづらくなる
- 「スモールスタートだから分けなくていいや」と舐めていると、肥大化したあとの分離がめちゃくちゃだるいことになる
リポジトリを分けるor分けない
ウェブ用サーバとアプリ用サーバのリポジトリを分けるべきか?という悩みが浮上する
本来なら分ける方が望ましい。しかし、作業人数や規模、実装内容によって判断が分かれる
リポジトリを2つに分ける(ウェブ用API + アプリ用API)
- CI/CD、ルーティング、名前空間などをリポジトリ毎に設定できる
- 「ウェブ用サーバに入れた修正がアプリ用サーバに入っていない」等の事象が発生し、同じような実装なのに差が出てしまうことも考えられる
リポジトリを3つに分ける(ウェブ用API + アプリ用API + 共通処理)
- 開発者が複数人の場合、これがもっとも望ましいかもしれない
- 多くのModels、Requests、Resources、Repositoriesなどを共通として扱い、Controllersを個別で管理することになる
- 共通部品の変更内容をしっかり管理・共有・レビューする仕組みは必須である。急に自分に起因しない不具合やエラーが発生するのは、多くのエンジニアにとって極めて不快感を与える
鋼の意思でリポジトリを分けない
- 人手不足な企業、中小企業で働く悲しきエンジニアはアプリ、バックエンド、フロントエンドを1人で全部作ることになる。決して良い方法ではないが、ひとりで管理するものを増やすコストに耐えられない敗北者には必要である
- ブランチはdevelop、deploy-web、deploy-mobileに分ける。developで開発したらdeploy-webとdeploy-mobileにマージする運用とし、各リポジトリごとにCI/CDを設定しておく
- WebとMobileの名前空間を設定してクラスを分ける(例:App\Http\Web\Controllers、App\Http\Mobile\Controllers)
- 環境変数にweb用サーバかmobile用サーバを設定できるようにする
- CI/CDで不要なファイルを削除するようにする。アプリサーバーの場合はapp\Http\Webを消し、ウェブサーバーの場合はapp\Http\Mobileを消すといった具合である。後述のルーティングファイルやフロントエンドのファイルなども削除対象になる
- routesには、web.php、api.php、mobile.phpを作成し、bootstrap/app.phpを下記のようにする
$apiRoute = env('API_ROUTE', 'web');
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: $apiRoute === "web" ? __DIR__.'/../routes/web.php' : null,
api: $apiRoute === "mobile" ? __DIR__.'/../routes/mobile.php' : ($apiRoute === "web" ? __DIR__.'/../routes/api.php' : null),
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
※環境変数を切り替える時php artisan optimize
の実行が必要である
※特定のコマンド(コントローラーの作成など)の挙動に困る
おわりに
普通であればサーバとリポジトリは細かく分けるだけだが、今回はブランチ単位で分ける場合の運用が必要だと感じて実践した
結果的にリポジトリを分けなくてもうまくいったが、内部がこんなんになってるとは思わないので、後任者に配慮したreadme.mdを書く必要がある