สร้าง GraphQL API Server ด้วย Apollo Server

Ashley Goolam

Ashley Goolam

3 September 2025

สร้าง GraphQL API Server ด้วย Apollo Server

เคยสงสัยไหมว่าจะสร้าง API ที่ทรงพลังซึ่งช่วยให้ไคลเอนต์สามารถร้องขอข้อมูลที่ต้องการได้อย่างแม่นยำได้อย่างไร? นั่นคือความมหัศจรรย์ของ GraphQL และด้วย Apollo Server การสร้าง API นั้นง่ายกว่าที่คุณคิด! หากคุณเบื่อกับ Endpoint ที่ไม่ยืดหยุ่นของ REST, GraphQL มอบความยืดหยุ่น และ Apollo Server คือเครื่องมือที่เหมาะสมที่สุดที่จะทำให้สิ่งนี้เกิดขึ้น ในบทเรียนเชิงสนทนานี้ เราจะแนะนำการตั้งค่าเซิร์ฟเวอร์ GraphQL โดยใช้ Apollo Server ตั้งแต่การเริ่มต้นโปรเจกต์ไปจนถึงการทดสอบ Queries และ Mutations ไม่ว่าคุณจะใช้ JavaScript หรือ TypeScript คุณก็จะมีเซิร์ฟเวอร์ที่ทำงานได้ในเวลาอันรวดเร็ว มาดำดิ่งและสร้างสรรค์สิ่งดีๆ ด้วย GraphQL และ Apollo Server กันเถอะ!

💡
ต้องการเครื่องมือทดสอบ API ที่ยอดเยี่ยมที่สร้าง เอกสาร API ที่สวยงาม หรือไม่?

ต้องการแพลตฟอร์มแบบครบวงจรที่ช่วยให้ทีมพัฒนาของคุณทำงานร่วมกันได้อย่างมี ประสิทธิภาพสูงสุด หรือไม่?

Apidog ตอบสนองทุกความต้องการของคุณ และ แทนที่ Postman ได้ในราคาที่ย่อมเยาลงมาก!
ปุ่ม

ทำไมต้องเลือก GraphQL และ Apollo Server?

ก่อนที่เราจะเริ่มลงมือทำ มาพูดคุยกันว่าทำไม GraphQL และ Apollo Server ถึงเป็นคู่หูที่ทรงพลัง GraphQL ซึ่งพัฒนาโดย Facebook ในปี 2012 และเปิดเป็นโอเพนซอร์สในปี 2015 เป็นภาษา Query สำหรับ API ที่ช่วยให้ไคลเอนต์สามารถร้องขอข้อมูลที่ต้องการได้อย่างเฉพาะเจาะจง ลดปัญหาการดึงข้อมูลมากเกินไป (over-fetching) และน้อยเกินไป (under-fetching) ที่พบบ่อยใน REST APIs แทนที่จะมีหลาย Endpoint คุณจะมี Endpoint อัจฉริยะเพียงจุดเดียวที่ให้บริการการตอบสนองที่ปรับแต่งได้ มันมีประสิทธิภาพ ยืดหยุ่น และเหมาะสำหรับแอปพลิเคชันสมัยใหม่ที่มีความต้องการข้อมูลที่ซับซ้อน

มาถึง Apollo Server ซึ่งเป็นเซิร์ฟเวอร์ GraphQL แบบโอเพนซอร์สที่ขับเคลื่อนโดยชุมชนจาก Apollo GraphQL มันพร้อมใช้งานสำหรับการผลิต รองรับ Node.js และผสานรวมกับฐานข้อมูลได้อย่างราบรื่น เช่น MongoDB หรือ PostgreSQL ด้วยคุณสมบัติเช่น schema stitching, caching และ real-time subscriptions ทำให้เป็นโซลูชันครบวงจรสำหรับการสร้าง API ที่ปรับขนาดได้ นอกจากนี้ยังเป็นมิตรกับผู้เริ่มต้นแต่ทรงพลังสำหรับมืออาชีพ เมื่อเทียบกับทางเลือกอื่นเช่น Express-GraphQL, Apollo Server ให้การตรวจสอบประสิทธิภาพที่ดีกว่าและตั้งค่าได้ง่ายกว่า หากคุณกำลังสร้างบล็อก, เว็บไซต์อีคอมเมิร์ซ หรือแบ็กเอนด์สำหรับมือถือ การผสมผสานนี้จะช่วยประหยัดเวลาและลดปัญหาให้คุณได้ ตื่นเต้นไหม? มาตั้งค่าโปรเจกต์ของเรากันเถอะ!

