Memo #1.2: Graphql part 2
ลองเล่น Graphql บน Graph.cool กัน
บทนำ (You can skip this)
มาถึง Memo ที่สองครับต่อจาก Memo เดิมครับ ก็จะพยายามปรับปรุงจาก Memo ก่อนหน้าครับ ทั้งเรื่องการย่อหน้า และภาพประกอบครับ
สรุป Graphql part 1
Graphql สรุปสั้นๆแล้วก็คือ API ที่อิงหลักการ Declarative หรือจะบอกว่าเป็น Declarative API ตัวหนึงก็ว่าได้ครับ โดยผู้ใช้เพียงแค่บอกว่าต้องการข้อมูลใดบ้าง เดี๋ยว API จะตอบกลับมาให้เอง โดยการจะตอบกลับมาได้นั้นเราต้องไป Define ไว้ก่อนว่ามี Schema อย่างไร จะตอบกลับอย่างไรได้บ้าง
มาลองเล่น Graphql tool กันดีกว่า
ก่อนอื่นเลย ถ้าเริ่มลองเขียน Graph API กันก่อนเลยน่าจะทำให้หลายๆคนงงและไม่เข้าใจกันได้ งั้นก่อนที่เราจะเข้าใจและรู้จักมันไปมากกว่านี้ลองมาเล่นกันแบบไม่ต้องเข้าใจอะไรกันก่อนดีกว่าครับ มีเว็บที่สำหรับสร้างและลองเล่นอยู่ครับ ซึ่งน่าสนใจมาก ผมขอแนะนำ Graph.cool ครับ
เอ๊ะ! มีคำว่า Schema
ใช่ครับ เวลาเราใช้ Graphql เราจะคุยกันด้วย Schema เจ้าตัวนี้เองจะเป็นตัวบอกว่ามีข้อมูลอะไรบ้างที่เราสามารถร้องขอได้ แล้วถ้าเราร้องขอไปจะตอบกลับมาเป็นข้อมูลประเภทอะไร ผมลองสร้าง Object Type Post และ Comment ใน Graph.cool ดูครับ

มาลองเล่น Graph.cool กัน
หลังจากเพิ่มข้อมูล Object Type ทั้งสองแล้วมาลองเล่น Play ground เพื่อเพิ่มความเข้าใจกันครับ อันดับแรงเลยเมื่อเราเข้าไปแล้วจะพบว่ามี Tool ให้ลอง Query ข้อมูลจาก Graph API กันนะครับ แถมมี DOCS ด้านขวาเพื่อบอกว่า Schema เรามี Type และ Fields อะไรบ้างใน Schema นี้ครับ โดยในที่นี้ Fields ต่างๆ Graph.cool จะสร้างให้ทันทีเมื่อเราสร้าง Object Type ใหม่

Type และ Fields ใน Schema
Type ในที่นี้จะพูดถึง Query และ Mutation โดยมันจะค่อนข้างตรงตัว
Query Type
Query มีไว้สำหรับการขอข้อมูล ซึ้งก็จะประกอบไปด้วย Fields ต่างๆโดย Fields เหล่านี้ก็ถูกสร้างขึ้นมาเพื่อ Resolve ข้อมูลออกมาตาม Type ต่างๆ เช่น String Int array เป็นต้นรวมถึง Object Type ที่เราสร้างขึ้นมาเองด้วย ซึ่ง Fields เหล่านี้สามารถรับ Arguments ได้ด้วยเพื่อเป็นการเลือกข้อมูลที่ต้องการนั้นแหละครับเช่น Fields allComments สามารถรับ first เป็น Int เพื่อบอกได้ว่าเราต้องการกี่คอมเม้นแรกนั้นเองครับ
Mutation Type
Mutation มีไว้สำหรับการเปลี่ยนแปลงข้อมูล(เพิ่ม ลบ แก้ไข) ซึ่งก็ประกอบไปด้วย Fields ต่างๆเหมือนกับ Query แต่ Fields ของ Mutation นั้นมักจะ Require Arguments เพื่อบอกว่าเราต้องการเปลี่ยนแปลงข้อมูลอะไร และเปลี่ยนเป็นอะไร(คงไม่มีใครทำแบบ Delete All ไม่ต้องส่งอะไรเข้าไปแค่ลบทิ้งให้หมดใช่ไหมครับ)
จริงๆเราสามารถใช้ทั้งสอง Type นี้สลับกันหรือแบบใดก็ได้ครับ แต่มันจะมีผลต่อความเข้าใจของคนที่มาใช้ API หรือเปล่าครับ เหมือนเราขอข้อมูลจาก REST API แต่ใช้ Method DELETE แล้วลบข้อมูลใช้ GET แค่คิดก็งงแล้วครับ
มาลอง Query กัน
การ Query ง่ายมากครับ เราสามารถใส่คำว่า query ไว้หรือไม่ไว้ข้างหน้าปีกกาก็ได้ครับ การที่เราใส่ query ไว้ข้างหน้าจะเป็นการบอกว่า Fields ข้างในปีกกานั้นเป็นของ Type ไหนนั้งเองครับ แต่ถ้าเราไม่ใส่ค่าเริ่มต้นจะเป็น Query ครับ

