🥳

エンジニアのための技術記事プラットフォーム「Chietta」を個人開発で作りました

2023/11/08に公開
6

はじめに

休憩中や電車とかの隙間時間にZennやQiitaのトレンド記事をよく読んだりするのですが、色んなサイトの技術記事をまとめたサービスがあれば便利だなと思い、Chiettaというサービスを個人で開発したので紹介します!
※内容に間違いなどあれば教えていただけると幸いです

どんなサービス?

https://www.chietta.app

Zenn、Qiita、企業ブログなどをまとめて見たり検索できるサービスです

1/8追記

新しく機能を追加しました!
・プロフィール機能
・ブックマーク機能
・ユーザのフォロー機能
・フォロー中のユーザのアクティビティのタイムライン
・Qiita, Zennなどのアカウント連携機能
・記事のコメント機能

フォローいただけると幸いです!↓
https://chietta.app/yasse

開発したきっかけ

自分自身よく電車とかの隙間時間に技術ブログを読んだりしているのですが、その媒体が主にZenn, Qiita, Twitterのように複数あって、結局Zennのトレンドだけを見るみたいなことがよくありました。「1つサイトでまとめて見れたら便利なのになあ」 と思い、じゃあ作るかということで作りました!

制作期間

色々回り道をしてこのサービスを作ることになったのですが、それも含めると約1カ月程になります。

開発の縛り

開発をするうえで、守っていたルールのようなものを紹介します。

無料で運用できるサービス

個人開発で最も重要になってくるのは、運用コストだと思っています。サービスの良し悪しに関わらず、無料のサービスだと仕様が変わらない限りは10年後でも動き続けます。その間ユーザが増えたり何かのきっかけでバズることもあるかもしれませんが、有料のものを使っているとユーザが思うように伸びなかったときにサービスを終了することも選択しなくてはいけません。またお金をつぎ込んで得られる高性能よりも、無料の範囲内で試行錯誤して作りあげられた高性能とでは、その価値には雲泥の差があると思っています。なので今回は無料枠でいかに良いサービスを作れるかということに重点を置いてアーキテクチャを考えたりしました。

高速レスポンスの実現

前述の話と少しかぶりますが、無料枠のマシンではお金をつぎ込んだマシンには勝てません。しかしサービスの性能といった観点では開発者の力量次第では無料枠のマシンでも勝てると思っています。例えば、性能に頼りきった脳死のサービスよりも、キャッシュを駆使したり、通信を抑えたりして高速なレスポンスを提供しているサービスの方が「性能が良いサービス」であると言えます。現在は無料で使えるPaaSが多くあるので、それらをどのように組み合わせて高速レスポンスを実現するかが、開発者の腕の見せ所であると思っています。

爆速な開発スピード

個人開発ではとりあえず動くサービスを作ってすぐにリリースすることが大切だと思っています。作りたいものがあればとりあえず爆速で作る→ユーザからフィードバックをもらう→それをもとに開発をする→フィードバック→...というサイクルを回すことで、サービスの方向性も定めやすく本当に必要な機能が何なのかというのも見えてくると思っています。そのために冗長なアーキテクチャではなく、開発スピードを重視したアーキテクチャを考えました。

また今回、実際にベータ版をリリースしてご意見などをもらいながら改善や機能の追加などをしました。ご意見をくれた方ありがとうございます!

技術選定

Chiettaを支えている技術を紹介します。

アーキテクチャ

Next.js

以前AI Typingというものを作った時、フロントはTypeScript、バックエンドはGoでクリーンアーキテクチャを採用したのですが、クリーンアーキテクチャのコードがあまりにも冗長で、開発効率が悪すぎたので、今回はフロントもバックもTypeScriptで実装して縛りにもあるように開発スピードをあげることを重視しました。Next.jsは多少使い慣れていたので迷わず選びました。

ホスティング

Next.jsのホスティングをどこにしようかとても迷いました。候補として以下のものがありました。