การตั้งค่าโปรเจกต์ของคุณใน JavaScript หรือ TypeScript

มาเริ่มต้นด้วยการสร้างรากฐานกัน เราจะตั้งค่าโปรเจกต์ Node.js และติดตั้งแพ็กเกจที่จำเป็น คุณสามารถเลือก JavaScript เพื่อความเรียบง่าย หรือ TypeScript เพื่อ Type Safety—ทั้งสองอย่างทำงานได้ดีกับ Apollo Server

ขั้นตอนที่ 1: เริ่มต้นโปรเจกต์

สร้างโฟลเดอร์ใหม่:

mkdir graphql-apollo-server
cd graphql-apollo-server

เริ่มต้น Node.js:

npm init -y
npm pkg set type="module"

ขั้นตอนที่ 2: ติดตั้ง Dependencies

Apollo Server ต้องการสองแพ็กเกจหลัก: @apollo/server สำหรับเซิร์ฟเวอร์ และ graphql สำหรับไลบรารี GraphQL หลัก สำหรับ TypeScript เราจะเพิ่ม Types และ Build Step

ติดตั้ง Dependencies:

npm install @apollo/server graphql

สำหรับ JavaScript:

เพียงแทนที่รายการ scripts เริ่มต้นในไฟล์ package.json ของคุณด้วยรายการ type และ scripts เหล่านี้:

{
	// ...etc.
	"type": "module",
    "scripts": {
    	"start": "node index.js"
    }
    // other dependencies
}

สำหรับ TypeScript (แนะนำ):

1. เริ่มต้น TypeScript:

npm install --save-dev typescript @types/node
{
  "compilerOptions": {
    "rootDirs": ["src"],
    "outDir": "dist",
    "lib": ["es2023"],
    "target": "es2023",
    "module": "esnext",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "types": ["node"]
  }
}

2. สุดท้าย แทนที่รายการ scripts ในไฟล์ package.json ของคุณด้วยรายการ type และ scripts ต่อไปนี้:

{
	// ...etc.
    "type": "module",
    "scripts": {
    	"compile": "tsc",
    	"start": "npm run compile && node ./dist/index.js"
    }
	// other dependencies
}
package.json

เคล็ดลับ: หากคุณยังใหม่กับ TypeScript มันจะเพิ่ม Type Safety ให้กับ Schema และ Resolvers ของคุณ ช่วยให้ตรวจจับข้อผิดพลาดได้ตั้งแต่เนิ่นๆ JavaScript เร็วกว่าสำหรับ Prototype—เลือกตามขนาดโปรเจกต์ของคุณ

ขั้นตอนที่ 3: สร้างไฟล์เซิร์ฟเวอร์

สร้างโฟลเดอร์ src ใน Root ของโปรเจกต์ของคุณ และเพิ่มไฟล์ index.ts (หรือ index.js สำหรับ JavaScript) ในโฟลเดอร์ใหม่นี้ นี่คือที่ที่เราจะกำหนด Schema และ Resolvers

project structure

การทดสอบ Query แบบง่าย

มาสร้าง Query แรกของเรากัน—ข้อความ "hello" แบบง่ายๆ สิ่งนี้จะแนะนำ Type Definitions (Schema) และ Resolvers (ฟังก์ชันที่ดึงข้อมูล) ของ GraphQL

กำหนด GraphQL Schema

Schema คือพิมพ์เขียวของ API ของคุณ ใช้ Tag gql จาก graphql-tag (รวมอยู่ใน `@apollo/server`) เพื่อกำหนดมัน

ใน index.ts (หรือ index.js):

import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';


// Define GraphQL schema
const typeDefs = `
  type Query {
    hello: String
  }
`;

// Define resolvers
const resolvers = {
  Query: {
    hello: () => "Hello! Welcome to my server",
  },
};

// Create and start the server
const server = new ApolloServer({ typeDefs, resolvers });

const { url } = await startStandaloneServer(server, {
  listen: { port: 4000 },
});

console.log(`🚀  Server ready at: ${url}`);

สำหรับ JavaScript, นำเข้า Types:

const { ApolloServer } = '@apollo/server';
const { startStandaloneServer } = '@apollo/server/standalone';

// Rest is the same

รันเซิร์ฟเวอร์

