ทำไมเราถึงต้องทำ API guideline?

ตอนนี้หลาย ๆ ที่ เริ่มมีการพัฒนา API Service ไปในรูปแบบของ Microservice กันพอสมควร บ่อยครั้งที่ทีมเรามักจะรีบโดดเข้าไปลงมือทำ API ของตัวเองเลย โดยไม่ได้สนใจหรือคำนึงถึงผู้ที่จะใช้มันมากนัก สนใจเพียงแต่การคลอดฟีเจอร์ออกมาได้ให้มากที่สุด ยิ่งรูปแบบการทำงานที่เราทำเป็น Microservice แล้ว สิ่งที่เกิดระหว่างการพัฒนาคือ การเกิดปัญหาของรูปแบบการเรียกใช้งาน และ รูปแบบของหน้าตาข้อมูลกันระหว่าง API Service ที่มีหลายอย่างยังไม่ได้ตกลงกัน ซ้ำร้ายกว่าคือการที่เราได้มี API Gateway มาคั่นตรงกลางระหว่าง API Service กับ Client อาทิ Mobile หรือ Web ผลกระทบที่เกิดคืองานจะตกมาหนักที่ API Gateway ที่ต้องทำการ Reformatting หรือทำ Data conversion ออกมาให้สอดคล้องกับที่ Client ต้องการ แต่ก็ต้องไปเจอความยากอีกเพราะบางที API Service แต่ละตัว ดั๊น… มีความอินดี้ เป็นตัวของตัวเองสูง มีการกำหนดวิธีเรียกใช้งานคนละรูปแบบ หรือ มีการพ่นข้อมูลออกมาคนละรูปแบบ ไม่มีความคล้ายคลึงกันเลย

จากที่กล่าวมาว่า หนักแล้ว แต่หากซ้ำร้ายไปกว่านั้น ผลที่ตามมาจากการเพิ่งจะได้มีการตกลงกันของรูปแบบหน้าตา API ที่เราอยากให้เป็น สิ่งที่เกิดขึ้นก็คือการที่ทีมต้องกลับมาแก้สิ่งที่ตัวเองได้เขียนไปแล้ว บางครั้งแทบจะรื้อกันเลยทีเดียว บางครั้งมันส่งผลกระทบไปตั้งแต่ Service ของตัวเองไปยัง Service รอบ ๆ ด้าน หรือกระทบขึ้นไปสู่ Client ที่เรียกใช้ เรียกได้ว่าจะเกิดมหกรรมของการต้องกลับมาแก้งานเก่าโดยฟีเจอร์ใหม่เป็นหมันยาว ๆ


ที่นี้ถ้าเราลองมองย้อนไปสู่จุดเริ่มต้นของปัญหา จริง ๆ แล้วปัญหามันเกิดจากอะไร?


ใช่แล้วครับ…

เราเริ่มทำงานโดยที่ยังไม่มี การสร้างข้อตกลงร่วมกัน (Working agreement)

ทีนี้สิ่งที่เกิดขึ้นมาจากการทำข้อตกลงร่วมกันในการทำงานว่า อะไรคือสิ่งที่เราอยากให้เป็น และ อะไรคือสิ่งที่คาดหวังของพวกเราร่วมกัน นั่นก็คือ… พระเอกของบทความนี้ ตัว API guideline นั่นเองครับ

สาเหตุมันก็มาจากบ่อยครั้งที่เราคุยกันเข้าใจอย่างนึง แต่ผลลัพธ์ที่ออกมานั้นดันเป็นอีกอย่างนึง

เพราะ บ่อยครั้ง… ปัญหามันไม่ได้เกิดจากการเข้าใจผิด แต่หลายครั้งเรากำลัง “เข้าใจถูกในสิ่งที่มันผิด” ดังนั้นเราต้องทำให้เกิดภาพเดียวกัน ร่วมกัน เป้าหมายเดียวกันให้ได้ ต้องทำให้ทุกคนเห็นภาพปลายทางที่ชัดเจนไปในทางเดียวกันให้ได้ นั่นคือการที่เราต้องสร้าง API guideline ของเราขึ้นมาร่วมกัน


แล้วทีนี้ถ้าเราจะเริ่มสร้าง API guideline ของทีมบ้าง ควรให้ความสนใจในเรื่องใดบ้าง?


ถ้าจากมุมมองของผมสิ่งที่ต้องควรทำเตรียมไว้เป็น checklist ได้เลยก่อนที่จะเริ่มวาง guideline นั้น ผมจะแบ่งออกมาเป็น 3 กลุ่ม คือ เรื่องการตั้งชื่อสิ่งต่าง ๆ, การตกลงกันในเรื่องการเรียกใช้งาน และ การแสดงผลลัพธ์ให้เป็นในรูปแบบที่ตกลงกันไว้
  1. การตั้งชื่อ เป็นที่รู้ ๆ กันมาตั้งนานแล้วว่าส่วนนี้เป็นส่วนที่ยากที่สุดและหนักที่สุดของเหล่าบรรดาโปรแกรมเมอร์ ฮ่า ๆ การตั้งชื่อนั้นก็ประกอบไปด้วยการตั้งชื่อ Service ให้อ่านแล้วเข้าใจได้ รวมถึงการกำหนดว่า รูปแบบของ URL ซึ่งต่อไปนี้ผมจะเรียกว่า endpoint โดย endpoint ของแต่ละ service นั้นควรมีรูปแบบเช่นไร? ยกตัวอย่างเช่น การเรียกใช้งานเพื่อดูข้อมูลของผู้ใช้ทั้งหมดที่มีในระบบเรา ถ้าลองตั้ง endpoint ของ API แบบเร็ว ๆ เราก็จะได้ออกมาหน้าตาประมาณนี้ เนอะ
