Skip to content

Ma11111ma/section8

Repository files navigation

Nuxt.js と Python(FastAPI)を用いた AI レシピ提案アプリの開発プロジェクト

1. 学習目的

本プロジェクトは、以下の 3 つのスキル習得・向上を目的としています。

  1. 新しい技術への挑戦: これまで使用経験のない Nuxt.js と Python(FastAPI)に触れ、モダンな Web 開発の知見を広げる。
  2. チーム開発フローの向上: Git/GitHub を利用したブランチ戦略、プルリクエストベースのコードレビュー、コンフリクト解消など、チーム開発における一連のプロセスを実践し、円滑な共同作業のスキルを磨く。
  3. 外部 API の利用体験: OpenAI や Gemini といった生成系 AI の API を実際にアプリケーションに組み込み、その仕組みと効果的な活用方法への理解を深める。

2. アプリ機能の概要

冷蔵庫にある食材を入力すると、AI がそれらを使ったレシピを提案してくれる Web アプリケーションです。ユーザーはアカウントを作成でき、気に入ったレシピを保存して後から見返すことができます。

2.1 参考サイト

冷蔵庫の食材からレシピ提案してくれるサービス

サービス名 URL 特徴
Pecco https://pecco.app/ 冷蔵庫の食材からレシピを提案するサービス
冷蔵庫にあるものでレシピ提案プロンプト https://chapro.jp/prompt/1964 ChatGPT プロンプトを使った食材提案
Panasonic 冷蔵庫 AI カメラ https://panasonic.jp/reizo/app/live-pantry/vegetable-ai.html AI カメラで野菜の使い切りをサポート

類似サービス

サービス名 URL 特徴
DELISH KITCHEN https://delishkitchen.tv/ 動画でわかりやすいレシピ提案
キッコーマン 今日の献立 https://www.kikkoman.co.jp/homecook/calendar/this-week.html 食材・調味料メーカー提供のレシピ
タニタ社員食堂レシピ https://www.tanita-thl.co.jp/ 健康志向のレシピ提案

3. 使用技術スタック

分類 技術 バージョン 選定理由
フロントエンド Nuxt.js v3 Vue ベースで学習コストが低く、SSR・SPA 両対応が可能
フロントエンド TypeScript 最新 型安全で保守性を高めるため
フロントエンド TailwindCSS 最新 開発効率が高く、デザインを素早く適用できるため
バックエンド Python 3.11 学習済み、エコシステムが豊富
バックエンド FastAPI 最新 型ヒントを活かした高速な API 開発が可能
認証 JWT (JSON Web Token) 標準 ステートレスな認証を実現し、SPAとの連携が容易なため
データベース PostgreSQL 15 系 JSON 型や拡張性が強力で、本格運用に耐えるため
インフラ Docker 最新 環境構築の一貫性を担保するため
インフラ Docker Compose 最新 ローカル開発でのマルチコンテナ管理が容易なため
外部 API OpenAI API 最新 高精度な自然言語処理を利用するため
外部 API Google Gemini API 最新 マルチモーダル AI を試すため
パッケージ管理 pnpm 最新 ワークスペース対応が強力でモノレポ管理に適しているため
サービス名 URL 特徴
DELISH KITCHEN https://delishkitchen.tv/ 動画でわかりやすいレシピ提案
キッコーマン 今日の献立 https://www.kikkoman.co.jp/homecook/calendar/this-week.html 食材・調味料メーカー提供のレシピ
タニタ社員食堂レシピ https://www.tanita-thl.co.jp/ 健康志向のレシピ提案

3. 使用技術スタック

分類 技術 バージョン 選定理由
フロントエンド Nuxt.js v3 Vue ベースで学習コストが低く、SSR・SPA 両対応が可能
フロントエンド TypeScript 最新 型安全で保守性を高めるため
フロントエンド TailwindCSS 最新 開発効率が高く、デザインを素早く適用できるため
バックエンド Python 3.11 学習済み、エコシステムが豊富
バックエンド FastAPI 最新 型ヒントを活かした高速な API 開発が可能
データベース PostgreSQL 15 系 JSON 型や拡張性が強力で、本格運用に耐えるため
インフラ Docker 最新 環境構築の一貫性を担保するため
インフラ Docker Compose 最新 ローカル開発でのマルチコンテナ管理が容易なため
外部 API OpenAI API 最新 高精度な自然言語処理を利用するため
外部 API Google Gemini API 最新 マルチモーダル AI を試すため
パッケージ管理 pnpm 最新 ワークスペース対応が強力でモノレポ管理に適しているため
認証機能 JWT 最新 認証機能を1から作る経験をするため