ในบรรทัดแรกเราจะบอกว่า เราต้องการทำอะไรคือ Query หรือ Mutation ครับ ในกรณีไม่ใส่ก็หมายถึง Query นั้นเองครับ ในบรรทัดที่ 2 ก็จะ Fields ว่าต้องการข้อมูลจาก Fields ไหนครับ และในที่นี้ผมใส่ Argument first ไปด้วยครับ ว่าต้องการแค่ตัวแรกนะ ต่อมาใน Fields เองก็สามารถมี Sub Fields ได้ครับ ทีนี้ post ที่ได้มาผมต้องการแค่ content กับ comments ทั้งหมดครับ ในแต่ละ comment ผมต้องการแค่ message ครับ นี่คือทั้งหมดของที่ Query ไปครับ
จะสังเกตุได้ว่ามันคล้ายกับ JSON มากต่างกันแค่ไม่มี value, colon และสามารถใส่วงเล็บคล้ายๆ Function เพื่อรับ Argument ได้ถ้าไม่ต้องการใส่ Argument ก็ไม่ต้องใส่วงเล็บครับ เหมือนกับ comments ในบรรทัดที่ 4 ครับ
สิ่งที่ตอบกลับมาจะเป็น JSON ธรรมดาครับ สังเกตุไหมว่าหน้าตาคล้ายกับที่เราร้องขอไปเลยครับ เพิ่มเติมคือ value ครับ
ใช้ Variables กันเถอะ
หลังจากที่เราลอง Query กันไปแล้วครับ จะเห็นว่าเราสามารถใส่ Arguments ลงไปได้ใช่ไหมครับ แต่การใส่ลงไปใน Query ตรงๆแบบนี้สำหรับผมแล้วดูไม่ค่อยยืดหยุ่นเลยนะครับ ยิ่งถ้าเราเก็บชุดๆ Query นี้เป็น String แล้วเราต้องการใช้ Query ตัวนี้แหละครับ แต่เราต้องเปลี่ยน value ของ Arguments เราต้องมาแก้ String ชุดนี้หรอครับ(แค่ตัวอย่างสมมุติให้ดูน่าใช้นะครับ) เรามีวิธีที่ง่ายกว่าครับ ก็แยกมันออกมาเป็น Variables สิครับ

สังเกตุว่ามันก็จะคล้ายๆของเดิมเลยครับ ที่เพิ่มมาคือเราต้องใส่ Type ด้านหน้าครับอันนี้บังคับแล้ว แล้วก็ต้องมีชื่อ Query ครับ ตามด้วย Variables ในวงเล็บและ Type ของมันนั้นเองครับ ต่อมา allPosts ของเราแทนที่จะใส่ value ไปตรงๆก็จะใส่เป็น Variables ของเราแทนครับ ส่วน value นั้นจะไปใส่ใน Query variables ด้านล่างแทนครับ สังเกตุว่าส่งไปในรูปแบบ JSON เลยครับ และสุดท้ายก็ตอบกลับมาเป็น JSON เหมือนเดิมครับ
มาใช้ Fragment กันต่อเถอะ
หลังจากใช้ Variables แล้วก็จะพาใช้ Fragment กันต่อครับ แล้วถ้าที่เรา Query มันมี Fields กับ Sub Fields ซ้ำกันเยอะๆละ Query มันจะยาวมากเลยใช่ไหมครับ เราสามารถแยกมันออกมาเป็น Fragment ได้ครับ และจริงๆแล้วถ้าเราเก็บ Fragment นี้เป็น String ชุดหนึ่งเราสามารถนำไปใช้กับ Query อื่นได้ด้วยครับก็แค่ต่อ String เข้าไปทีนี้ Query นั้นๆก็รู้จัก Fragment นี้แล้วครับ

ก็จะต่อจากตัวอย่างเก่าเลยครับ จะเห็นว่าถ้าเราไม่แยก PostFragment ออกมา Sub Fields ในบรรทัดที่ 3 และ 6 จะต้องเขียนซ้ำกันแน่ๆ ส่วน CommentFragment ผมแค่แยกออกมาให้เห็นว่าเราสามารถใส่ Fragment ใน Fragment ได้เช่นกันครับ
Fragment นั้นจะอยู่นอก Query ครับ เราจะต้องตั้งชื่อให้ Fragment เสมอครับ และต้องบอก Type ของ Fragment ด้วย ส่วนภายใน Fragment ก็ใส่เป็น Fields ที่เราต้องการใน Type นั้นๆครับ
มาดูหน้าตา Request ที่ส่งไปกันครับ
หลังจากลองเล่นผ่านเว็บ Graph.cool มาสักพักหลายๆคน คงจะงงใช่ไหมครับ ว่าแล้วถ้าใช้จริงละจะส่ง Request ไปยังไงกัน ทีนี้ผมจะมาลองยกตัวอย่างด้วย Postman กันนะครับ(คิดว่าน่าจะดูเข้าใจง่ายสุดแล้วครับ)

ผมก็ยังคง Request ไปที่เว็บ Graph.cool เหมือนเดิมครับ จะเห็นว่าส่งไปเป็น JSON โดยมี Key query และ variables ครับ value เป็น String ธรรมดาครับ ส่วน Fragment จะรวมอยู่ใน query ต่อท้ายไปครับ
สรุปท้ายก่อนจบ Memo
สำหรับผมแล้ว Memo รอบนี้ค่อนข้างยาวช่วงหลังอาจจะเร่งไปบ้างครับ เล่าไม่จบสักทีครับ ที่ยังเหลืออยู่คงเป็น Mutation Type แล้วก็ลองเขียน Graphql ใช้การเองจริงๆสักรอบครับ ขอบคุณที่อ่านจนจบครับ