Food Shuffle APIは、位置情報を活用して飲食店のレビューを共有するアプリケーション「food Shuffle」のバックエンドAPIサーバーです。
既存のグルメサイトが抱える課題意識から制作されました。多くのサイトでは、インセンティブ(報酬)を目的としたレビューが多く投稿されることで情報の信頼性が損なわれており、利用者が本当に価値のある情報を見つけにくいという問題がありました。
そこで、レビューの「価値」と「信頼性」を根本から高めることを目的としました。
-
レビューの価値向上 レビューの入手方法を、位置情報を利用したユーザー同士の「すれ違い」という偶然性の高い手段に限定しました。これにより、レビューの入手機会が制限され、一つ一つの情報の希少価値が高まります。また、他者と共有できるレビューも自身のストックから1つに絞る方式とし、ユーザーがより価値が高いと判断した情報を厳選して共有するよう動機付けます。
-
信頼性の高い情報の流通: レビューを受け取ったユーザーが、実際にその飲食店を訪れた後に「いいね」という形で評価できる機能を設けました。この「いいね」の数に応じてレビューの共有範囲(すれ違い時に相手に届く距離)が広がるため、実際の利用者によって支持された信頼性の高い情報ほど、より多くの人に届きやすくなる循環が生まれます。
位置情報を利用する特性上、サーバーへの通信リクエストが多発することを想定し、高いパフォーマンス性能を持つGo言語を採用しました。また、チームメンバーが学習したいという意欲が高かったことも選定を後押ししました。
過去の開発で利用経験があるメンバーがいたため、チーム内の他メンバーに対する学習コストを低減できると考え採用しました。
過去に利用経験のあるXORMでは、テーブル定義の際に外部キー設定をSQL文として記述する必要があるなど機能面が少し物足りないと感じました。 そこで、GoのORMとして多機能で、情報量も豊富なGORMを選択しました。
メインのデータベースには、チームメンバー全員が使い慣れているためMySQLを採用しました。一方で、コア機能である位置情報共有で、ユーザー間の距離計算を効率的に行うために、インメモリデータベースであるRedisを導入しました。また、TTL設定によって一時的な情報保存にも適していたため採用しました。
電話番号認証を簡単かつ迅速に実装できる点、そして無料で利用できるというメリットからFirebase Authenticationを選択しました。
リアルタイム通信: WebSocket (Gorilla WebSocket)
その他: Zap (ロギング), Cron (バッチ処理)
レイヤードアーキテクチャを採用して責務の分離を意識しています。
main.go: アプリケーションのエントリーポイント。各種初期化処理を実行。server: Ginフレームワークの初期化とルーティング設定。handler: HTTPリクエストを受け取り、バリデーションを行い、適切なサービスを呼び出す。service: 中核となるビジネスロジックを実装。リポジトリ層を介してデータ操作を行う。repository: データ永続化のための抽象層。orm: GORMを利用したMySQLとのやり取り。redis: Redisを利用したキャッシュ(ユーザー仮登録)と位置情報管理。fireauth: Firebase Admin SDKによる電話番号認証の検証。
middleware: JWT認証やユーザー種別によるアクセス制御。dto: (Data Transfer Object) APIのレスポンスやリクエストに使用するデータ構造。model: GORMのデータベースモデル(テーブルスキーマ)。ws: WebSocketによるリアルタイム通信の管理。utility: 認証、画像処理、カスタムエラー、定数など、共通の補助機能。public: ユーザー登録用のシンプルなWebフロントエンド関連ファイル。
- アカウント管理: メールアドレス、パスワード、電話番号認証による新規登録とログイン。
- 位置情報共有: WebSocketを利用したリアルタイムな位置情報送信。
- レビュー交換: 付近のユーザーとすれ違うことで、設定したレビューを自動で交換・受信。
- レビュー管理:
- 飲食店のレビュー投稿(写真付き)。
- 受信したレビューを「興味あり」「興味なし」「いいね」で分類・管理。
- 自分が投稿・いいね・興味ありに分類したレビューの一覧表示。
- 店舗情報:
- 店舗詳細情報の閲覧。
- 訪問した店舗(レビュー済み/未レビュー)の一覧表示。
- 店舗へのチェックイン機能。
- 予約機能: 店舗への予約申し込みと、自身の予約状況の確認。
- 共有設定:
- すれ違い時に共有する自身のレビュー(最大3つ)を設定。
- レビュー共有の通知モード(Active/Silent/Disabled)の切り替え。
- 店舗管理:
- 自身の店舗情報の管理・閲覧。
- コースメニューの登録・管理。
- 混雑状況の更新: 店舗の混み具合(空き/余裕あり/満席)をリアルタイムで更新。
- レビュー閲覧: 自身の店舗に投稿されたレビューの一覧表示といいね数の確認。
- 予約管理: 店舗に入った予約の一覧表示。
- お助けブースト: 緊急の集客キャンペーン(例:予約キャンセル発生時など)を作成し、近隣のユーザーに通知。
- 近隣ユーザー表示: 店舗周辺にいる一般ユーザーの数を把握。
| Method | Path | 認証 | 説明 |
|---|---|---|---|
POST |
/v1/login |
不要 | ユーザーログイン |
POST |
/v1/pre-register |
不要 | 一般ユーザー仮登録(情報送信) |
POST |
/v1/register |
不要 | 一般ユーザー本登録(Firebaseトークン検証) |
GET |
/v1/auth/images/:id |
必要 | 画像ファイルを取得 |
| Method | Path | 説明 |
|---|---|---|
GET |
/places |
訪問した場所のリストを取得 |
GET |
/locations |
WebSocketで位置情報を共有するエンドポイント |
PUT |
/mode/:status |
共有モード(通知状態)を変更 |
GET |
/reviews/receives |
受信したレビュー(未分類)一覧を取得 |
GET |
/reviews/interests |
「興味あり」のレビュー一覧を取得 |
GET |
/reviews/likes |
「いいね」したレビュー一覧を取得 |
POST |
/reviews/posts |
新規レビューを投稿 |
PUT |
/reviews/sets |
共有するレビューを設定 |
PUT |
/:review_uuid/status/:review_status |
レビューのステータスを更新 |
GET |
/reservations/upcomings |
自身の今後の予約一覧を取得 |
GET |
/restaurants/visited |
訪問済み(未レビュー)の店舗一覧 |
GET |
/restaurants/reviewed |
レビュー投稿済みの店舗一覧 |
GET |
/restaurants/:restaurant_uuid |
店舗詳細情報を取得 |
POST |
/restaurants/:restaurant_uuid/reservations |
店舗へ予約 |
GET |
/restaurants/:restaurant_uuid/posted |
自分がその店に投稿したレビュー詳細を取得 |
GET |
/restaurants/:restaurant_uuid/reviews |
その店に対して受信したレビュー一覧を取得 |
POST |
/restaurants/:restaurant_uuid/checkin |
店舗へチェックイン |
| Method | Path | 説明 |
|---|---|---|
GET |
/ |
自身の店舗情報を取得 |
GET |
/courses |
自身の店舗のコース一覧を取得 |
GET |
/reviews |
自身の店舗に投稿されたレビュー一覧を取得 |
GET |
/nearby |
店舗周辺のユーザー数を取得 |
GET |
/reservations |
店舗の予約一覧を取得 |
POST |
/campaigns |
お助けブースト(緊急キャンペーン)を作成 |
PUT |
/mode/:status |
店舗の混雑状況を更新 |
- Go 1.23+
- MySQL
- Redis
- Docker (推奨)
-
リポジトリをクローン
git clone git@github.com:Doremifa-donuts/food-shuffle-api.git cd food-shuffle-api -
依存関係をインストール
go mod tidy
-
環境変数の設定 ルートディレクトリに
.envファイルを作成し、以下の変数を設定します。# Server Configuration GO_PORT=5678 # Database Configuration MYSQL_HOST=db_host MYSQL_PORT=3306 MYSQL_USER=your_user MYSQL_PASSWORD=your_password MYSQL_DATABASE=food_shuffle # JWT Configuration JWT_SECRET_KEY=your_super_secret_key JWT_TOKEN_LIFETIME=86400 # 24 hours in seconds # Google Cloud / Firebase # serviceAccountKey.jsonのパスを指定 GOOGLE_APPLICATION_CREDENTIALS=./serviceAccountKey.json
-
Firebaseサービスアカウントキー Firebaseプロジェクトからサービスアカウントキー(JSONファイル)をダウンロードし、プロジェクトのルートに
serviceAccountKey.jsonという名前で配置してください。
go run main.go