เริ่มเซิร์ฟเวอร์ของคุณ:

node index.js  # For JavaScript
npm start  # For TypeScript

เยี่ยมชม http://localhost:4000 ในเบราว์เซอร์ของคุณ คุณจะเห็น GraphQL Playground—IDE บนเว็บสำหรับทดสอบ Queries

the playground

ทดสอบ Query

ใน Playground ให้รัน Query นี้บนแผงด้านซ้าย:

query {
  hello
}

คลิก "Execute" ที่ด้านขวา คุณจะเห็น:

{
  "data": {
    "hello": "Hello! Welcome to my server"
  }
}
sample graphql query

สำเร็จ! Query แบบง่ายนี้แสดงให้เห็นพื้นฐานของ GraphQL: Type Query ที่มีฟิลด์ hello คืนค่าเป็น String Resolvers คือ "สมอง" ที่ให้ข้อมูล—ในกรณีนี้คือข้อความคงที่ นี่เป็นจุดเริ่มต้นที่ดีในการยืนยันการตั้งค่าของคุณ

การทดสอบ Query ด้วย Type ที่ซับซ้อน

ตอนนี้ มาเพิ่มความซับซ้อนด้วย Custom Type กัน เราจะสร้าง Type Book และ Query เพื่อดึงรายการหนังสือ สิ่งนี้แสดงให้เห็นว่า GraphQL จัดการข้อมูลที่มีโครงสร้างอย่างไร

อัปเดต Schema

แก้ไข typeDefs เพื่อรวม Type Book:

const typeDefs = gql`
  type Book {
    title: String
    author: String
  }

  type Query {
    books: [Book]
  }
`;

เพิ่มข้อมูลตัวอย่าง

ใต้ typeDefs ให้เพิ่มข้อมูลตัวอย่างต่อไปนี้สำหรับ Type Book ใหม่ของเรา:

// Sample data
const books = [
  {
    title: 'The Awakening',
    author: 'Kate Chopin',
  },
  {
    title: 'City of Glass',
    author: 'Paul Auster',
  },
];

อัปเดต Resolvers

แทนที่เนื้อหา Resolver ด้วยสิ่งต่อไปนี้สำหรับ Type books:

const resolvers = {
  Query: {
    books: () => books
  }
};

รีสตาร์ทเซิร์ฟเวอร์และกลับไปที่ Playground

ทดสอบ Query

รัน:

query GetBooks {
  books {
    title
    author
  }
}

ผลลัพธ์:

{
  "data": {
    "books": [
      {
        "title": "The Awakening",
        "author": "Kate Chopin"
      },
      {
        "title": "City of Glass",
        "author": "Paul Auster"
      }
    ]
  }
}

เจ๋งใช่ไหม? Query นี้ดึงอาร์เรย์ของออบเจกต์ Book GraphQL ช่วยให้ไคลเอนต์ระบุได้อย่างแม่นยำว่าต้องการฟิลด์ใดบ้าง—ไม่มากไม่น้อยไปกว่านั้น หากคุณละเว้น author มันจะคืนค่าเฉพาะชื่อเรื่องเท่านั้น ความยืดหยุ่นนี้คือเหตุผลที่ GraphQL เหนือกว่า REST สำหรับแอปพลิเคชันที่ต้องจัดการข้อมูลจำนวนมาก

testing a more complicated query

การทดสอบ Mutation เพื่อเพิ่มข้อมูล

Queries ใช้สำหรับการอ่าน แต่ Mutations ใช้สำหรับการเขียน มาเพิ่ม Mutation เพื่อสร้างหนังสือใหม่ ซึ่งแสดงให้เห็นว่า GraphQL จัดการการสร้างข้อมูลอย่างไร

อัปเดต Schema

เพิ่ม Type Mutation:

const typeDefs = `
  type Book {
    title: String
    author: String
  }

  type Query {
    books: [Book]
  }

  type Mutation {
    createBook(title: String!, author: String!): Book
  }
`;

! หมายถึงฟิลด์ที่จำเป็น

อัปเดต Resolvers

const resolvers = {
  Query: {
    books: () => books,
  },
  Mutation: {
    createBook: (_: any, { title, author }: { title: string; author: string }) => {
      const newBook = { title, author };
      books.push(newBook);
      return newBook;
    }
  }  
};

ทดสอบ Mutation

ใน Playground ให้รัน:

mutation CreateBook{
  createBook(title: "Harry Potter", author: "J.K Rowling") {
    author
    title
  }
}

