【微経験】独学で動画特化の料理レシピ保存サービスを開発するまで【Rails / Next.js / AWS / Docker / GitHub Actions】

# はじめに
こんにちは！ちゃんよ（[@y4tk8](https://x.com/y4tk8)）と申します。

今回、Web系開発企業への転職を目指して独学でWebサービスを開発しました。ポートフォリオが主目的ですが、実サービスを意識して微経験者なりに本気で取り組んだのでインプット 〜 開発 〜 リリースまでの経緯や苦労した点、感じたことなどを書いてみます。

何か役立つことがあれば幸いです。

# 自己紹介
大学卒業後、新卒で注文住宅メーカーに営業職として入社しました。3年間従事したのち、海外へのプログラミング留学を経て都内の受託開発企業へ入社。PHPでバックエンド開発をしていましたが諸事情で2ヶ月で退職しました。その後は広義のIT業界にはいましたが、エンジニアリングからは完全に離れていました。

改めてエンジニアへ転職するため、ポートフォリオ開発に至りました。

# 目次
- [1. ポートフォリオ紹介](#1-ポートフォリオ紹介)
- [2. 機能一覧](#2-機能一覧)
- [3. 使用技術一覧](#3-使用技術一覧)
- [4. 開発で苦労したポイント](#4-開発で苦労したポイント)
- [5. インプットに使った教材](#5-インプットに使った教材)
- [6. 振り返りと感じたこと](#6-振り返りと感じたこと)
- [7. 最後に](#7-最後に)

# 1. ポートフォリオ紹介
![top-image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862635/71822693-0528-48d0-86de-19b76901b2b8.png)

サービス名：**Yum Keeper**
サービスURL：https://www.yumkeeper.net

※ゲストログイン機能を用意しているので是非お気軽にお試しください

### サービス概要
動画特化の料理レシピ保存サービスです。YouTube動画と共に具材や調味料、分量などをシンプルに保存・管理できます。サービス名の由来は英語のYummy（美味しい）の短縮系である**Yum** + **Keeper**（貯蔵庫）の組み合わせ。そのままですね。「.com」のドメインは売り切れてました。。

### GitHub
- [バックエンドリポジトリ](https://github.com/y4tk8/yumkeeper_backend)
- [フロントエンドリポジトリ](https://github.com/y4tk8/yumkeeper_frontend)
- [ドキュメントリポジトリ](https://github.com/y4tk8/yumkeeper_docs)

### 開発動機
私は普段から動画（特にYouTube）で料理レシピを探します。ただ、作り方を覚えても料理のたびに材料や分量をYouTube再生して確認するのが非常に面倒でした。そこで、YouTube動画と一緒にシンプルにレシピ管理できるサービスがほしいと思い、開発しました。

### 開発スケジュール
- インプット：4ヶ月半
- ポートフォリオ開発：5ヶ月（内訳は以下）
  - **企画**：10日
    - 詳細：アイデア着想、競合調査、要件定義
    - 成果物：サービス概要書、機能一覧表

  - **設計**：2週間
    - 詳細：データベース設計、インフラ設計、必要ページ洗い出し
    - 成果物：ER図、テーブル定義書、インフラ構成図　※画面遷移図は手書き

  - **開発**：4ヶ月
    - 環境構築：2週間
    - バックエンド：1ヶ月半
    - フロントエンド：2ヶ月

  - **デプロイ**：10日
    - 詳細：インフラ構築、CD導入、リリース

![er_diagram.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862635/b03f6af4-acb2-4f65-8550-bf22bc86eac6.png)

![infra_prod.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862635/ff168d75-c978-45ed-acd7-60498627dd66.png)


# 2. 機能一覧
### 1. ユーザーアカウント関連
- サインアップ
- サインイン
- サインアウト
- アカウント有効化
- パスワードリセット
- パスワード変更
- アカウント認証メール再送
- 退会
- ゲストサインイン

### 2. レシピ関連
- レシピ追加
- レシピ詳細
- レシピ編集
- レシピ更新
- レシピ削除
- レシピ一覧
- レシピ並び替え
  - 最新の更新順、追加日（新しい順）、追加日（古い順）
- YouTube動画取得（_YouTube Data API_）
- YouTube動画埋め込み

### 3. その他
- ページネーション（_Pagy_）
- 認可
  - 未認証ユーザーのアクセス制御
  - 他ユーザー保有レシピへのアクセス制御
- バリデーション & エラーメッセージ表示
  - 空文字、長さ、フォーマットなど
  - YouTube Data APIから動画取得時、レスポンスに応じたバリデーション
- フラッシュ
  - ユーザー操作に応じて成功 / 失敗の各種メッセージ
- モーダル
- 404エラー
- 500エラー

# 3. 使用技術一覧
- バックエンド
  - 言語: Ruby 3.3.7 / Ruby on Rails 7.2.2.1
  - テスト: RSpec
  - 静的解析ツール: Rubocop
- フロントエンド
  - 言語: TypeScript 5.8.2 / React 19.0.0 / Next.js 15.1.6
  - テスト: Vitest / React Testing Library / MSW / Cypress
  - デザイン: Tailwind CSS / Shadcn UI
  - 静的解析・整形ツール: ESLint / Prettier
- インフラ: AWS(Route53 / ALB / ECS on Fargate / ECR / RDS / ACM etc) / Nginx / Vercel
- CI / CD: GitHub Actions
- 環境構築: Docker / Docker Compose / Dev Containers
- 外部API: YouTube Data API

# 4. 開発で苦労したポイント
1. **レシピの編集ページ**
編集ページは「DBに追加済みのレシピを初回マウントしてから、新たに登録する材料 & 調味料を追加 ＋ 不要なデータは削除した上でそれらを全て**PATCH**でRailsに送る」という構成です。つまり、PATCHリクエストといっても中身は「既存データの更新 or 削除」「新しいデータの登録」が混在していたので、各データのID管理とデータベースとの整合性を取るために非常に苦労しました。

2. **フロントエンドのE2Eテスト**
CypressでシナリオベースのE2Eテストを導入しました。認証系のテストは書けましたが、メインのレシピ機能のE2Eが「ユーザーのトークン認証 ＋ 非同期処理 ＋ useEffectでの副作用管理」という色々な挙動が混合して、Next.js特有の**タイミングのズレ**が頻発しました。加えて、それをCypressという独自環境で再現するのでとても難しく、どうがんばっても書けませんでした。

3. **本番環境でのNginxとRailsの疎通**
環境構築時点でNigixとRailsをコンテナ化しました。環境差異を吸収するのがDockerの大きなメリットなので、デプロイはスムーズに進むだろうと思いましたがそんなことはなく。本番ではPumaサーバーをNginxより先に起動する必要がありますが、その対応が大変でした。ALBからのヘルスチェックが失敗したり、本番で成功したと思ったら今度は開発環境でエラーが出たり。最終的にComposeファイルもDevとProdで分離しました。

※工夫ポイントはGitHubリポジトリのREADMEに書いています

# 5. インプットに使った教材
サービス開発前にインプットに用いた教材を以下にまとめます。
これから学習する方の参考にもなれば幸いです。

### 書籍（敬称略）
- [Railsチュートリアル](https://railstutorial.jp/)
- [プロを目指す人のためのRuby入門［改訂2版⁠］⁠- 伊藤淳一 著](https://gihyo.jp/book/2021/978-4-297-12437-3)
- [改訂3版 JavaScript本格入門 - 山田祥寛 著](https://gihyo.jp/book/2023/978-4-297-13288-0)
- [これからはじめるReact実践入門  - 山田祥寛 著](https://www.sbcr.jp/product/4815619480/)
- [仕組みと使い方がわかる Docker＆Kubernetesのきほんのきほん - 小笠原種高 著](https://book.mynavi.jp/ec/products/detail/id=120304)
- [ネットワークはなぜつながるのか　第２版 - 戸根　勤 著](https://bookplus.nikkei.com/atcl/catalog/07/P83110/)
- [おうちで学べるデータベースのきほん 第2版 - ミック 著 木村 明治 著](https://www.shoeisha.co.jp/book/detail/9784798185330)
- [達人に学ぶDB設計徹底指南書 第2版 - ミック 著](https://www.shoeisha.co.jp/book/detail/9784798186627)
- [Webを支える技術 - 山本陽平 著](https://gihyo.jp/book/2010/978-4-7741-4204-3)
- [プリンシプル オブ プログラミング 3年目までに身につけたい 一生役立つ101の原理原則 - 	上田勲 著](https://www.shuwasystem.co.jp/book/9784798046143.html)
- [21世紀最強の職業　Web系エンジニアになろう - 勝又健太 著](https://www.j-n.co.jp/books/978-4-408-33933-7/)

### Udemy
- [3分動画でしっかり学ぶGit/GitHub入門〜プロへの道！業務で使えるバージョン管理ブートキャンプ](https://www.udemy.com/course/gitgithub-3min/?couponCode=ST16MT230625JA)
- [React(v18)完全入門ガイド｜Hooks、Next14、Redux、TypeScript](https://www.udemy.com/course/react-complete-guide/?couponCode=ST16MT230625JA)
- [理解して使う！Docker入門＋応用：初心者から実務で使えるスキルが身に付ける](https://www.udemy.com/course/ok-docker/?couponCode=ST16MT230625JA)
- [AWS：ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得](https://www.udemy.com/course/aws-and-infra/?couponCode=ST16MT230625JA)
- [【完全版】AWS ECSコンテナアプリケーション開発（入門から実践まで）](https://www.udemy.com/course/ok-aws-ecs/?couponCode=ST16MT230625JA)
- [プログラミング中級者になりたい人のためのクリーンコード入門](https://www.udemy.com/course/clean-code-tutorial/?couponCode=ST16MT230625JA)

### Techpit
- [【Rails×React】UberEats風アプリを作りながら、SPA開発を学ぼう](https://www.techpit.jp/courses/138)
- [Railsアプリケーションのパフォーマンス改善をしながらN+1問題を解決するスキルを身に付けよう！](https://www.techpit.jp/courses/79)

### その他
- [Progate](https://prog-8.com/)
- [Next.js 公式チュートリアル](https://nextjs.org/learn)
- [IT用語辞典 e-Words](https://e-words.jp/)
- [TECH WORLD（YouTube）](https://www.youtube.com/@TECHWORLD111)
- 各技術の公式ドキュメント

# 6. 振り返りと感じたこと
### とにかく理解する
最初はわからないことだらけですが、理解の「点」が増えると次第に「〇〇ということは△△の可能性があるから□□をやってみよう」と自分で仮説を立てられるようになります。後から楽になるので、序盤に理解から逃げないことが非常に重要だと思いました。

### 期限を決める
期限 ＝ 総工数 ＋ バッファ。開発中、節目ごとに期限を設けてきましたが「これならいけるだろう」と余裕を持って〆切を決めても予期せぬバグや色々なイレギュラーは付きもので、何事もなくスムーズに完遂したことは一度もありませんでした。ただ、期限を守る前提があると、本来不要だったタスクを消したり優先順位や時間配分を組み替える知恵が生まれます。リスケは最終手段。

### ChatGPTの使い方を工夫する
今のChatGPTは非常に高精度なので、公式ドキュメントを読んだ上で適切に質問すれば高確率で解決しました。回答精度が落ちてきた場合はメモリ全消去 & 新チャットで質問し直せば正しい答えが返ってくることもしばしば。これで問題の8割は解決しました。残り2割はググる（日本語も英語も）＋ 自分で処理を追う。それでも解決しない場合はStack Overflow または teratailで質問してました。余談ですが、Stack Overflowは日本語で質問書いてDeepLで全英訳して投稿すると海外エンジニアもがんがんコメントくれるのでおすすめです（たまにスパム扱いされるのでカジュアルに英文直すと投稿できます）。

# 7. 最後に
2024年8月にProgateを始めて、サービス開発からリリースまで完遂できたことにひとまずホッとしています。私は年齢的に後発なので、微経験からエンジニアに戻ることに非常に葛藤しました。営業なら元の人柄やコミュ力で短期間で大きな成果を出すプレイヤーがちらほらいますが、技術の世界ではあり得ないと思いました。「通用するのか」「きちんと価値を出せるのか」を本当に悩みましたが、エンジニアとして再チャレンジすることを選びました。

私は事業やプロダクトをスケールさせる戦略などの上流に興味があるので、自分なりに価値を出せるようがんばります！

以上、長文ですが読んでいただきありがとうございました。