【個人開発】未経験から独学でキャットフード検索サービスを作ってみた　【Ruby on Rails × Next.js】

# はじめに
はじめまして。<br>
未経験から独学でwebエンジニアを目指しているくまと申します。<br>

この度、全ての猫を飼われているおうちの方に使って欲しい **キャットフード検索サービス「ねこまんま」** を作成しました。<br>

https://www.nekomanmafood.com/

GitHubでリポジトリも公開しています。

https://github.com/kuma0319/catfood-app


サービス概要や使用技術等を紹介させていただきます。


# サービス概要
#### サービス作成の背景
現在私は3匹の猫を飼っています。<br>
猫には毎日ドライキャットフードをあげているのですが、そのキャットフードについて悩むことがとにかく多いです。<br>
というのも、キャットフードはとにかく種類が多い上に、何を基準に選べばいいのかが分かりにくいものです。<br>
だからといって、ネットで情報を集めようと思っても、大体どこのサイトでも似たようなフードばかりが紹介されています。どうやらブランディング力のあるフードばかり紹介されているようです。<br>

そのため結局、 **自分が正しいと思う情報を取捨選択しキャットフードを選ぶ** 必要があります。<br>
しかし、キャットフードはとにかく種類が多く、国内外合わせると膨大でとても簡単に比較は出来ません。<br>
私はよくペットショップなどでキャットフードを比べてみるのですが、数種類のキャットフードについて原材料や成分を見比べてみるだけでもかなり苦労していました。。。

キャットフードをまとめているようなサイトはいくつもありますし、楽天市場やamazonといったショッピングモールにも多数のキャットフードはあります。<br>
しかしキャットフード検索に特化している訳ではないため、**絞り込むための要素が限定的** であるという問題があります。<br>
また、キャットフードのを判断する上で必要な **コミュニティも不足** しています。<br>
これだと、ある程度どういったキャットフードを選ぶべきかが分かっても、最適な選択が難しい可能性があります。<br>

それであれば自分で作ってしまおうと作成したのが、コミュニティ機能も付いたキャットフード検索サービスである「ねこまんま」です。

#### ターゲット、解決したい課題
このサービスのターゲットはもちろん猫を飼われている全ての方々です。<br>
各ご家庭によってキャットフードの選定基準は、原料や成分にこだわりたい人、特定のメーカーがお気に入りな人、リーズナブルさを求める人、全てを加味したい人、様々だと思います。<br>
「ねこまんま」は、こういった色んなニーズを解決できると考えています。

#### 機能一覧
##### 1. キャットフード閲覧&検索機能
メイン機能になります。国内外700種以上のキャットフードが閲覧出来ます。<br>
様々な情報をデータベース化しているため、 **成分量で絞り込んだり除外したい原材料をキーワードとして指定する** といったことが可能です。<br>
この例だと、タンパク質30%以上、糖質15%以下、原材料に"穀類"というキーワードを含まないキャットフードのみを抽出しています。

![キャットフード検索.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3299695/f445a57c-9581-0112-b137-cf30ac28d873.gif)


##### 2. ウォッチリスト機能
キャットフードを検索し気になったものがあれば、ウォッチリストに追加することが出来ます。<br>
ウォッチリストでは、各情報をテーブル形式で一括比較することが可能なので、同じようなキャットフードの微妙な違いも一目で分かるようになります。

![ウォッチリスト.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3299695/059510d5-0fcb-4124-b8fc-e047c69fbef3.gif)


##### 3. お気に入り、レビュー機能
個人的にリストとして残しておきたいようなお気に入りキャットフードは、お気に入り登録することが可能です。<br>
また、ユーザー目線でしか評価できないような、食いつきの良さ、フードの香り、といった主観的な項目についてはレビュー機能で評価が可能です。

![お気に入り、レビュー.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3299695/23aed91f-41b4-477d-71b3-045eaff9dc38.gif)


##### 4. 相談所機能
キャットフードについて、気になることや困ったことはユーザー同士で相談し合える相談所機能を設けています。