4. チーム開発と進め方

4-1.担当振り分けと開発スタイル

本プロジェクトでは、機能ごとに担当者を分け、フロントエンドからバックエンドまでを一気通貫で開発する「垂直分割」スタイルを採用します。

  • 担当 A(MAI): ユーザー認証機能、レシピ保存(CRUD)機能
  • 担当 B(HARUMU): AI レシピ提案機能、UI/UX 全般

4-2.開発フロー

開発は以下のフローを基本とします。詳細はdocs/github_rules.mdを参照してください。

  1. 担当機能の Issue を元に、mainブランチから作業ブランチを作成 (feature/issue番号-機能名)。
  2. 作業が完了したら、変更をリモートにpushする。
  3. GitHub 上でプルリクエストを作成し、もう一方のメンバーをレビュー担当者に指定する。
  4. レビューと承認を経て、mainブランチにマージする。

4-3.開発スケジュール概要

  • Day 1: 環境構築、github 練習
  • Day 2: 設計 FIX、API 基盤構築
  • Day 3: 各担当のコア機能(認証, AI 連携)の実装
  • Day 4: レシピ保存機能の実装とテスト
  • Day 5: 統合テスト、デモ準備

4-4.開発環境

開発のセットアップから動作確認までに必要なコマンドをすべて網羅した表です。 サーバー起動コマンドを、ルートディレクトリで実行できるようにしました。 pnpm devを使ってフロントエンド・バックエンドの起動が可能です。

分類 目的・確認方法 コマンド 実行場所
初期セットアップ 全ての依存関係をインストール pnpm install ルート
データベース DBコンテナを起動 docker-compose up -d ルート
DBコンテナを停止 docker-compose down ルート
仮想環境 Python仮想環境を有効化 source venv/bin/activate packages/backend
Python仮想環境を無効化 deactivate (venv有効化中の) ターミナル
DBマイグレーション テーブル構造を最新の状態に更新 alembic upgrade head packages/backend
(venv有効化後)
サーバー起動 バックエンドサーバーを起動 pnpm dev:backend ルート
バックエンドサーバーを停止 Ctrl + C 実行中のターミナル
フロントエンドサーバーを起動 pnpm dev:frontend ルート
フロントエンドサーバーを停止 Ctrl + C 実行中のターミナル
テスト実行 バックエンドの単体テストを実行 pytest packages/backend
(venv有効化後)
フロントエンドの単体テストを実行 pnpm --filter nuxt-app test ルート
E2E(統合)テストを実行 pnpm exec playwright test ルート

4-4.コミュニケーション

  • 定例会: 毎朝 10 分程度の朝会を実施し、進捗と課題を共有します。
  • ツール: 随時の連絡には Discord/Zoom を使用します。
  • 時間設定: 解決にかける時間意識を持ち、30 分以上悩んでも解決しない場合はすぐにチームメンバーに相談します。

5. 改善点と学べたこと

項目 内容・教訓
環境構築の再現性 PythonのvenvはPC環境に依存しやすく、requirements.txtとバージョン統一の重要性を学んだ。
DBの互換性 テスト(SQLite)と本番(PostgreSQL)でのARRAY型の非互換性に直面。JSON型のような汎用的な型が重要。
設定ファイルの一元管理 チーム開発では.envconfig.pyの同期が不可欠。extra = 'ignore'設定で堅牢性を高める必要があった。
的確なエラーハンドリング CORSエラーの裏でバックエンドがクラッシュしているなど、ログを突き合わせた根本原因の特定が不可欠だった。

5-1.新しい技術