Vercel

Next.jsを提供している会社のホスティングサービス。
・無料プランあり(商用利用不可)
・SSR, ISR対応
・エッジサーバーから静的コンテンツの配信
・自動CI/CD
今回はSSRなどの設定が不要なことや、自動でエッジサーバから配信してくれるという理由でこのVercelを採用しました。

Cloudflare Pages

無料でいろいろできるホスティングサービス。以下の記事で詳しく書かれています。
https://zenn.dev/rivine/articles/2023-06-23-deploy-hugo-to-cloudflare-pages
Next.jsだとSSR、ISRの設定が必要。
Next.jsを使っていなかったらこれを採用していたと思います。

GAE

Google Cloud上で簡単にWebアプリケーションが運用できるサービス。無料枠が用意されていて、枠を超えると従量課金で課金されていく。

これもSSR、ISRの設定が必要だが、他のホスティングサービスよりも自由にカスタマイズできる。

データベース

無料枠で使える範囲を基準に選定しました。(2023/11/05現在)

2024/04/14(追記)

PlanetScaleの無料枠が2024/04/8で終了したので、ChiettaではTiDBへ移行しました。

https://x.com/y4isse/status/1776816117908205966

PlanetScale

無料で使える範囲↓

ストレージ/月 行読み取り数/月 行書き込み数/月
5GB 10億 1千万

https://planetscale.com/docs/concepts/planetscale-plans

無料枠でストレージが5GBも使えて、自動バックアップやブランチ機能などが使えるすごいDBです。容量が一番大きいという理由で採用したのですが、無料枠なのにいろんな機能が使えて今後も使いたいと思いました。

Gitのようにブランチという概念があり、本番環境と開発環境を分けることができたり、安全にスキーマを変更することができます。一度誤ってすべてのデータを消してしまったのですが、自動バックアップのおかげで復元することができたのでとても感謝しています。

Vercel Storage

無料枠で使える範囲↓

計算時間 (1 か月あたり) ストレージ(合計) 書き込みデータ(月あたり) データ転送(月額)
60時間 256MB 256MB 256MB

PlanetScaleに比べてしまうとストレージ容量が少なかったので採用しませんでした。

https://vercel.com/docs/storage/vercel-postgres/usage-and-pricing

Render

無料で使える範囲↓

ストレージ 有効期限 RAM CPU
1GB 90日 256MB 0.1CPU

90日の有効期限があり無料だとそれ以降は使えないので今回は選択肢からはずれました。

https://render.com/docs/free

その他の技術

・React
・NextAuth
・Tailwind css
・Prisma
・Zod
・Jotai
・react-hook-form
・node-cache

これらの技術の選定理由はドキュメントがしっかりしているかメンテナンスがされているかという点で決めています。自分自身、個人開発かつ開発経験が浅いということもあり、参考にできるものが多い方が嬉しかったり、Next.jsの進化がすごいので、それに対応していってくれるかどうかというのもありました。

こだわったところ

僕なりにこだわった点をいくつか紹介していきます。

高速レスポンス

ISR

Chiettaでは基本的にはISRを採用していて、静的コンテンツとしてキャッシュしてエッジサーバから配信されるようになっています。SSRを使用してしまうと、リクエスト毎にサーバにアクセスして、データベースの情報を取ってくるのですが、これだとPlanetScaleの無料枠の制限に簡単に到達してしまうのと、レスポンスが遅くなってしまうというのがあります。しかしSSGのようにビルド時にコンテンツを生成してしまうと、Chiettaのような内容が更新され続けるようなサービスでは使えないので、それを解消するためにISRという方式を採用しています。

ISRとは指定した時間が経ってからアクセスされるとバックグラウンドで最新の情報にビルドされるというやり方です。これはNext.js(App router)ではfetchのオプションのrevalidateで設定できます。

エッジサーバ

