はじめに
こんにちは、mizukoです!
この度、エンジニアのためのインプット・アウトプットを加速させるサービス「PaPut(パプト)」のβ版をリリースしました!
サービスについてはぜひこちらをご覧ください!
本記事では、PaPutを支える技術について記載していきたいと思います!
技術選定の軸
私が技術選定を行う際に軸にしているのは以下です。
- モダンか?
- 情報は多いか?
- 市場価値は高いか?
- 人材確保は容易か?
いくら素晴らしい技術でも、導入や保守が大変だと無駄なコストがかかってしまいます。
他人にも受け入れやすく、できるだけモダンで今後に繋がるような技術を選定するように心がけています。
フロントエンド
フレームワーク
フロントエンドにはNext.jsを使っています。
開発当初、丁度App Routerが登場したので、そのまま採用しています。
また、検索エンジンにインデックスしてもらいたいので、基本的にはSSRで動くようにしています。
今だとRemixも選択肢に含まれてくるかなとは思いますが、当時はNext一択レベルだったと思います。
Nuxtに関しては、3への破壊的なバージョンアップ及び3自体のバグの多さを見てしまうと、採用する気にはなれませんでした。。ごめんねNuxt君。。
Tailwind CSS
UIにはTailwind CSSを利用しています。
柔軟にデザインを実装できるかつ、モバイルファーストなためレスポンシブにも対応しやすい事が採用した大きな理由です。
状態管理
状態管理には、グローバルでuseContextとRecoilを併用して使っています。
useContextはアプリケーション全体で利用され、頻繁に更新されない静的な情報を管理し、Recoilではモーダルの表示非表示のような、動的な状態を管理する様にしています。
非同期の状態管理は、TanStack Queryを利用しています。
アーキテクチャ
アーキテクチャにはfeaturesを採用しています。
採用した理由としては、
- DDDライクになる
- 機能毎にコードをグループ化することで、可読性、保守性が上がる
- コンポーネントの切り方が明確になる
という点です。
atomic designは切り分けが難しくなりがちで、結果的に一貫したコンポーネント設計ができなくなる事が多い印象です。
featuresなら機能毎にシンプルにコンポーネントを切っていけるので、気に入っています!
その他
- chart.js
- react-calendar-heatmap
- react-hook-form
- react-select
- react-toastify
- react-infinite-scroller
- zod
など
バックエンド
言語
バックエンドではGoを利用しています。
採用理由としては、
- 速度が速い
- 言語仕様がシンプルで良い
- クリーンアーキテクチャと相性が良い(ベストプラクティスではないけど)
の2点と、冒頭で記載した軸で選定しました。
GoはExceptionや継承が利用できないなど、これまでの言語仕様と大きく異なる部分があり最初は戸惑うことも多かったですが、クリーンアーキテクチャと組み合わせて開発していく中では非常にシンプルに開発する事ができて気に入っています。(ここは賛否があるところですよね)
フロントエンドと型の共有が行える、NodeのExpressやNest.jsも選択肢でしたが、上記の開発体験の良さや市場価値の高さ、速度面で強いGoを採用しました。
単純に個人開発のスピードだけ考えると、Nodeを採用した方が効率的かなと思います。
ORM
ORMはBunを採用しています。
採用理由としては、
- ライブラリ自体が軽量
- 他ORMに比べて高速
- 型安全性が高い
という点です。
開発当初はGormを採用していたのですが、せっかくならと比較し、明らかに高速かつ開発体験が良かったのでBunへ乗り換えました。
その際、Genも試してみたので、興味がある方は是非見てみてください!
アーキテクチャ
アーキテクチャはクリーンアーキテクチャを採用しています。
一人で開発を行うにしてはやりすぎ感はあるのですが、今後サービスを作り続ける上で基盤となる仕組みを構築したかったので、あえて採用しました。
基盤ができたので、今後はスピード感を上げて開発していけそうです...!
インフラ
ホスティングサービス
Vercel
フロントにはVercelを利用しています。
言わずもなが、Next.jsと相性が良く、特筆した設定をしなくても簡単にデプロイできます。
素敵
Render
バックエンドにはRenderを利用しています。
無料枠で十分な機能を使え、デプロイに関してもBluprintデプロイというymlファイルの定義で簡単に行えるので個人開発としては最良な選択肢になりうるかなと思います。
RenderでもDockerのruntimeで動作するようにしているので、Clud RunやECSへの切り替えも容易(なはず)という構成になっています。
DB
DBはPostgreSQLを採用しており、Renderで動かしています。
拡張機能が豊富なのと、複雑なクエリでのパフォーマンスがMySQLよりも優れているとされているからです。
将来、特に検索周りでクエリが複雑になる可能性が高いので、PostgreSQLを採用しました。
また、全文検索の拡張機能PGrongaも試してみたかったのも一つの要因です。(Renderで利用できなかったので、本番運用はしていません...)
おわりに
本記事では、PaPutを支える技術を紹介しました!
個人開発をする上で、どんな技術を使うべきか悩んでいる人の参考になれば幸いです🤗
今回リリースしたPaPut(パプト)も、是非手軽に利用してみて下さい!
サービスの詳細に関してもこちらに記載していますので、是非ご覧いただけると嬉しいです!