รู้จักกับ GraphQL อีกแนวทางการออกแบบ Web Services

Natcha Luangaroonchai
1 min readDec 2, 2016

--

โลกของการพัฒนาโปรแกรมในยุคนี้คงจะเป็นอะไรไปไม่ได้นอกจากแนวทางของ APIs First และถ้าต้องสร้าง Web Services ขึ้นมาสักตัวแล้วเราคงจะต้องนึกถึง RESTful และ JSON เป็นอันดับแรก ๆ (หรือ SOAP ถ้าคุณจำเป็นต้องมี schema)

แต่วันนี้ผมจะพามาทำความรู้จักกับแนวทางการออกแบบ Web Services อีกวิธีที่จะช่วยให้ชีวิตดีขึ้น!

GraphQL เมื่อ Web Services มาบรรจบกับ Query Language

งง? อธิบายจากปัญหาก่อนถ้าใครที่ทำงานกับ RESTful มานาน ๆ จะพบว่าการออกแบบ Request และ Response เป็นเรื่องยุ่งยากเพราะมันไม่ได้มี schema ตรงกลางมาคอยช่วยกำหนดรูปแบบหรือถ้าจะยึดกับมาตรฐานสักที่ (ที่ผมใช้คือ http://jsonapi.org) ก็ต้องมาทำความเข้าใจและมันเป็นไปไม่ได้ที่ทุกมาตรฐานจะเหมาะกับงานของเราทำให้ต้องมากำหนดมาตรฐานกันด้วยเอกสารยาวหลายหน้า

มันจะดีกว่าไหม? ถ้ามาตรฐานมันถูกกำหนดในโปรแกรมมาตั้งแต่ต้น (หลายคนบอก SOAP ไง หรือจะใช้ gRPC ก็ได้น่ะ /แต่ผมจะทำงานกับ JSON อ่ะ) เมื่อความต้องการออกมาเป็นแบบนี้เลยมีคนสร้างสิ่งที่เรียกว่า GraphQL ออกมา

ผู้สร้าง GraphQL ก็ไม่ใช่ใครที่ไหน Facebook นั่นเอง http://graphql.org/ และยังใช้กับผลิตภัณฑ์ของตัวเองมาตั้งแต่ปี 2012 แล้วด้วย!

หลักการของ GraphQL คือเราต้องกำหนด schema ของข้อมูลที่จะใช้คุยกันระหว่าง client กับ server รวมไปถึงกำหนดวิธีการ query ข้อมูลด้วย query? ใช่แล้ว GraphQL มีลักษณะคล้ายกับการ query ข้อมูลจากฐานข้อมูลที่คุ้นเคยกันดี เพียงแต่มันไม่ได้ไปยุ่งกับ business logic เจ้า GraphQL ทำหน้าที่เป็นเพียงแค่ตัวกลางคอยแปลสิ่งที่ client ส่งเข้ามาและ format สิ่งที่จะส่งออกไปจากระบบของเรา คล้าย ๆ กับคนกลางที่ช่วยจัดการเรื่องข้อมูลนั่นแหละ

เนื่องจากบทความเรื่องนี้อาจจะยาวหลายตอนดังนั้นเรามาค่อย ๆ เรียนรู้ไปพร้อม ๆ กัน ผมจะเริ่มจากการเขียน service แรกแบบง่าย ๆ ด้วย “Hello, world!”

ในตัวอย่างผมได้สร้าง query ที่ชื่อว่า HelloWorld (บรรทัดที่ 11) จากนั้นประกาศฟิลด์ชื่อว่า hello และสร้าง resolver ฟังก์ชันสำหรับส่งคำว่า “world!” เมื่อมีการเรียก service เข้ามา ทดลองเรียก service ด้วย cURL แบบนี้

$ curl -XPOST \
-H "Content-Type: application/graphql"
-d "{ hello }"
http://localhost:8080/graphql

จะได้ผลลัพธ์ออกมาแบบนี้

{
"data": {
"hello": "world!"
}
}

ผลลัพธ์จะอยู่ในรูปแบบ JSON แต่ถ้าสังเกตุตอนเรียกจะพบว่า syntax มันไม่ใช่ JSON แต่เป็น format ของ “application/graphql” โดยเฉพาะ จะเกิดอะไรขึ้นถ้าเราเผลอส่ง header เป็น JSON ไปแทน? ก็จะได้ error แบบนี้เพราะ GraphQL ไม่รู้จัก input แบบ JSON

{
"data": null,
"errors": [{
"message": "Must provide an operation.",
"locations": []
}]
}

ตอนหน้าเราจะมาต่อกันที่วิธีการสร้าง query ประเภทต่าง ๆ กัน

--

--