skipLink.label

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

  1. Parse REST routes — extract method, path, name, params
  2. Generate GraphQL types — create schema with Query and Mutation types
  3. Map methods — GET → Query, POST → Mutation
  4. Generate resolvers — wrap existing logic in resolver functions
  5. 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 schema
type 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 Query
type Query {
getUsers: String
createUser(name: String!, email: String!): String // WRONG!
}
// ✅ Correct: POST becomes Mutation
type 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.

  1. Download ไฟล์เริ่มต้นของ quest:

    Terminal window
    npx bluebeltdojo download quest-98-api-migration
    cd quest-98-api-migration
  2. เปิด problem.js ใน editor ของคุณพร้อมความช่วยเหลือของ AI

  3. Implement solution ตาม instructions ใน problem.js

  4. ตรวจสอบ solution ของคุณ:

    Terminal window
    node test.js
  5. ส่งคำตอบ:

    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