/getAllUsers

ดูอ่านเข้าใจเลย ตรงไปตรงมาดี แต่… รูปแบบด้านบนนี้ มันก็ยังดูไม่โอเค เพราะ endpoint นั้นจะต้องระบุว่าจะเป็น Resource อะไรเพียงเท่านั้น ซึ่ง Resource ก็คือการระบุชื่อของข้อมูลที่จะแสดงออกมา เช่น ข้อมูลของสัตว์เลียง เราก็ตั้งว่า pet

ส่วนการกระทำต่าง ๆ ที่ทำได้ จะส่งผ่าน HTTP Method ต่าง ๆ อาทิ GET, PUT, POST, DELETE เราจะเรียกมันว่า Verbs โดยแต่ละคำสั่งก็คงพอจะเดาได้นั่นคือ GET ใช้สำหรับเรียกดูข้อมูล, POST ใช้สำหรับการสร้างข้อมูลมาใหม่, DELETE ใช้การลบข้อมูล, PUT ใช้กับการอัพเดทแก้ไขข้อมูลหรือบางครั้งก็ใช้ในการสร้างข้อมูลขึ้นมาใหม่ ถ้าจะระบุชัดเจนว่าเป็นการแก้ไขค่าบางส่วนไม่ใช่ทั้งหมด (Patial update) ก็สามารถใช้ PATCH ได้ครับ สำหรับข้อมูลเพิ่มเติมการใช้ Verbs แบบต่าง ๆ ให้ดูรายละเอียดได้ที่นี่ครับ >> https://en.m.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods


ที่นี้ถ้าพอเราลองมาปรับเป็นแบบนี้ดู (ผมได้ทำการเพิ่ม Verbs เข้ามาด้านหน้า endpoint เพื่อระบุว่าเป็นการกระทำชนิดไหนด้วยน่ะครับ)

GET /student

แบบนี้ก็ดูดีขึ้นมาเยอะเลยมีการระบุ Resource ที่ชัดเจนว่า Endpoint นี้คือข้อมูลอะไร อีกทั้งยังมีการระบุ Verbs ว่าคือการกระทำประเภทของการเรียกดูข้อมูล

แต่… มันก็ยังไม่โอเคน่ะครับ เพราะที่นิยมกันทั่วไปในส่วนของ Resource นั้นต้องระบุเป็นคำชนิดที่เป็นพหูพจน์ (Plural) เหตุผลก็เพือเป็นการระบุว่าเราสามารถเข้ามาที่นี่แล้ว ต้องได้ข้อมูลหลาย ๆ Object ออกมา อีกเหตุผลนึงคือการเรียกเพื่อระบุให้แสดงออกมาแค่ Object ที่สนใจออกมาก้อนเดียว มักจะใช้รูปแบบตามนี้

GET /users/1

ตัวอย่างผลลัพธ์ : https://jsonplaceholder.typicode.com/users/1

คือการแสดงข้อมูลของนักเรียน id = 1 ออกมาเพียงคนเดียว (id นี่คือตั้งเป็นตัวอย่างน่ะครับ ให้มองว่ามันคือ Unique Key ที่สามารถใช้อ้างอิงข้อมูล Object นั้น ๆ ได้)

ทีนี้ถ้าเรามีการเรียกใช้งานแบบนี้ล่ะครับ

GET /users

ถ้าให้ลองทายข้อมูลที่ออกมาคืออะไรครับ?

ใช่แล้ว… มันคือการเรียกดูก้อนของ Object ของผู้ใช้งานหลาย ๆ คนออกมานั่นเอง เพราะเราไม่ได้ระบุว่าอยากดูข้อมูลใครเป็นพิเศษใช่ไหมครับ

ตัวอย่างผลลัพธ์ : https://jsonplaceholder.typicode.com/users


เรามาทบทวนคำศัพท์ใหม่ ๆ ที่เพิ่มเข้ามากันครับ ถ้าหากกำลังพัฒนา API สิ่งที่คุณต้องรู้ ย้ำอีกทีน่ะครับว่าต้องรู้ คือคำว่า Endpoint, Resource, Verbs และ Object ตรงนี้ใครยัง งง ๆ จุดไหน หรือ ผมยังอธิบายได้ไม่เคลียร์ สามารถชี้แนะเพิ่มเติมได้น่ะครับ


สำหรับบทความชุดนี้ได้มีการอ้างอิงจากลิงค์ด้านล่างเป็นหลักครับ ผู้ที่สนใจศึกษาเพิ่มเติมสามารถอ่านต่อได้ตามลิงค์ด้านล่างนี้ได้เลยครับ