VercelではISRしたコンテンツをエッジサーバから自動で配信してくれます。そのため、ユーザは日本にあるエッジサーバからデータを取得し、アメリカにあるVercelのサーバへのアクセスが不要になるので、高速レスポンスを実現できます。実際にアクセスしてもらうと分かると思うのですが、平均レスポンスタイムは100ms以下と比較的早いレスポンスタイムとなっていると思います。

その他

他にも以下のようにして、高速化を図っています。
・OGP画像は取得後すべてサーバー側でキャッシュして通信を減らす
・DBに適切なインデックスを貼ってDBアクセスの高速化

処理速度の記録

高速レスポンスを実現するために最初の段階で、各処理の実行時間をコンソールに出力するようにしていて、開発を進める中でその時間を見てボトルネックになっているところが数字でわかるような仕組み作りをしていました。施策による処理時間の変化を比較するために変更を加える前後でGitHubのissueにログを残しておき、その効果を記録しておくようにすることで、数字として変化を見れるようにしておきました。

無限スクロール

これは完全に個人的な嗜好なのですが、無限に記事が流れてきてほしいと思っていたので無限スクロールで実装しました。実装にあたって以下の記事を参考させていただきました。

https://zenn.dev/catnose99/articles/0f0bb01ee6a940

UX向上のためスケルトンを表示するようにしました。これによって取得したデータを表示する時のレイアウトの変化を最小限に抑えています。

以下のサイトでスケルトンを簡単に作ることができます。
https://skeletonreact.com/

大変だったところ

無料枠の回数制限

無料枠で運用しているということもあり、PlanetScaleでは読み取りや書き込みの回数に制限があります。何も考えずに開発すると簡単に制限に達してしまうので、アクセス回数を抑えた実装をする必要があります。対応策として、サーバ側でインメモリのキャッシュを使用することで、DBへのリクエストの回数をこちらで制御するということをしています。例えばDBから取得した結果を1時間は新しいものと見なして使い回すことでDBへのアクセスを減らしています。これによって1時間はDBへのアクセスがないので、1日でも最大24回のアクセスに抑えることができます。Chiettaではサーバの内部でnode-cacheを使用してこれを実現しています。

またクライアント側でもfetchオプションにキャッシュを設定して、サーバへのアクセスを減らすというようなこともしています。

今後の展望

QiitaやZennだけでなく多くの企業ブログや個人ブログも取り入れて、様々な技術記事が集まるプラットフォームにしたいと考えています!また、データ量が多くなり検索がすごく遅かったりと改善点が色々あるので改善していきたいです。

フィードバック・問い合わせ

以下のフォーム、またはこちらのXのDMにお問い合わせやご要望などなんでも送ってください!
https://forms.gle/5iWkCsRrnoZN9XFs8

さいごに

拙い記事ですが最後まで読んでいただきありがとうございます!まだまだ改善点が多いサービスですが、どんどん改善していって、もっと良いサービスとしていけるように頑張っていきたいです!

Discussion

Kazu1Kazu1

UIUXが良すぎて良すぎて。。。。。
勉強になります!

やせやせ

ありがとうございます!
UI/UXはこだわったのでとても嬉しいです!

砂漠砂漠

ななめ読みなんですが、トレンドの評価基準はそのプラットフォームの高評価数ですかね?
そうなると、プラットフォームごとの差異が出てきて、記事の品質を定量的に評価できないのでは?
(偉そうに上から目線ですみません…)

やせやせ

コメントありがとうございます!その件は自分もすごく悩んでいたのですが、なかなかいい案が思いつかず現在は定量的ではありませんが高評価数で評価させて頂いてます、、、とても貴重なご指摘ありがとうございます!

ドシロウトドシロウト

非エンジニアですけど、試してみました、便利そう。ありがとうございます。

新着の記事>フォロー中のカテゴリをRSSで出力できるといいなぁって思いました。

やせやせ

貴重なご意見ありがとうございます!
お時間かかるかもしれませんが対応させていただきます!