項目 内容・気づき
FastAPI vs Express.js Express.jsでは手動で設定が必要だったリクエストボディのバリデーションが、FastAPIではPydanticのスキーマ定義だけで完結し、型安全かつ高速に開発できる。API仕様書(Swagger UI)の自動生成も開発体験として非常に優れていた。
Nuxt.js vs Next.js Nuxt 3の自動インポート機能は、Next.jsに比べ規約が強く、記述量が少なくて済む印象。一方で、TypeScriptの型定義連携で予期せぬエラーに遭遇し、フレームワークの内部理解の重要性も感じた。
Pythonの環境管理 Node.jsのpnpmのようなロックファイルによる厳密なバージョン管理に慣れていると、Pythonのvenvは環境差異が出やすく、チームでの厳密な管理が必要だと実感した。
Details ### 違い
項目 JWT (JSON Web Token) Firebase Authentication
役割 規格・仕様 サービス・製品
概要 認証情報をJSON形式で安全にやり取りするための「トークンの設計図」。署名によって改ざんを防ぐ。 Googleが提供する、ユーザー認証機能一式をまとめたバックエンドサービス(BaaS)。内部でJWTなどの技術を使っている。
使い方 自分でトークンの生成、検証、失効などのロジックをすべて実装する必要がある。 SDKを導入し、数行のコードでGoogleログインやメール認証などを実装できる。ユーザー管理などもすべてFirebase側が行う。
自由度 非常に高い。トークンに含める情報や有効期限など、すべてを自由に設計できる。 低い。Firebaseの提供する認証フローに乗る必要がある。
分類 目的・確認方法 コマンド 実行場所
初期セットアップ 全ての依存関係をインストール pnpm install ルート
データベース DBコンテナを起動 docker-compose up -d ルート
DBコンテナを停止 docker-compose down ルート
仮想環境 Python仮想環境を有効化 source venv/bin/activate packages/backend
Python仮想環境を無効化 deactivate (venv有効化中の) ターミナル
DBマイグレーション テーブル構造を最新の状態に更新 alembic upgrade head packages/backend
(venv有効化後)
サーバー起動 バックエンドサーバーを起動 pnpm dev:backend ルート
バックエンドサーバーを停止 Ctrl + C 実行中のターミナル
フロントエンドサーバーを起動 pnpm dev:frontend ルート
フロントエンドサーバーを停止 Ctrl + C 実行中のターミナル
テスト実行 バックエンドの単体テストを実行 pytest packages/backend
(venv有効化後)
フロントエンドの単体テストを実行 pnpm --filter nuxt-app test ルート
E2E(統合)テストを実行 pnpm exec playwright test ルート

4-5.コミュニケーション

  • 定例会: 毎朝 10 分程度の朝会を実施し、進捗と課題を共有。
  • ツール: 随時の連絡には Discord/Zoom を使用。
  • 時間設定: 解決にかける時間意識を持ち、30 分以上悩んでも解決しない場合はすぐにチームメンバーに相談。

5. 改善点と学べたこと

項目 内容・教訓
環境構築の再現性 PythonのvenvはPC環境に依存しやすく、requirements.txtとバージョン統一の重要性を学んだ。
DBの互換性 テスト(SQLite)と本番(PostgreSQL)でのARRAY型の非互換性に直面。JSON型のような汎用的な型が重要。
設定ファイルの一元管理 チーム開発では.envconfig.pyの同期が不可欠。extra = 'ignore'設定で堅牢性を高める必要があった。
的確なエラーハンドリング CORSエラーの裏でバックエンドがクラッシュしているなど、ログを突き合わせた根本原因の特定が不可欠だった。

5-1.新しい技術

項目 内容・気づき
FastAPI vs Express.js Express.jsでは手動で設定が必要だったリクエストボディのバリデーションが、FastAPIではPydanticのスキーマ定義だけで完結し、型安全かつ高速に開発できる。API仕様書(Swagger UI)の自動生成も開発体験として非常に優れていた。
Nuxt.js vs Next.js Nuxt 3の自動インポート機能は、Next.jsに比べ規約が強く、記述量が少なくて済む印象。一方で、TypeScriptの型定義連携で予期せぬエラーに遭遇し、フレームワークの内部理解の重要性も感じた。
Pythonの環境管理 Node.jsのpnpmのようなロックファイルによる厳密なバージョン管理に慣れていると、Pythonのvenvは環境差異が出やすく、チームでの厳密な管理が必要だと実感した。

5-2. JWTとFirebaseの違いと今回の実装方法

違い

