最近仕事で、ソフトウェアアーキテクチャとか、逆コンウェイの法則とか、なんか色々考えてる流れで、個人もしくは0からなにの制約も無くサービスを作るとしたらどうするかなーって考えてみた。なお考えただけなので、それ半年後後悔するよって結果かもしれない
これのサービス版みたいなイメージですね。
こんな構成で書いてみます。
登場人物
- MySQL or PostgreSQL
- https://planetscale.com/ でもいいし、https://supabase.com/ を使ってもいいかもですね。
- Backend
- BFF感は強いけど、FrontendとBackendの間ではなくDBとFrontendの間なのでBackend
- しかしマイクロサービスではないので、FrontendのためのBackendでしかない
- Frontend
- クラウドサービス
- Vercel
- PlanetScale
別で考えること
- WEBだけじゃなくてAPIつくるとしたら?
- WEBだけじゃなくてバッチ処理とかFrontned以外をトリガーとする処理は?
思考を放棄
- SPA/SSR/SSG/ISR/SWR
とりあえず図
flowchart LR
UA--HTTPS-->Frontend
UA-->React.js-->GraphQL
subgraph Vercel
subgraph Frontend
Next.js
end
Next.js-->GraphQL
subgraph Backend
direction TB
GraphQL["Next.js API Route Endpoint"]-->Apollo
Apollo-->Resolver
Resolver--Query-->PrismaORM
Resolver--Command-->Domain[[DomainLayer]]-->PrismaORM
end
end
subgraph PlanetScale
PrismaORM-->MySQL
MySQL
end
マイクロサービス的に様々な用途に使われるAPIだとしたら、GraphQLのQueryがほぼそのままMySQLのクエリをWrapしてるみたいな開発は避けたほうが腐敗防止的にもいいと思うんだけど、まぁFrontendのためにしか使わないGraphQL Endpointという前提を置くとこれでいいんじゃないかな。
けどCommandはDB更新するだけならまだいいけど、トランザクション処理したり、他のAPI巻き込んだり、なんかまぁ色々複雑になると思うので、そこはDomain Layerにお仕事させるなど
Schedule Jobどうすうる?
一昔前のCloud Runとか、Serverless系(FunctionsやLambdaなど)はHTTPトリガーしかなかった(厳密にはpubsub eventとかあるけど、一旦置いとく)時代とおなじかな。HTTPで書いて叩こうね。ただ同じRuntimeに乗る以上リソースを専有されたくないので、Serverlessの良さを使ってスケールさせたり、HTTP Timeoutを拡張する考えじゃなくて、冪等に処理できるようにしてやっていくとかそういう戦略は必要かな。
まとめ
一昔前ならRailsとかLaravelとかまぁそういうフルスタックフレームワークがカバーしていた事を、全てNode.js(TypeScript)で書くほうが、Rails + jsで書くよりフロントが書きやすくなるし、FrontendとBackendを書く際に言語をスイッチするコストも掛からないってのは、一つの形としてありだよね。
個人的にはGoの硬さが好きなので、好きを見て自分の中での2022年版のGoかくなら〜を書いてみたい。
この2021も妄想で書いただけなので、まぁそれはそれ。
とりあえず、深く考えてないで書いてるので、もう少し調べたり色々見聞きしたりしたら確実にかわるとおもう。でもとりあえず昔はJavascriptがこんなに活躍する世界はおもってなかったよね。
Google MapがAjaxだ!って言って地図をぐりぐり動かせるようになったあの時は感動したけど!
追記
書いてみた