![相談所.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3299695/c3bafab8-4b4a-da2a-e41d-59736956e93c.gif)


##### 5. 認証関係、マイページ
認証はトークンベースの認証を設けています。また、メールアドレス認証機能やパスワードリセット機能、ゲストログイン機能を実装しています。<br>
マイページではプロフィールの編集や、お気に入りリストの確認が可能です。

![マイページ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3299695/bc330111-a1f7-a1d3-db01-3cb812e59a5e.png)


##### 6. レスポンシブ対応
レスポンシブデザインを実装しているため、モバイルユーザーの方でもデスクトップユーザーの方でも同じように利用できます。

![レスポンシブ_リサイズ.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3299695/5c535e4f-73f4-0fa5-254f-21002c92b3a0.gif)


# こだわった点
* 楽天APIを利用してキャットフードの画像や周辺項目を用意することで、視覚的にも分かりやすいサイトとなりました。<br>
* キャットフード検索のロジックを工夫し、柔軟かつ効率的に絞り込み検索が出来るようにしました。<br>
* SSG/SSR/CSRを要所要所で使い分け、高速なページ遷移と良質なユーザー体験を心がけました。<br>

# 使用技術、選定理由
ここからは使用技術及び、技術選定の理由を列挙します。<br>

#### 技術選定で意識したこと

* 開発するサービスに必要、相性がいいこと
  * とりあえずよく使用されていたり、モダンであるからという理由だけではなく、なぜこのサービスに必要なのかという部分が無いと、今後の技術選定において価値が無いと考えました。
* ある程度モダンでシェアが高いこと
  * モダンな技術である方が現場で即戦力となれる可能性が高まることや、最新の技術をキャッチアップしていく能力を身に着けることが出来ると考えました。
  * また、ある程度シェアのある技術であることは、上記と同様に現場で使用されている可能性が高いことや、情報もそれだけ多いため、エラー対応のハードルが比較的低くなることが考えられます。
* 学習コスト
  * 未経験からwebエンジニアへ転向することを考えると、学習すべき内容は非常い多いです。
  * そのため、学習コストとそれが実際にサービスにどの程度必要かを考慮しました。

#### バックエンド

* Ruby：3.2.2
* Ruby on Rails(APIモード)：7.0.4.3
* RSpec
* Rubocop
* PostgreSQL：15.3
* 主要gem
  * jbuilder (JSONデータ編集用)
  * rakuten_web_service (楽天API用)
  * devise, devise_token_auth (認証用)
  * kaminari (ページネーション用)
  * shoulda-matchers (RSpec用)

:::note info
技術選定理由

【Ruby、Ruby on Rails】<br>
Ruby on Railsは、最も早くサービスを立ち上げるのに向いたフレームワークであり、今回のような個人開発では最適解と思われます。スタートアップでもよく使用される技術であることや、Rubyは日本発の言語であるためドキュメントが豊富であり十分な学習教材(Railsチュートリアルなど)が揃っていることから選定しました。<br>

【RSpec】<br>
Railsチュートリアルでは、テストフレームワークとしてminitestが採用されていましたが、シェアはRSpecが高いことや、minitestが学習済みの場合はRSpecの学習コストは低いということがありましたので、RSpecを採用しました。<br>

【PostgreSQL】<br>
データベースは機能的にもシェア的にもさほど大差の無い、MySQLとPostgreSQLで悩みましたが、デプロイ先のRender.comの標準データベースであるPostgreSQLを取りました。

:::

#### フロントエンド

* TypeScript：5.0
* Next.js (React)：13
* Tailwind CSS、Preline UI
* ESLint
* Prettier
* 主要package
  * axios (HTTPリクエスト用)
  * nookies (cookies用)
  * react-hook-form (送信フォーム用)
  * moment (日時フォーマット用)

:::note info
技術選定理由

