Programming
GraphQL เนี่ย สมัยผมทำร้านเน็ตเมื่อ 20 กว่าปีก่อน (SiamCafe.net น่ะแหละ SiamCafe Blog) API มันยังไม่ซับซ้อนขนาดนี้หรอก REST ก็ถือว่าเจ๋งแล้ว แต่โลกมันเปลี่ยนไปไวไง เดี๋ยวนี้ data เยอะขึ้น app ก็ต้องการ data ที่เฉพาะเจาะจงมากขึ้น GraphQL เลยเข้ามาตอบโจทย์ตรงนี้แหละ
พูดง่ายๆ GraphQL มันคือ query language สำหรับ API และ runtime ที่ช่วย fulfill query นั้นๆ Server จะ expose GraphQL endpoint เดียว แล้ว client ก็สามารถ request data ที่ตัวเองต้องการได้เป๊ะๆ ไม่ต้องโหลดอะไรเกินจำเป็น
GraphQL คือ specification ที่ Facebook สร้างขึ้นมาเพื่อแก้ปัญหา over-fetching และ under-fetching ของ REST API สมัยก่อน ถ้าเราต้องการข้อมูลแค่ชื่อ user จาก REST endpoint เราอาจจะต้องโหลดข้อมูล user ทั้งหมดมา ซึ่งมันเกินความจำเป็น (over-fetching) หรือบางทีข้อมูลที่เราต้องการมันกระจัดกระจายอยู่ในหลาย endpoint ทำให้เราต้องเรียกหลายครั้งกว่าจะได้ข้อมูลครบ (under-fetching)
GraphQL แก้ปัญหาเหล่านี้ได้ด้วยการให้ client เป็นคนกำหนดเองว่าจะเอา data อะไรบ้างจาก server server ก็จะส่ง data กลับมาตามที่ request เท่านั้น
# GraphQL query
query {
user(id: "123") {
name
email
}
}
# GraphQL response
{
"data": {
"user": {
"name": "Kittitouch Charoenpanasit",
"email": "bom@siamcafe.net"
}
}
}
จาก code จะเห็นว่าเรา request แค่ name และ email ของ user id 123 server ก็จะส่งกลับมาแค่สอง field นี้จริงๆ
GraphQL schema คือ contract ระหว่าง client กับ server มัน define ว่า client สามารถ query data อะไรได้บ้าง และ data type ของแต่ละ field เป็นอะไร Schema จะประกอบไปด้วย type definitions และ resolvers
Type definitions คือการ define structure ของ data เช่น
type User {
id: ID!
name: String!
email: String
posts: [Post]
}
type Post {
id: ID!
title: String!
content: String
}
เครื่องหมาย ! หมายถึง field นั้น required ส่วน [Post] หมายถึง array of Post objects
Resolvers คือ function ที่ resolve data สำหรับแต่ละ field ใน schema เช่น resolver สำหรับ field name ใน type User อาจจะดึงข้อมูลจาก database หรือ external API ก็ได้
เอาแบบง่ายสุดๆ เริ่มจาก Node.js กับ Express แล้วกันนะ สมัยผมทำ SiamCafe.net ใหม่ๆ ยังไม่มีอะไร advance ขนาดนี้เลย (ฮา)
mkdir graphql-example
cd graphql-example
npm init -y
npm install express express-graphql graphql
index.js
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { buildSchema } = require('graphql');
// Define schema
const schema = buildSchema(`
type Query {
hello: String
}
`);
// Define resolver
const root = {
hello: () => 'Hello world!'
};
const app = express();
app.use('/graphql', graphqlHTTP({
schema: schema,
rootValue: root,
graphiql: true, // Enable GraphiQL UI
}));
app.listen(4000, () => console.log('Running a GraphQL API server at http://localhost:4000/graphql'));
node index.js
http://localhost:4000/graphql แล้วลอง query
query {
hello
}
แค่นี้เราก็มี GraphQL API ง่ายๆ แล้ว จริงๆ มันซับซ้อนกว่านี้เยอะ แต่เอาเป็นว่านี่คือจุดเริ่มต้นที่ดี
REST ก็ดี GraphQL ก็เจ๋ง แต่ใครเหมาะกับอะไรมากกว่ากัน? มันขึ้นอยู่กับ use case และความต้องการของ project เรา
REST เหมาะกับ API ที่ simple และ predictable resource-based API ที่ client ต้องการข้อมูลครบถ้วนจาก endpoint เดียว (หรือ endpoint ที่ predefined) REST ยังคงเป็น choice ที่ดี
GraphQL เหมาะกับ API ที่ complex และ flexible client ต้องการ data ที่เฉพาะเจาะจง และ API ที่มีการเปลี่ยนแปลงบ่อยๆ GraphQL จะช่วยลด over-fetching และ under-fetching และทำให้ client สามารถ evolve ได้ง่ายขึ้น
| Feature | REST | GraphQL |
|---|---|---|
| Data Fetching | Multiple endpoints, fixed data | Single endpoint, client-specified data |
| Over-fetching | Possible | Not possible |
| Under-fetching | Possible | Not possible |
| Flexibility | Less flexible | More flexible |
| Versioning | Required | Less required |
| Learning Curve | Lower | Higher |
ถ้าโปรเจคเรามีเงื่อนไขเหล่านี้ ลองพิจารณา GraphQL ดูนะ
GraphQL ไม่ใช่แค่ buzzword แต่มันถูกนำไปใช้จริงในหลายบริษัทใหญ่ๆ เช่น Facebook, GitHub, Shopify และอื่นๆ อีกมากมาย เหล่านี้คือตัวอย่างการใช้งาน
GitHub GraphQL API เป็นตัวอย่างที่ดีของการนำ GraphQL มาใช้ใน production GitHub เปิดให้ developer สามารถ query data เกี่ยวกับ repositories, users, issues และอื่นๆ ได้อย่าง flexible
Shopify GraphQL API ช่วยให้ developer สามารถสร้าง custom storefronts และ integrations ได้อย่างง่ายดาย โดยไม่ต้องกังวลเรื่อง over-fetching หรือ under-fetching
Facebook เองก็ใช้ GraphQL ใน mobile apps ของตัวเอง เพื่อ optimize data fetching และ improve performance
GraphQL มี learning curve ที่สูงกว่า REST นิดหน่อย เพราะต้องเข้าใจ concept ของ schema, types, resolvers แต่ถ้าเข้าใจแล้ว GraphQL จะช่วยให้ development ง่ายขึ้นเยอะ
ไม่ GraphQL ไม่ได้เหมาะกับทุกโปรเจค ถ้า API เรา simple และ resource-based REST ก็อาจจะเป็น choice ที่ดีกว่า แต่ถ้า API เรา complex และ flexible GraphQL จะเป็นตัวเลือกที่ดีกว่า
ไม่ GraphQL ไม่ได้ replace REST แต่เป็น alternative ที่ดีกว่าในบางสถานการณ์ ทั้งสองอย่างมีข้อดีข้อเสียต่างกัน และสามารถ coexist กันได้
GraphQL ปลอดภัยถ้าเรา implement security measures ที่เหมาะสม เช่น authentication, authorization และ input validation เหมือน REST เลยแหละ
หวังว่าบทความนี้จะช่วยให้เข้าใจ GraphQL มากขึ้นนะ สมัยผมทำ SiamCafe.net ก็ไม่ได้มีอะไรแบบนี้ให้ใช้หรอก ต้องเขียนเองหมด (หัวเราะ) แต่โลกมันเปลี่ยนไปแล้ว เรียนรู้ไว้ไม่เสียหาย!
SiamCafe.net — แหล่งความรู้ด้าน IT, Network, Security, Programming อันดับ 1 ของไทย ก่อตั้งตั้งแต่ปี 1997 โดย อ.บอม ผู้เชี่ยวชาญด้าน IT Infrastructure และ Forex Trading มากกว่า 25 ปี บทความทุกชิ้นเขียนจากประสบการณ์จริงในวงการ IT ประเทศไทย
ดูวิดีโอเพิ่มเติมเกี่ยวกับGraphQL คืออะไร ดีกว่า REST ยั:
สมัยผมทำร้านเน็ตฯ เคยเจอพวกชอบโหลดบิตทิ้งไว้ทั้งคืน ทำให้เน็ตคนอื่นช้าหมด GraphQL ก็เหมือนกัน ถ้า query ข้อมูลเยอะเกินไป server จะอืดได้ ต้องระวังเรื่องนี้ให้ดี
จำไว้ว่า request ที่ซับซ้อนมากๆ ควรจะแยกออกเป็นหลาย requests เล็กๆ แทน เพื่อให้ server ทำงานได้เร็วขึ้น และไม่กิน resource มากเกินไป
ถ้าข้อมูลเยอะมากๆ เช่น รายชื่อลูกค้าเป็นหมื่นเป็นแสน อย่า query มาทีเดียวหมด ให้ใช้ pagination แบ่งเป็นหน้าๆ เหมือนเวลาเราดูหน้าเว็บที่มีหลายหน้า จะช่วยลดภาระของ server และ client ได้เยอะ
query {
allCustomers(first: 10, after: "cursor123") {
edges {
node {
id
name
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
Code ตัวอย่างนี้ `first: 10` คือเราขอข้อมูลมาแค่ 10 รายการ และ `after: "cursor123"` คือเราขอข้อมูลหลังจาก cursor ที่ชื่อ "cursor123" ซึ่งเป็นตำแหน่งที่เราเคย query ไปแล้ว
GraphQL ก็เหมือน REST ที่สามารถใช้ caching ได้ ทั้งฝั่ง server และ client ถ้าข้อมูลไม่ค่อยมีการเปลี่ยนแปลง การ cache จะช่วยลดภาระของ server ได้เยอะมากๆ
สมัยก่อนตอนทำ SiamCafe.net ผมใช้ Varnish Cache ช่วย cache พวกหน้าเว็บที่คนเข้าเยอะๆ ทำให้ server ไม่ต้องทำงานหนัก
GraphQL เหมาะกับ project ที่ต้องการความยืดหยุ่นในการดึงข้อมูลมากๆ เช่น mobile app ที่ต้องดึงข้อมูลหลายอย่างจากหลาย sources หรือ project ที่ client ต้องการ control ว่าจะดึงข้อมูลอะไรบ้าง
ถ้าเคยใช้ REST มาก่อน GraphQL อาจจะดูยากนิดหน่อยในช่วงแรก แต่พอเข้าใจ concept แล้วจะรู้ว่ามันไม่ได้ยากอย่างที่คิด แถมยังช่วยให้ชีวิตง่ายขึ้นเยอะด้วย
ลองเริ่มจาก tutorial ง่ายๆ ดูก่อน แล้วค่อยๆ ศึกษาเพิ่มเติมไปเรื่อยๆ เดี๋ยวก็เก่งเอง
GraphQL เองไม่ได้มีปัญหาเรื่อง security แต่ก็ต้องระวังเรื่อง injection เหมือน REST ทั่วไป ต้อง sanitize input ให้ดี และ implement authentication/authorization ให้ถูกต้อง
เคยเจอเคสลูกค้าโดน hack เพราะไม่ได้ validate input ทำให้คนร้าย inject SQL เข้ามาได้ เรื่องพวกนี้สำคัญมากๆ
GraphQL ไม่ได้ผูกติดกับ database อะไร Database อะไรก็ได้ ขอแค่มี GraphQL server ที่สามารถดึงข้อมูลจาก database นั้นๆ มาให้ได้
GraphQL เป็น technology ที่น่าสนใจ และมีประโยชน์มากๆ สำหรับ project ที่ต้องการความยืดหยุ่นในการดึงข้อมูล แต่ก็ต้องศึกษาให้เข้าใจก่อนใช้งานจริง และอย่าลืมเรื่อง security ด้วย
ถ้าใครสนใจเรื่อง Forex ลองดู iCafeForex ได้นะ หรือถ้าอยากอ่านบทความอื่นๆ เกี่ยวกับ IT ลองเข้าไปดูที่ SiamCafe Blog
หวังว่าบทความนี้จะเป็นประโยชน์กับทุกคนนะครับ :)