API Migration Tool
API Migration Tool
medium 25-30 minutes🎯 Learning Objectives
- How to convert REST route definitions to GraphQL schema and resolvers
- Why GET routes become Query resolvers and POST routes become Mutation resolvers
- How to generate GraphQL type definitions from REST endpoint parameters
- Why incremental migration beats wholesale rewrites
📖 Concept: REST → GraphQL Migration
REST API migration คือการเปลี่ยนจาก REST endpoints ที่มี multiple URLs เป็น GraphQL ที่มี single endpoint — เหมือนการเปลี่ยนจาก many small techniques เป็น one unified fighting style แต่ migration ต้องทำอย่าง incrementally — อย่า rewrite ทุก endpoint พร้อมกัน
หลักการสำคัญ: GET → Query, POST → Mutation — นี่คือ semantic mapping ที่ถูกต้อง. AI tools มักจะ convert ทุกอย่างเป็น Query ซึ่งผิด — POST endpoints ต้องกลายเป็น Mutation เพราะมันมี side effects
Think of it like converting a library of individual forms into a single powerful form — each REST endpoint becomes a GraphQL field, but the semantics (read vs write) must be preserved exactly.
⚙️ How It Works
The Migration Workflow
- Parse REST routes — extract method, path, name, params
- Generate GraphQL types — create schema with Query and Mutation types
- Map methods — GET → Query, POST → Mutation
- Generate resolvers — wrap existing logic in resolver functions
- Verify — ensure all routes are mapped correctly
REST → GraphQL Mapping
// REST definition{ method: 'GET', path: '/users', name: 'getUsers', params: [] }{ method: 'POST', path: '/users', name: 'createUser', params: ['name', 'email'] }
// GraphQL schematype Query { getUsers: String}
type Mutation { createUser(name: String!, email: String!): String}
// Resolvers{ Query: { getUsers: (parent, args) => { ... } }, Mutation: { createUser: (parent, args) => { ... } }}The Critical Rule: POST → Mutation
// ❌ Naive AI: all routes become Querytype Query { getUsers: String createUser(name: String!, email: String!): String // WRONG!}
// ✅ Correct: POST becomes Mutationtype Query { getUsers: String}type Mutation { createUser(name: String!, email: String!): String // CORRECT}💡 Example: Walkthrough
const routes = [ { method: 'GET', path: '/users', name: 'getUsers', params: [] }, { method: 'POST', path: '/users', name: 'createUser', params: ['name', 'email'] }];
// Analysis:// - GET /users → Query.getUsers// - POST /users → Mutation.createUser// - createUser params: name, email → add to Mutation type
// Output:{ schema: 'type Query {\n getUsers: String\n}\ntype Mutation {\n createUser(name: String!, email: String!): String\n}', resolvers: { Query: { getUsers: [Function] }, Mutation: { createUser: [Function] } }}⚠️ Common Mistakes
Mistake 1: Converting POST to Query
“ทุก route กลายเป็น Query” → POST endpoints มี side effects — ต้องเป็น Mutation
Mistake 2: Forgetting to generate resolvers
“Schema ถูกต้องแต่ resolvers ว่าง” → ทุก field ใน schema ต้องมี resolver function
Mistake 3: Not including parameters in type definition
“ลืมใส่ params ใน GraphQL type” → Parameters ต้องถูก map เป็น GraphQL arguments:
(name: String!, email: String!)
Mistake 4: Empty input crashes
“ไม่ได้ handle routes ว่าง” → Empty routes → return
{ schema: '', resolvers: {} }
📝 Knowledge Check
📝 Knowledge Check
Q1:In GraphQL, what should POST REST routes be converted to?
Q2:What is the correct output structure for restToGraphQL()?
Q3:Why should REST → GraphQL migration be done incrementally?
🏋️ Quest: API Migration Tool
Now it’s time to practice! Migrate REST endpoints to GraphQL resolvers.
-
Download ไฟล์เริ่มต้นของ quest:
Terminal window npx bluebeltdojo download quest-98-api-migrationcd quest-98-api-migration -
เปิด
problem.jsใน editor ของคุณพร้อมความช่วยเหลือของ AI -
Implement solution ตาม instructions ใน
problem.js -
ตรวจสอบ solution ของคุณ:
Terminal window node test.js -
ส่งคำตอบ:
Terminal window npx bluebeltdojo submit
💡 Tip: ทดสอบ edge case — POST routes ต้องเป็น Mutation ไม่ใช่ Query
คำใบ้
restToGraphQL(routes)รับ array ของ route objects และ return{ schema, resolvers }- GET → Query, POST → Mutation — นี่คือ rule ที่ต้อง遵守
- Parameters ต้องถูก map เป็น GraphQL arguments
- ถ้าติดขัด ดู
_solution/solution.js