ผลลัพธ์:

{
  "data": {
    "createBook": {
      "title": "Harry Potter",
      "author": "J.K Rowling"
    }
  }
}
test mutation

เพื่อยืนยัน ให้รัน Query GetBooks ซ้ำอีกครั้ง:

query GetBooks {
  books {
    title
    author
  }
}

ผลลัพธ์:

{
  "data": {
    "books": [
      {
        "title": "The Awakening",
        "author": "Kate Chopin"
      },
      {
        "title": "City of Glass",
        "author": "Paul Auster"
      },
      {
        "title": "Harry Potter",
        "author": "J.K Rowling"
      }
    ]
  }
}
final book added

เพิ่มหนังสือเล่มใหม่แล้ว! Mutations จะคืนค่าข้อมูลที่สร้างขึ้น ช่วยให้ไคลเอนต์ได้รับ Feedback ทันที ในสภาพแวดล้อมจริง ให้เชื่อมต่อกับฐานข้อมูลเช่น MongoDB เพื่อการเก็บข้อมูลถาวร

JavaScript vs TypeScript: ควรเลือกอะไรดี? สำหรับ Prototype ที่รวดเร็ว JavaScript ก็ใช้ได้—มี Boilerplate น้อยกว่า แต่สำหรับโปรเจกต์ขนาดใหญ่ TypeScript จะโดดเด่นด้วย Type Safety สำหรับ Schemas และ Resolvers TS ช่วยตรวจจับข้อผิดพลาดได้ตั้งแต่เนิ่นๆ ทำให้เซิร์ฟเวอร์ GraphQL ของคุณแข็งแกร่งขึ้น

การเพิ่มความซับซ้อน: ID และ Queries พร้อม Arguments

เพื่อให้เป็นจริงมากขึ้น ให้เพิ่ม ID ให้กับหนังสือ และ Query เพื่อดึงข้อมูลตามชื่อเรื่อง

อัปเดต Schema:

const typeDefs = `
    type Book {
      id: ID!
      title: String
      author: String
    }

    type Query {
      books: [Book]
      book(title: String!): Book
    }

    type Mutation {
      createBook(title: String!, author: String!): Book
    }
`;

อัปเดตข้อมูลและ Resolvers:

// Sample data
const books = [
  {
    id: 1,
    title: 'The Awakening',
    author: 'Kate Chopin',
  },
  {
    id: 2,
    title: 'City of Glass',
    author: 'Paul Auster',
  },
];

// Resolvers 
const resolvers = {
  Query: {
    books: () => books,
    book: (_: any, { title }: { title: string }) => books.find(book => book.title === title),
  },
  Mutation: {
    createBook: (_: any, { title, author }: { title: string; author: string }) => {
      const newBook = { id: books.length + 1, title, author };
      books.push(newBook);
      return newBook;
    }
  }  
};

ทดสอบ Query:

query GetBook {
  book(title: "The Awakening") {
    id
    title
    author
  }
}

ผลลัพธ์:

{
  "data": {
    "book": {
      "id": "1",
      "title": "The Awakening",
      "author": "Kate Chopin"
    }
  }
}

สิ่งนี้แสดงให้เห็น Arguments ใน Queries ช่วยให้ไคลเอนต์สามารถกรองข้อมูลได้อย่างมีประสิทธิภาพ

adding more complexity

แนวทางปฏิบัติที่ดีที่สุดสำหรับ GraphQL กับ Apollo Server

การแก้ไขปัญหาทั่วไป

บทสรุป

เราได้สร้างเซิร์ฟเวอร์ GraphQL ที่แข็งแกร่งด้วย Apollo Server ตั้งแต่ Hello Queries ไปจนถึง Mutations ไม่ว่าจะเป็นใน JS หรือ TS คุณก็พร้อมที่จะสร้าง API ที่ยืดหยุ่น ทดลอง เพิ่ม Subscriptions และ Deploy ไปยัง Heroku GraphQL และ Apollo Server คือกุญแจสู่ API ที่มีประสิทธิภาพของคุณ!

Apidog ยังรองรับการทดสอบด้วย GraphQL ดังนั้นอย่าลืมลองใช้ได้ ฟรี!

ปุ่ม
apidog image

ฝึกการออกแบบ API แบบ Design-first ใน Apidog

ค้นพบวิธีที่ง่ายขึ้นในการสร้างและใช้ API