# API 規格文檔 ## 概述 定義 Drama Ling 應用的完整 RESTful API 規格,基於 `system_structure_design.json` 中定義的14個功能特性和9個數據源設計。 ## API 設計原則 ### RESTful 設計標準 - [ ] **資源導向**: API端點基於資源設計而非動作 - [ ] **HTTP動詞**: 正確使用GET、POST、PUT、DELETE、PATCH - [ ] **狀態碼**: 使用標準HTTP狀態碼表示結果 - [ ] **無狀態**: API設計為無狀態,不依賴server端session - [ ] **版本控制**: API版本控制策略 (如 `/api/v1/`) ### API 安全原則 - [ ] **身份驗證**: JWT Token認證機制 - [ ] **授權控制**: Role-based權限控制 - [ ] **資料驗證**: 嚴格的輸入資料驗證 - [ ] **速率限制**: 防止API濫用的速率控制 - [ ] **HTTPS強制**: 所有API強制使用HTTPS ### 回應格式標準 ```json { "success": boolean, "data": object | array | null, "message": string, "error": { "code": string, "message": string, "details": object }, "meta": { "timestamp": "ISO8601", "request_id": "string", "pagination": object } } ``` ## 認證與授權 API ### 用戶認證 ```http POST /api/v1/auth/register Content-Type: application/json { "email": "user@example.com", "password": "securePassword123", "username": "dramatic_learner", "preferredLanguage": "en", "nativeLanguage": "zh-TW" } ``` ```http Response 201 Created { "success": true, "data": { "userId": "550e8400-e29b-41d4-a716-446655440000", "username": "dramatic_learner", "email": "user@example.com", "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refreshToken": "550e8400-e29b-41d4-a716-446655440001", "expiresIn": 3600 }, "message": "User registered successfully", "meta": { "timestamp": "2024-09-05T15:30:00Z", "requestId": "550e8400-e29b-41d4-a716-446655440002" } } ``` ### 登入驗證 ```http POST /api/v1/auth/login { "email": "user@example.com", "password": "securePassword123" } ``` ### Token 更新 ```http POST /api/v1/auth/refresh Authorization: Bearer ``` ### 登出 ```http POST /api/v1/auth/logout Authorization: Bearer ``` ## 用戶資料管理 API ### 用戶資料 (UserProfile) #### 獲取用戶資料 ```http GET /api/v1/users/profile Authorization: Bearer Response 200 OK { "success": true, "data": { "user_id": "USR_12345", "username": "dramatic_learner", "email": "user@example.com", "avatar_url": "https://cdn.example.com/avatars/12345.jpg", "level": "B1", "total_score": 15680, "streak_days": 15, "joined_date": "2024-01-15T08:00:00Z", "last_active": "2024-09-05T14:30:00Z", "preferences": { "target_language": "en", "native_language": "zh-TW", "difficulty_preference": "adaptive", "daily_goal_minutes": 30, "notifications_enabled": true, "theme": "light" }, "subscription": { "plan": "premium", "status": "active", "expires_at": "2025-01-15T08:00:00Z" } } } ``` #### 更新用戶資料 ```http PUT /api/v1/users/profile Authorization: Bearer { "username": "new_username", "avatar_url": "https://cdn.example.com/avatars/new_avatar.jpg", "preferences": { "daily_goal_minutes": 45, "notifications_enabled": false } } ``` #### 用戶學習統計 ```http GET /api/v1/users/stats Authorization: Bearer Response 200 OK { "success": true, "data": { "total_dialogues": 245, "total_study_time": 1280, // minutes "vocabulary_learned": 890, "vocabulary_mastered": 650, "scenarios_completed": 35, "achievements_unlocked": 18, "current_streak": 15, "longest_streak": 28, "weekly_progress": { "dialogues_this_week": 12, "minutes_this_week": 180, "goal_completion_rate": 0.85 } } } ``` ## 學習內容 API ### 課程與場景 (Lesson) #### 獲取場景列表 ```http GET /api/v1/lessons/scenarios Authorization: Bearer Query Parameters: - category: string (daily_life, social, emergency, professional) - difficulty: string (A1, A2, B1, B2, C1, C2) - limit: integer (default: 20) - offset: integer (default: 0) Response 200 OK { "success": true, "data": { "scenarios": [ { "scenario_id": "SC_Restaurant_01", "title": "餐廳訂位", "description": "學習如何在餐廳預約座位和點餐", "category": "daily_life", "difficulty": "A2", "estimated_duration": 8, // minutes "thumbnail_url": "https://cdn.example.com/scenarios/restaurant.jpg", "vocabulary_count": 25, "completion_rate": 0.75, "user_completed": true, "user_score": 85, "unlock_condition": null, "is_premium": false } ], "pagination": { "total": 65, "page": 1, "per_page": 20, "total_pages": 4 } } } ``` #### 獲取場景詳情 ```http GET /api/v1/lessons/scenarios/{scenario_id} Authorization: Bearer Response 200 OK { "success": true, "data": { "scenario_id": "SC_Restaurant_01", "title": "餐廳訂位", "description": "學習如何在餐廳預約座位和點餐", "category": "daily_life", "difficulty": "A2", "learning_objectives": [ "學會預約餐廳座位", "掌握點餐相關詞彙", "練習詢問食材和偏好" ], "target_vocabulary": [ { "word": "reservation", "phonetic": "/ˌrezəˈveɪʃən/", "translation": "預約", "definition": "an arrangement to have something kept for you" } ], "cultural_notes": "西式餐廳通常需要事先預約,特別是在熱門時段...", "estimated_duration": 8, "prerequisite_scenarios": ["SC_Greeting_01"], "user_progress": { "completed": true, "best_score": 85, "completion_count": 3, "last_completed": "2024-09-03T19:20:00Z" } } } ``` ### 詞彙管理 API #### 獲取詞彙列表 ```http GET /api/v1/vocabulary Authorization: Bearer Query Parameters: - category: string (life, academic, business, etc.) - difficulty: string (A1-C2) - mastery_level: string (learning, practicing, mastered) - limit: integer (default: 50) Response 200 OK { "success": true, "data": { "vocabulary": [ { "vocab_id": "VOC_0001", "word": "restaurant", "phonetic": "/ˈrestərɑːnt/", "part_of_speech": "noun", "definition": "A place where people pay to sit and eat meals", "translation": "餐廳", "difficulty": "A2", "frequency_rank": 1250, "user_mastery": { "level": "practicing", // learning, practicing, mastered "score": 75, "review_count": 5, "last_reviewed": "2024-09-03T10:15:00Z", "next_review": "2024-09-07T10:15:00Z" }, "example_sentences": [ { "english": "We made a reservation at the new restaurant.", "chinese": "我們在新餐廳訂了位。" } ] } ] } } ``` #### 詞彙複習API ```http GET /api/v1/vocabulary/review/daily Authorization: Bearer Response 200 OK { "success": true, "data": { "review_session_id": "REV_20240905_USR12345", "total_words": 15, "estimated_time": 5, // minutes "words": [ { "vocab_id": "VOC_0001", "word": "restaurant", "review_type": "recognition", // recognition, recall, spelling "options": ["餐廳", "旅館", "商店", "學校"] // for recognition type } ] } } ``` #### 提交複習結果 ```http POST /api/v1/vocabulary/review/submit Authorization: Bearer { "review_session_id": "REV_20240905_USR12345", "results": [ { "vocab_id": "VOC_0001", "user_answer": "餐廳", "is_correct": true, "response_time": 2.5, // seconds "confidence": 4 // 1-5 scale } ] } ``` ## 對話練習 API ### 對話系統 (Dialogue) #### 開始對話練習 ```http POST /api/v1/dialogues/start Authorization: Bearer { "scenario_id": "SC_Restaurant_01", "difficulty_override": "A2", // optional "target_vocabulary": ["reservation", "menu", "order"] // optional } Response 201 Created { "success": true, "data": { "dialogue_id": "DLG_20240905_001", "scenario_id": "SC_Restaurant_01", "session_token": "session_token_here", "initial_context": { "setting": "高級餐廳內部,晚上8點", "your_role": "客人", "ai_role": "餐廳服務員", "objective": "成功預約並點餐" }, "ai_message": { "message": "Good evening! Welcome to Milano Restaurant. Do you have a reservation?", "audio_url": "https://cdn.example.com/audio/dlg001_001.mp3", "suggestions": [ "Yes, I have a reservation under Smith.", "No, but could we get a table for two?", "I'd like to make a reservation for tonight." ] } } } ``` #### 發送對話訊息 ```http POST /api/v1/dialogues/{dialogue_id}/message Authorization: Bearer { "message": "Yes, I have a reservation under Chen for 8 PM.", "message_type": "text", // text, audio "audio_url": "https://cdn.example.com/user_audio/msg001.mp3" // if audio } Response 200 OK { "success": true, "data": { "ai_response": { "message": "Perfect! Mr. Chen, your table for two is ready. Right this way please.", "audio_url": "https://cdn.example.com/audio/dlg001_002.mp3", "analysis": { "grammar_score": 90, "semantic_score": 95, "fluency_score": 85, "overall_score": 90, "feedback": "Excellent use of formal language for restaurant context!" }, "suggestions": [ "Thank you. Could we see the menu please?", "Great! What do you recommend today?", "Thank you. We'd like to start with drinks." ] }, "dialogue_progress": { "turns_completed": 2, "estimated_turns_remaining": 6, "objectives_completed": ["greeting", "reservation_confirmation"], "objectives_remaining": ["ordering", "payment"] } } } ``` #### 獲取AI分析詳情 ```http GET /api/v1/dialogues/{dialogue_id}/analysis Authorization: Bearer Response 200 OK { "success": true, "data": { "dialogue_id": "DLG_20240905_001", "overall_analysis": { "grammar_score": 88, "semantic_score": 92, "fluency_score": 85, "total_score": 88, "completion_percentage": 100 }, "detailed_feedback": [ { "turn_number": 1, "user_message": "Yes, I have a reservation under Chen for 8 PM.", "analysis": { "grammar_issues": [], "semantic_appropriateness": "Excellent - appropriate formality level", "fluency_notes": "Natural and confident delivery", "suggestions": [], "vocabulary_used": [ { "word": "reservation", "usage_correctness": "perfect", "context_appropriateness": "excellent" } ] } } ], "improvement_suggestions": [ "Consider using more varied vocabulary for ordering", "Practice pronunciation of 'th' sounds" ], "vocabulary_progress": { "words_practiced": 8, "words_used_correctly": 7, "new_words_encountered": 3 } } } ``` #### 結束對話 ```http POST /api/v1/dialogues/{dialogue_id}/complete Authorization: Bearer Response 200 OK { "success": true, "data": { "dialogue_summary": { "dialogue_id": "DLG_20240905_001", "duration": 420, // seconds "turns_completed": 8, "final_score": 88, "objectives_achieved": 4, "objectives_total": 4, "vocabulary_practiced": 12, "experience_gained": 150, "score_gained": 75 }, "rewards": { "experience_points": 150, "score_points": 75, "achievements_unlocked": ["First Perfect Dialogue"], "vocabulary_progress": { "words_advanced": 3, "words_mastered": 1 } } } } ``` ## 任務系統 API ### 任務管理 (Task & TaskReward) #### 獲取可用任務 ```http GET /api/v1/tasks Authorization: Bearer Query Parameters: - type: string (daily, weekly, achievement, challenge) - status: string (available, in_progress, completed) Response 200 OK { "success": true, "data": { "tasks": [ { "task_id": "TASK_DAILY_001", "type": "daily", "title": "完成3次對話練習", "description": "今天完成任意3次對話練習以獲得獎勵", "objectives": [ { "objective_id": "OBJ_001", "description": "完成對話練習", "target_value": 3, "current_value": 1, "unit": "次" } ], "rewards": { "experience": 100, "score": 50, "special_items": ["daily_streak_bonus"] }, "deadline": "2024-09-05T23:59:59Z", "status": "in_progress", "created_at": "2024-09-05T00:00:00Z" } ] } } ``` #### 獲取任務詳情 ```http GET /api/v1/tasks/{task_id} Authorization: Bearer Response 200 OK { "success": true, "data": { "task_id": "TASK_WEEKLY_001", "type": "weekly", "title": "週練習大師", "description": "本週完成20次對話練習並達到平均85分", "long_description": "挑戰自己在本週內完成20次高品質的對話練習...", "objectives": [ { "objective_id": "OBJ_001", "description": "完成對話練習", "target_value": 20, "current_value": 8, "unit": "次" }, { "objective_id": "OBJ_002", "description": "平均分數達標", "target_value": 85, "current_value": 87.5, "unit": "分" } ], "rewards": { "experience": 500, "score": 300, "special_items": ["premium_scenario_unlock"], "achievements": ["weekly_master"] }, "progress_percentage": 40, "deadline": "2024-09-08T23:59:59Z", "difficulty": "medium" } } ``` #### 領取任務獎勵 ```http POST /api/v1/tasks/{task_id}/claim_reward Authorization: Bearer Response 200 OK { "success": true, "data": { "rewards_claimed": { "experience": 500, "score": 300, "special_items": ["premium_scenario_unlock"], "achievements": ["weekly_master"] }, "updated_user_stats": { "total_experience": 15680, "total_score": 8950, "level": "B1+", "achievements_count": 19 } } } ``` ## 排行榜與競爭 API ### 排行榜系統 (Leaderboard) #### 獲取排行榜 ```http GET /api/v1/leaderboard Authorization: Bearer Query Parameters: - type: string (global, weekly, friends, regional) - category: string (overall, dialogue_count, vocabulary_mastered) - limit: integer (default: 50) Response 200 OK { "success": true, "data": { "leaderboard_type": "global", "category": "overall", "period": "all_time", "updated_at": "2024-09-05T15:30:00Z", "user_rank": { "rank": 1247, "score": 15680, "percentile": 78.5 }, "top_users": [ { "rank": 1, "user_id": "USR_VIP_001", "username": "LanguageMaster", "avatar_url": "https://cdn.example.com/avatars/vip001.jpg", "score": 45680, "level": "C2", "country": "TW", "streak_days": 365, "badges": ["yearly_champion", "perfectionist"] } ], "nearby_users": [ // Users around current user's rank ] } } ``` #### 好友排行榜 ```http GET /api/v1/leaderboard/friends Authorization: Bearer Response 200 OK { "success": true, "data": { "friends_ranking": [ { "rank": 1, "user_id": "USR_12346", "username": "StudyBuddy", "avatar_url": "https://cdn.example.com/avatars/12346.jpg", "score": 18950, "level": "B2", "status": "online", "recent_activity": "完成了商務會議場景 - 2小時前" } ], "current_user": { "rank": 3, "score": 15680, "score_difference": -3270, // difference from rank 1 "rank_change": 1 // compared to last week } } } ``` ## 訂閱與購買 API ### 訂閱管理 (Subscription) #### 獲取訂閱方案 ```http GET /api/v1/subscriptions/plans Authorization: Bearer Response 200 OK { "success": true, "data": { "plans": [ { "plan_id": "PLAN_BASIC", "name": "基礎版", "description": "解鎖基礎功能,享受無廣告體驗", "price": { "monthly": { "amount": 199, "currency": "TWD", "original_price": 199 }, "yearly": { "amount": 1980, "currency": "TWD", "original_price": 2388, "discount_percentage": 17 } }, "features": [ "無限對話練習", "無廣告體驗", "基礎AI分析", "雲端同步" ], "limitations": [ "僅基礎和社交場景", "不含語音識別" ] } ], "current_subscription": { "plan_id": "PLAN_PREMIUM", "status": "active", "expires_at": "2025-01-15T08:00:00Z", "auto_renewal": true, "payment_method": "credit_card" } } } ``` #### 訂閱方案 ```http POST /api/v1/subscriptions/subscribe Authorization: Bearer { "plan_id": "PLAN_PREMIUM", "billing_cycle": "yearly", // monthly, yearly "payment_method_id": "pm_1234567890", "auto_renewal": true } Response 201 Created { "success": true, "data": { "subscription_id": "SUB_20240905_001", "plan_id": "PLAN_PREMIUM", "status": "active", "started_at": "2024-09-05T15:30:00Z", "expires_at": "2025-09-05T15:30:00Z", "next_billing_date": "2025-09-05T15:30:00Z", "amount_paid": 3999, "currency": "TWD" } } ``` ### 內購系統 (Purchase) #### 獲取付費內容 ```http GET /api/v1/store/content Authorization: Bearer Query Parameters: - category: string (scenario_pack, expert_course, premium_content) - price_range: string (0-100, 100-500, 500+) Response 200 OK { "success": true, "data": { "content_packs": [ { "content_id": "PACK_TRAVEL_001", "type": "scenario_pack", "title": "旅遊場景包", "description": "包含機場、飯店、觀光等15個實用旅遊場景", "price": { "amount": 149, "currency": "TWD", "original_price": 199, "discount_percentage": 25 }, "content_preview": { "scenarios_count": 15, "estimated_hours": 8, "difficulty_range": "A2-B2", "preview_scenario": "SC_AIRPORT_001" }, "thumbnail_url": "https://cdn.example.com/packs/travel.jpg", "user_owned": false, "special_offer": { "expires_at": "2024-09-10T23:59:59Z", "offer_text": "限時75折優惠!" } } ] } } ``` #### 購買內容 ```http POST /api/v1/store/purchase Authorization: Bearer { "content_id": "PACK_TRAVEL_001", "payment_method_id": "pm_1234567890" } Response 201 Created { "success": true, "data": { "purchase_id": "PUR_20240905_001", "content_id": "PACK_TRAVEL_001", "amount_paid": 149, "currency": "TWD", "purchased_at": "2024-09-05T15:45:00Z", "content_unlocked": { "scenarios": ["SC_AIRPORT_001", "SC_HOTEL_001", "..."], "access_expires": null // permanent access } } } ``` ### 廣告系統 (AdImpression) #### 獲取廣告獎勵機會 ```http GET /api/v1/ads/opportunities Authorization: Bearer Response 200 OK { "success": true, "data": { "available_ads": [ { "ad_id": "AD_REWARD_001", "type": "video", "duration": 30, // seconds "reward": { "type": "extra_dialogue", "quantity": 2, "description": "額外2次對話練習機會" }, "cooldown_remaining": 0, // seconds until next ad "daily_limit_remaining": 3 } ] } } ``` #### 觀看廣告獲得獎勵 ```http POST /api/v1/ads/watch Authorization: Bearer { "ad_id": "AD_REWARD_001", "watch_duration": 30, // seconds actually watched "completion_status": "completed" // completed, skipped, error } Response 200 OK { "success": true, "data": { "reward_granted": { "type": "extra_dialogue", "quantity": 2, "expires_at": "2024-09-06T15:45:00Z" }, "next_ad_available_at": "2024-09-05T16:15:00Z" } } ``` --- ## 錯誤處理 ### 標準錯誤碼 ```json { "success": false, "error": { "code": "VALIDATION_ERROR", "message": "輸入資料驗證失敗", "details": { "field": "email", "reason": "invalid_format" } } } ``` ### 常見錯誤碼 - `UNAUTHORIZED` (401): 未授權存取 - `FORBIDDEN` (403): 權限不足 - `NOT_FOUND` (404): 資源不存在 - `VALIDATION_ERROR` (400): 資料驗證失敗 - `RATE_LIMIT_EXCEEDED` (429): 超過速率限制 - `INTERNAL_SERVER_ERROR` (500): 伺服器內部錯誤 - `SERVICE_UNAVAILABLE` (503): 服務暫時不可用 ### 訂閱相關錯誤 - `SUBSCRIPTION_REQUIRED`: 需要訂閱才能存取 - `SUBSCRIPTION_EXPIRED`: 訂閱已過期 - `PAYMENT_FAILED`: 付款處理失敗 - `CONTENT_NOT_PURCHASED`: 內容未購買 --- ## API 版本控制與部署 ### 版本控制策略 - [ ] **URL版本控制**: `/api/v1/`, `/api/v2/` - [ ] **向後相容**: 新版本保持向後相容性 - [ ] **廢棄通知**: 提前6個月通知API廢棄 - [ ] **多版本支援**: 同時支援2-3個版本 - [ ] **版本文檔**: 每個版本維護獨立文檔 ### 環境配置 ```bash # 開發環境 API_BASE_URL=https://dev-api.dramaling.com API_VERSION=v1 # 測試環境 API_BASE_URL=https://staging-api.dramaling.com API_VERSION=v1 # 生產環境 API_BASE_URL=https://api.dramaling.com API_VERSION=v1 ``` ### 效能考量 - [ ] **回應時間**: 95%的API請求在200ms內回應 - [ ] **快取策略**: 靜態內容使用CDN,動態內容使用Redis - [ ] **資料庫優化**: 適當的索引和查詢優化 - [ ] **負載平衡**: 水平擴展API服務器 - [ ] **監控告警**: API效能和錯誤率監控 --- ## 待完成任務 ### 高優先級 1. [ ] 完善所有API端點的詳細規格和範例 2. [ ] 設計API的認證和授權機制 3. [ ] 建立API文檔的自動生成和維護流程 4. [ ] 實現API的錯誤處理和驗證邏輯 ### 中優先級 1. [ ] 設計API的快取和效能優化策略 2. [ ] 建立API的測試套件和自動化測試 3. [ ] 規劃API的版本控制和遷移策略 4. [ ] 設計API的監控和分析系統 ### 低優先級 1. [ ] 研究GraphQL作為REST API的補充 2. [ ] 探索Real-time API (WebSocket) 的應用場景 3. [ ] 建立API的開發者工具和SDK 4. [ ] 設計第三方整合的API授權機制 --- **最後更新**: 2024年9月5日 **負責人**: 待分配 **審查週期**: 每兩週檢討一次