項目 JWT (JSON Web Token) Firebase Authentication
役割 規格・仕様 サービス・製品
概要 認証情報をJSON形式で安全にやり取りするための「トークンの設計図」。署名によって改ざんを防ぐ。 Googleが提供する、ユーザー認証機能一式をまとめたバックエンドサービス(BaaS)。内部でJWTなどの技術を使っている。
使い方 自分でトークンの生成、検証、失効などのロジックをすべて実装する必要がある。 SDKを導入し、数行のコードでGoogleログインやメール認証などを実装できる。ユーザー管理などもすべてFirebase側が行う。
自由度 非常に高い。トークンに含める情報や有効期限など、すべてを自由に設計できる。 低い。Firebaseの提供する認証フローに乗る必要がある。

例えるなら:

  • JWT: 家の「設計図」。どんな部屋をどこに作るか(トークンの中身)は自由だが、家を建てるのは自分。
  • Firebase: 「建売住宅」または「マンション」。設計は決まっているが、すぐに住み始めることができる。

今回の実装方法

今回のプロジェクトでは、JWTの規格に沿って、認証機能をフルスクラッチで実装しました。

  1. トークンの発行(バックエンド: auth_logic.py

    • ユーザーが/users/loginに正しいメールアドレスとパスワードを送信します。
    • サーバーはそれを検証し、成功すればpython-joseライブラリを使ってJWT(アクセストークン)を生成します。
    • トークンの中身(ペイロード)には、ユーザーを識別するための情報(sub: user.email)と有効期限(exp)を含ませました。
    • 生成したトークンをクライアント(フロントエンド)に返します。
  2. トークンの保持(フロントエンド: Piniaストア)

    • フロントエンドは受け取ったアクセストークンを、状態管理ライブラリPiniaのストアに保存します。
    • さらに、localStorageにもトークンを保存することで、ページをリロードしてもログイン状態が維持されるようにしました。
  3. トークンの検証(バックエンド: dependencies.py _ フロントエンドは、認証が必要なAPI(/recipesなど)を呼び出す際、作成した共通関数useApiFetchを使って、リクエストヘッダーにAuthorization: Bearer <トークン>の形でトークンを付与します。 _ バックエンドは、get_current_userという依存性注入関数で、送られてきたトークンを検証します。 _ トークンが改ざんされていないか、有効期限が切れていないかを確認し、問題がなければユーザー情報をDBから取得して、APIの処理を続行します。 _ もしトークンが無効であれば、401 Unauthorizedエラーを返します。


6. 今後追加したい機能

項目 内容
レシピ画像の自動生成 DALL-Eなどの画像生成AIを連携させ、レシピに画像を表示する。
AI応答の高速化 レシピのレスポンスに時間がかかっているので、Server-Sent Events (SSE)を利用したストリーミング表示を実装し、体感速度を向上させる。
テストの拡充と自動化 コードカバレッジを計測し、E2EテストをCIに組み込んで品質保証を自動化する。
  1. トークンの保持(フロントエンド: Piniaストア)
    • フロントエンドは受け取ったアクセストークンを、状態管理ライブラリPiniaのストアに保存します。
    • さらに、localStorageにもトークンを保存することで、ページをリロードしてもログイン状態が維持されるようにしました。
  2. トークンの検証(バックエンド: dependencies.py
    • フロントエンドは、認証が必要なAPI(/recipesなど)を呼び出す際、作成した共通関数useApiFetchを使って、リクエストヘッダーにAuthorization: Bearer <トークン>の形でトークンを付与します。
    • バックエンドは、get_current_userという依存性注入関数で、送られてきたトークンを検証します。
    • トークンが改ざんされていないか、有効期限が切れていないかを確認し、問題がなければユーザー情報をDBから取得して、APIの処理を続行します。
    • もしトークンが無効であれば、401 Unauthorizedエラーを返します。

6. 今後追加したい機能

項目 内容
レシピ画像の自動生成 DALL-Eなどの画像生成AIを連携させ、レシピに画像を表示する。
AI応答の高速化 レシピのレスポンスに時間がかかっているので、Server-Sent Events (SSE)を利用したストリーミング表示を実装し、体感速度を向上させる。
テストの拡充と自動化 コードカバレッジを計測し、E2EテストをCIに組み込んで品質保証を自動化する。

About

OpenAI LLMが提案レシピを返すアプリ

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •