ใช้ในการขอข้อมูลจาก api โดยสามารถเลือกได้เฉพาะ field ที่ต้องการจริงๆผ่านการส่ง request เพียงครั้งเดียว
เหมาะกับงานที่ต้องการ query ข้อมูลที่ซับซ้อน แต่ในการสร้าง api สำหรับ graphql จะไม่เหมือนกับการสร้าง
REST api แบบปกติ
schema ใช้กำหนดชนิดของ field ที่ต้องการดึงข้อมูลออกมา โดยเรากำหนดชื่อ type เองได้แต่มี root type
อยู่ 3 type ได้แก่ Query, Mutation และ Subscribtion
typeDefs ระบุ type
resolver ใช้ขื่อของ typeDefs มาทำงานเป็น function
context ผ่านตัวแปรเข้าไปในฟังก์ชันของ resolver
schema
type Query { info: String! feed: [Link!]! }
type Mutation { post(url: String!, description: String!): Link! updateLink(id: ID!, url: String, description: String): Link deleteLink(id: ID!): Link }
type Link { id: ID! description: String! url: String! }
|
Query ใช้กำหนด field ที่ต้องการ
Mutation ใช้กำหนดฟังก์ชัน ตัวแปรที่ส่งเข้าไปในฟังก์ชันและ type ที่ใช้ฟังก์ชัน
type เรากำหนดขึ้นมาเองได้
index.js
const { GraphQLServer } = require('graphql-yoga') // links คือข้อมูลที่สมมติว่าเป็นข้อมูลจาก database let links = [{ id: 'link-0', url: 'www.howtographql.com', description: 'Fullstack tutorial for GraphQL' }]
let idCount = links.length const resolvers = { Query: { // info กับ feed ทำเป็นฟังก์ชันแสดงผลลัพธ์ออกมา info: () => 'This is the API of a Hackerners Clone', feed: () => links, }, Mutation: { // ใช้ args.something ตามที่กำหนดใน schema เพื่ออ่านค่า post: (root, args) => { const link = { id: `link-${idCount++}`, description: args.description, url: args.url, } links.push(link) return link }, updateLink: (root, args) => { // ชื่อ updateLink กับ post มาจาก schema const link = { id: `link-${args.id}`, description: args.description, url: args.url, } links[args.id] = link // update ค่า links return link } }, Link: { // root คือ parant node หรือ id ปัจจุบันของ link id: (root) => root.id, description: (root) => root.description, url: (root) => root.url, } }
const server = new GraphQLServer({ typeDefs: './src/schema.graphql', // path to schema resolvers, }) server.start(() => console.log(`Server is running on http://localhost:4000`))
|
ตัวอย่าง client ใช้งาน
query { field1 field2 }
mutation { method_name( parameter1: value parameter2: value ){ field1 field2 } }
|
ใช้ schemaglue ช่วยให้เราแยก schema กับ resolver ของแต่ละ business logic ออกจากกันได้
index.js ที่ใช้ schemaglue
const { ApolloServer, gql } = require('apollo-server') const glue = require('schemaglue') // This will look for any js files under the 'src/graphql' folder that // comply to a certain convention described below. Those files describe // bits and pieces of the GraphQL schema and resolver that schemaglue will // reassemble into a single 'schema' string and 'resolver' object. const options = { js: '**/*.js', // default ignore: '**/somefileyoudonotwant.js' } const { schema, resolver } = glue('graphql', options) const typeDefs = gql(schema); const resolvers = resolver;
const server = new ApolloServer({ typeDefs, resolvers })
server.listen().then(({ url }) => { console.log(`🚀 Server ready at ${url}`) })
|
ต่อมาเราสามารถแบ่งโครงสร้างของ graphql ได้เป็นดังนี้
index.js graphql |- book |-schema.graphql |- resolver.js
|
ตัวอย่างไฟล์ schema.graphql
# Comments in GraphQL are defined with the hash (#) symbol. # This "Book" type can be used in other type declarations.
type Book { title: String author: String }
# The "Query" type is the root of all GraphQL queries. # (A "Mutation" type will be covered later on.)
type Query { books: [Book] }
|
ตัวอย่างไฟล์ resolver.js
const books = [ { title: 'Harry Potter and the Chamber of Secrets', author: 'J.K. Rowling', }, { title: 'Jurassic Park', author: 'Michael Crichton', }, ] // mockup data
exports.resolver = { Query: { // can use seneca here. books: () => books, // ส่วนนี้จะเรียกใช้ query หรือเรียก microservice อื่นๆ }, }
|
ความคิดเห็น
แสดงความคิดเห็น