แนวทางการใช้งาน GraphQL
GraphQL เป็นภาษาสำหรับการติดต่อสื่อสารกับ API ที่เรียกว่า “query language” ซึ่งช่วยให้ผู้ใช้สามารถระบุข้อมูลที่ต้องการและรับข้อมูลเฉพาะที่ต้องการกลับมาจาก API ได้อย่างมีประสิทธิภาพมากขึ้น ในบทความนี้เราจะพูดถึงแนวทางการใช้งาน GraphQL ในการพัฒนาแอปพลิเคชันและเว็บไซต์
- สร้าง schema เริ่มต้นด้วยการสร้าง schema ซึ่งเป็นการกำหนดรูปแบบของข้อมูลที่ API ของเราจะให้ผู้ใช้สามารถเรียกข้อมูลได้ โดย schema ประกอบด้วย type ต่างๆ ที่อธิบายลักษณะของข้อมูล เช่น type Query ที่ใช้สำหรับการเรียกข้อมูล และ type Mutation ที่ใช้สำหรับการเปลี่ยนแปลงข้อมูล
- สร้าง resolver ต่อมาเราจะต้องสร้าง resolver ซึ่งเป็นฟังก์ชันที่ใช้ในการดึงข้อมูลจากแหล่งข้อมูลต่างๆ เช่นฐานข้อมูล และส่งกลับข้อมูลเป็นตามที่ผู้ใช้ร้องขอใน query ในการสร้าง resolver เราสามารถใช้ภาษา JavaScript, Python, Ruby หรือภาษาอื่นๆ ก็ได้
- สร้าง query และ mutation หลังจากสร้าง schema และ resolver เสร็จแล้ว เราจะสร้าง query และ mutation ที่ใช้ในการร้องขอข้อมูล โดย query ใช้สำหรับการร้องขอข้อมูลเพื่อดึงค่า ส่วน mutation ใช้สำหรับการเปลี่ยนแปลงข้อมูล เช่นการเพิ่ม การลบ หรือการแก้ไขข้อมูล
- ทดสอบการใช้งาน เมื่อเราได้สร้าง schema, resolver, query และ mutation เสร็จแล้ว เราจะต้องทดสอบการใช้งาน API ของเราว่าสามารถทำงานได้อย่างถูกต้องหรือไม่ สามารถใช้งาน GraphiQL ที่เป็นเครื่องมือสำหรับทดสอบ GraphQL API ได้ โดย GraphiQL จะช่วยให้เราสามารถเรียก query และ mutation ได้อย่างง่ายดาย และดูผลลัพธ์ที่ได้กลับมาได้
- การใช้งานในแอปพลิเคชัน เมื่อเราได้ทดสอบและตรวจสอบ API ของเราแล้ว ต่อไปเราสามารถนำ GraphQL API ไปใช้งานในแอปพลิเคชันหรือเว็บไซต์ของเราได้ โดยใช้ไลบรารีหรือโมดูลที่เป็น GraphQL client เพื่อให้สามารถส่ง query และ mutation ไปยัง API ของเราได้อย่างง่ายดาย ซึ่งในปัจจุบันมีไลบรารีหลายรูปแบบที่สามารถใช้งานได้ เช่น Apollo Client หรือ Relay
- การจัดการ error ในกรณีที่เกิด error ในการใช้งาน GraphQL API เราจะต้องจัดการ error ด้วยการส่ง error response กลับไปยังผู้ใช้ โดย GraphQL มีรูปแบบการจัดการ error ที่เป็นไปอย่างมีประสิทธิภาพ เราสามารถกำหนด error code และ error message ต่างๆ ได้ในการส่งกลับ response ซึ่งจะช่วยให้ผู้ใช้งานสามารถแก้ไขปัญหาได้อย่างรวดเร็ว
- การปรับปรุงและเพิ่มเติม schema เมื่อเราได้เริ่มการใช้งาน GraphQL API แล้ว เราอาจต้องการปรับปรุงหรือเพิ่มเติม schema เพื่อรองรับการใช้งานที่หลากหลายมากยิ่งขึ้น ในกรณีนี้ เราจะต้องอัปเดต resolver และทำการทดสอบเพื่อตรวจสอบว่าการปรับปรุงหรือเพิ่มเติม schema นั้นสามารถทำงานได้อย่างถูกต้องหรือไม่
- การเลือกใช้งานไลบรารีและเครื่องมือต่างๆ ในการพัฒนา GraphQL API เราสามารถเลือกใช้งานไลบรารีและเครื่องมือต่างๆ ได้ตามความต้องการของโปรเจกต์ หรือขึ้นอยู่กับว่าเราต้องการสร้าง API แบบไหน เช่นถ้าเราต้องการสร้าง API สำหรับ mobile application แล้ว Apollo Client อาจจะเหมาะสมกับการใช้งาน เนื่องจากมีการจัดการ caching และเพิ่มประสิทธิภาพในการใช้งานของ mobile application ในขณะที่ถ้าเราต้องการสร้าง API สำหรับเว็บไซต์หรือเว็บแอปพลิเคชัน แล้ว Relay อาจจะเหมาะสมกับการใช้งาน เนื่องจากมีความสามารถในการจัดการข้อมูลในหน้าเว็บไซต์ได้ดีกว่า
- การตรวจสอบความปลอดภัย เมื่อเราสร้าง GraphQL API แล้ว เราจะต้องให้ความสำคัญกับความปลอดภัยของ API เพื่อป้องกันการโจมตีและการแอบแฝงของข้อมูล ดังนั้น เราควรตั้งค่าการใช้งาน GraphQL API ให้มีการตรวจสอบความปลอดภัยอย่างเหมาะสม เช่นการกำหนดสิทธิ์การเข้าถึงข้อมูลให้เหมาะสม การใช้งาน SSL เพื่อป้องกันการถูกแอบดักจับข้อมูล และการเข้ารหัสข้อมูลเป็นต้น
- การจัดการกับ error และการ logging การจัดการ error และการ logging เป็นสิ่งที่สำคัญในการพัฒนา GraphQL API เพื่อช่วยให้เราสามารถตรวจสอบข้อผิดพลาดได้อย่างรวดเร็วและช่วยให้เราแก้ไขปัญหาได้อย่างตรงไปตรงมา นอกจากนี้ เรายังสามารถ logging และตรวจสอบ performance ของ GraphQL API เพื่อช่วยให้เราปรับปรุงประสิทธิภาพการทำงานของ API ได้อย่างสม่ำเสมอ
นี่คือ 10 ข้อสำคัญที่ควรรู้เมื่อพัฒนา GraphQL API ซึ่งสามารถช่วยให้เราสร้าง API ได้อย่างมีประสิทธิภาพและง่ายต่อการบำรุงรักษา ในกรณีที่เราต้องการเรียนรู้เพิ่มเติมเกี่ยวกับ GraphQL สามารถเรียนรู้ได้จากเอกสารอย่างเช่น GraphQL Documentation หรือเรียนรู้จากคอร์สออนไลน์และหนังสือที่เกี่ยวข้องกับ GraphQL ได้เช่นกัน
ตัวอย่างการใช้งาน Graphql กับ apollo
Apollo เป็น library สำหรับเชื่อมต่อและใช้งาน GraphQL ในแอพพลิเคชั่นต่าง ๆ ซึ่งสามารถใช้งานได้กับหลาย platform เช่น React, Angular, Vue, iOS, Android และอื่น ๆ
ตัวอย่างการใช้งาน GraphQL กับ Apollo สามารถอธิบายได้ดังนี้
- การติดตั้ง Apollo Client เราสามารถติดตั้ง Apollo Client ได้โดยใช้ npm ดังนี้
npm install @apollo/client
- การสร้าง GraphQL Query เราสามารถสร้าง GraphQL query โดยใช้
gql
ที่ได้รับจาก@apollo/client
library แล้วเรียกใช้งานโดยใช้useQuery
hook ดังนี้
import { gql, useQuery } from '@apollo/client';
const GET_BOOKS = gql`
query GetBooks {
books {
id
title
author
}
}
`;
function BookList() {
const { loading, error, data } = useQuery(GET_BOOKS);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;
return (
<ul>
{data.books.map((book) => (
<li key={book.id}>
{book.title} by {book.author}
</li>
))}
</ul>
);
}
- การสร้าง GraphQL Mutation เราสามารถสร้าง GraphQL mutation โดยใช้
useMutation
hook ดังนี้
import { gql, useMutation } from '@apollo/client';
const ADD_BOOK = gql`
mutation AddBook($title: String!, $author: String!) {
addBook(title: $title, author: $author) {
id
title
author
}
}
`;
function AddBookForm() {
const [title, setTitle] = useState('');
const [author, setAuthor] = useState('');
const [addBook, { data }] = useMutation(ADD_BOOK);
const handleSubmit = (event) => {
event.preventDefault();
addBook({ variables: { title, author } });
setTitle('');
setAuthor('');
};
return (
<form onSubmit={handleSubmit}>
<label>
Title:
<input type="text" value={title} onChange={(e) => setTitle(e.target.value)} />
</label>
<label>
Author:
<input type="text" value={author} onChange={(e) => setAuthor(e.target.value)} />
</label>
<button type="submit">Add Book</button>
</form>
);
}
- การกำหนดค่า client ของ Apollo เราสามารถกำหนดค่า client ของ Apollo ได้ด้วย
ApolloClient
ตามตัวอย่างนี้
import { ApolloClient, InMemoryCache } from '@apollo/client';
const client = new ApolloClient({
uri: 'https://example.com/graphql',
cache: new InMemoryCache()
});
ในตัวอย่างนี้เราสร้าง client ของ Apollo โดยกำหนด uri
เป็น endpoint ของ GraphQL server และใช้ InMemoryCache
เป็น cache สำหรับการจัดการข้อมูลที่ได้รับจาก server
- การใช้งาน ApolloProvider เราสามารถใช้
ApolloProvider
เพื่อทำให้ component ในตัวอย่างที่แล้วสามารถเข้าถึง client ของ Apollo ได้ ดังนี้
import { ApolloProvider } from '@apollo/client';
function App() {
return (
<ApolloProvider client={client}>
<BookList />
<AddBookForm />
</ApolloProvider>
);
}
ในตัวอย่างนี้เราใช้ ApolloProvider
ในการ wrap component ที่ต้องการเข้าถึง client ของ Apollo ซึ่งเป็น BookList
และ AddBookForm
โดยใช้ client
ที่เราได้กำหนดไว้ในข้อ 4
- การใช้งาน Subscription Apollo ยังสามารถใช้งาน Subscription ได้เช่นกัน ดังนี้
import { gql, useSubscription } from '@apollo/client';
const NEW_BOOKS = gql`
subscription {
newBooks {
id
title
author
}
}
`;
function NewBookList() {
const { loading, error, data } = useSubscription(NEW_BOOKS);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;
return (
<ul>
{data.newBooks.map((book) => (
<li key={book.id}>
{book.title} by {book.author}
</li>
))}
</ul>
);
}
ในตัวอย่างนี้เราใช้ useSubscription
hook ในการสร้าง Subscription สำหรับการติดตามการเพิ่มหนังสือใหม่ โดยเมื่อมีการเพิ่มหนังสือใหม่ server จะส่งข้อมูลใหม่ไปยัง client โดยอัตโนมัติและ component NewBookList
จะถูกอัพเดทข้อมูลใหม่ทัน
- การใช้งาน Cache Apollo ยังมี Cache สำหรับจัดการข้อมูลที่ได้รับจาก server เพื่อลดการเรียกข้อมูลซ้ำๆ ดังนี้
import { gql, useQuery } from '@apollo/client';
const ALL_BOOKS = gql`
query {
books {
id
title
author
}
}
`;
function BookList() {
const { loading, error, data } = useQuery(ALL_BOOKS);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;
return (
<ul>
{data.books.map((book) => (
<li key={book.id}>
{book.title} by {book.author}
</li>
))}
</ul>
);
}
ในตัวอย่างนี้เราใช้ useQuery
hook ในการเรียกข้อมูลหนังสือจาก server และสร้าง component BookList
ที่แสดงรายการหนังสือทั้งหมด แต่ถ้ามีการเรียกข้อมูลซ้ำกัน Apollo จะเก็บข้อมูลที่ได้รับจาก server ไว้ใน Cache เพื่อใช้ในการแสดงผลข้อมูลต่อไป
สรุปท้ายบทความ
การใช้งาน GraphQL กับ Apollo คือวิธีที่ง่ายและมีประสิทธิภาพในการสร้างแอปพลิเคชันในส่วนของ client โดยเราสามารถใช้งานได้ง่ายผ่าน Library ของ Apollo ที่มี API ที่ใช้งานง่ายและเหมาะสมกับการเรียกข้อมูลแบบ Asynchronous และ Subscription ด้วย Cache ที่ช่วยลดการเรียกข้อมูลซ้ำซ้อนในการแสดงผลข้อมูลให้เร็วขึ้น