【TypeScript】<br>
初学者でTypeScriptはハードルが高いかとも思いましたが、以下の理由でJavaSctiptでなくTypeScriptを選びました。<br>
　・静的型付けであるため、即座にエラー箇所が分かる。<br>
　・使用しているIDE (VS code) の補完機能との相性が抜群に良く、開発効率が向上する。<br>
　・Next.js及びReactのコンポーネントにおけるデータの取り扱いと相性が良い。<br>
　・JavaScriptのスーパーセットであり、全く新しい言語という訳ではないためTypeScriptそのものの学習コストはさほど高くない。<br>

実際にTypeScriptは導入して大正解だったと感じています。初学者だからこそ、どこでどの値が渡ってきているか、どのメソッドが使えるかといったことを把握しながら進められるTypeScriptは重要だと感じました。

【Next.js(React)】<br>
まず私のサービスにおいては、数百種のキャットフードのページを用意する必要があるため、SSGによってあらかじめページをビルドしておくことが必須要件だと考えました。<br>
比較対象としては、Nuxt.js(Vue.js)となるのですが以下の要件でNext.js(React)を利用することに決めました。<br>
　・技術トレンドをサーチしたところ、直近ではNext.js(React)の方が大分注目されている。<br>
　・Next.jsの方がページ単位のSSG/SSR切り替え(Nuxt.jsも対応しているみたいですが)やISRなど、Nuxt.jsの上をいっていると感じた。<br>
　・Next.jsはVercelによって開発されており、Vercelでのデプロイが非常に簡単で強力。<br>
　・TypeScriptも簡単に導入が可能。<br>
　・ゼロコンフィグにより、特に設定不要で多くの機能を利用できることが初学者にとって利用ハードルを下げてくれている。<br>

今回は適用出来ていませんが、App Routerシステムも導入されたことで更にNext.jsのサーバーサイドレンダリングが強力になったみたいですね。

:::

#### インフラ

* バックエンド：Render.com（AvtiveStorageにはS3使用）
* フロントエンド：Vercel

:::note info
技術選定理由


未経験からポートフォリオを作成した方々でAWSを採用されている人も多かったですが、学習コストが高すぎることや、個人開発でリリースするレベル感のサービスのスケーラビリティを考慮すると、まずは学習コストをあまりかけずに十分運用が可能だと思われるRender.comやVercelなどのPaaSとしました。<br>
フロント側がVercelであることは上述の通りで、バックエンド側がRender.comであるのは、Herokuの無料プランが廃止されたことに加え、同程度の機能であればRender.comの方が比較的安く運用出来るという情報から、Render.comを選択しました。

:::



#### 開発環境

* PC：HPのノートPC(メモリ8GB 泣)
* OS：WindowsにWSL2を使用してLinux環境を構築
* IDE：VSCode
* コンテナ：Docke/docker-compose

とりあえず手持ちのノートPCで開発を進め、なんだかんだで最後まで頑張ってもらいましたが、メモリ8GBは全然スペック足りてませんでした。。。

# ER図

![230819_ねこまんまER図.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3299695/303514a7-0ac3-3fa3-d365-989105499aab.png)

# インフラ構成図

![230819_nekomanma_infrastructure.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3299695/526f4b73-dd2b-11ed-0638-d615a9ccf955.png)

# 今後の展望
インフラ関連が知識的にも技術的にも不足しているため、CI/CDパイプライン構築、AWSなどのIaaSに挑戦、IaC化など、サービスを運用しながら学習、アップデートしていきたいと考えています。<br>
また、フロントエンド側のテスティングフレームワークとしてJestを導入していますが、学習コストが高く感じ現段階では触れていません。少しずつ学習を進めていきたいと思います。<br>

# おわりに
最後まで読んで下さりありがとうございました。<br>
未経験から完全独学で何とか作りたいサービスを作り切ることが出来ました。<br>
ポートフォリオを作成する中で、やはり作りたいものを自分の手で作ることの出来るwebエンジニアという仕事を必ずしたいという意欲が増しました。<br>
学習やポートフォリオ作成では、あまり辛いという感覚は無く楽しくやりがいを感じることが多かったです。<br>
ネット記事でもあまり見つけることが出来なかったような問題にも直面したため、Qiitaで発信していこうと思います。