แนะนำการใช้ GraphQL เบื้องต้น



ใช้ในการขอข้อมูลจาก 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 อื่นๆ
  },
}



ความคิดเห็น