จากบทความเรื่อง Write a Kubernetes-ready service from zero step-by-step
ทำการสรุป workflow หรือขั้นตอนของการพัฒนาระบบ REST API ด้วยภาษา Go
เริ่มตั้งแต่การพัฒนา API แบบง่าย ๆ
จากนั้นทำการเพิ่มความสามารถที่จำเป็นต้องมีทั้ง logging, health check และ graceful shutdown
รวมไปถึงการ deploy ระบบงาน
ซึ่งในตัวอย่างจะทำการสร้าง Docker Image
และทำการ deploy ด้วย Kubernetes
จึงทำการแปลและสรุปในแบบที่เข้าใจไว้นิดหน่อย
มาเริ่มกันเลย
ขั้นตอนที่ 1 สร้างระบบ API แบบง่าย ๆ ด้วย Hello World
อย่าลืมทำการทดสอบว่า ทำงานได้ตามที่ต้องการด้วย มี code ดังนี้ [gist id="5d8a524111c8a6f453a3cbffb1190d07" file="1.go"]ขั้นตอนที่ 2 อย่าลืมการเขียน logging ของระบบ
ทำตั้งแต่เริ่มจะได้งาม ๆ จะได้รู้ว่าควรหรือไม่ควรเขียนอะไร !! มี library หรือ framework ให้ใช้เพียบเช่น log, glog และ logrus เป็นต้น ตัวอย่างการเพิ่ม log ใน API แบบง่าย ๆ คือ- การ start service
- service start เรียบร้อย
- service เกิด error ขึ้นมา
ขั้นตอนที่ 3 ทำการเพิ่ม router ของ API เข้าไป
ในระบบ API นั้นจะมี endpoint หรือของการทำงานจำนวนมาก ซึ่งจะกำหนดไว้ในส่วนที่เรียกว่า router ถ้ายังทำใน package main หรือในไฟล์เดียว มันจะเยอะเกินไป ทำให้ดูและและจัดการยาก ดังนั้นแยกออกมาดีกว่า ส่วนการพัฒนา router ของ API ขึ้นอยู่ที่ความชอบว่าจะใช้ library หรือ framework อะไร เช่น gorilla/mux เป็นต้น หรือจะเขียนเองเด้วย package net/http ก็ได้ เอาที่สบายใจ ในการเขียน code นั้นส่วนการจัดการ router ไม่น่าจะอยู่ใน package main นะ !! ตรงนี้คือการแบ่งหน้าที่รับผิดชอบไปในแต่ละ package ซึ่งเป็นแนวปฏิบัติที่ดี ข้อดีคือแก้ไขและดูแลรักษาได้ง่าย ใคร ๆ เขาก็ทำกันแบบนี้นะ ใช่หรือเปล่า ? ดังนั้นในระบบของเราจะมี 2 package คือ- package main สำหรับเริ่ม
- package handlers สำหรับจัดการเรื่องของ router
ขั้นตอนที่ 4 ว่าด้วยเรื่องของการจัดการ dependency หรือ library ต่าง ๆ
สำหรับระบบใหญ่ และ การทำงานเป็นทีม สิ่งที่ควรมีคือ เครื่องมือในการจัดการ dependency หรือ library ต่าง ๆ ที่ใช้งาน ซึ่งใน go นั้นมีให้ใช้เยอะมาก ทั้งการเขียน shell/bat script กับการใช้ go get ทั้งการใช้ตัวจัดการ dependency เช่น dep และ glide เป็นต้น โดยในบทความจะใช้ dep ซึ่งติดตั้งไม่ยาก สามารถใช้งานได้ง่าย ๆ ดังนี้ [gist id="5d8a524111c8a6f453a3cbffb1190d07" file="6.txt"] เพียงเท่านี้ก็มีตัวจัดการ dependency แล้วนะ ง่ายมาก ๆขั้นตอนที่ 5 อย่าลืมชุดการทดสอบ API
เพื่อความสบายใจ สิ่งที่ต้องทำคือ สร้างชุดการทดสอบของ API แรกขึ้นมา การเริ่มต้นที่ดี มีชัยไปกว่าครึ่งนะครับ มาเขียนชุดการทดสอบ API กัน ข้อดีของ go คือมี package ชื่อว่า httptest มาให้ใช้แล้วนะสิ มาเขียนกันเถอะ เริ่มด้วย test case ง่าย ๆ คือ success ไงละ [gist id="5d8a524111c8a6f453a3cbffb1190d07" file="7.go"]ขั้นตอนที่ 6 จัดการเรื่องของ configuration ของระบบ
ซึ่งจาก The twelve-factor app นั้น แนะนำให้ทำการแยก configuration ออกจาก code หรือระบบงานด้วย นั่นคือให้ใส่ configuration ไว้ในแต่ละ environment แทน จะเห็นได้ว่าใน code ตัวอย่าง ทำการ hard code Port ไว้ ดังนั้นเราสามารถทำการเปลี่ยน port ของ API ไปไว้ใน environment variable จากนั้นใน code ก็เปลี่ยนไปดึงจาก environment variable แทน ทำให้ง่ายต่อการเปลี่ยนแปลงอีกด้วย ดังนี้ [gist id="5d8a524111c8a6f453a3cbffb1190d07" file="8.go"]ขั้นตอนที่ 7 จัดการเรื่องของ Health check และความพร้อมของ API
เริ่มเข้าสู่เรื่องของ operation ต่าง ๆ ของการ deploy ระบบงาน ในส่วนนี้ทำให้รู้ว่า API ยังมีชีวิตดีอยู่หรือไม่ ถ้าไม่ จะได้ทำการ restart service ใหม่ขึ้นมา รวมทั้งยังตรวจสอบความพร้อมต่าง ๆ ของ API เช่นถ้ามีการใช้ database แล้ว ถ้า API/service ไม่สามารถติดต่อ database ได้ ก็ให้ทำการนำ service นี้ออกไป หรือ ไม่ให้เข้าใช้งานเป็นต้น ตัวอย่างของ health check ของ API [gist id="5d8a524111c8a6f453a3cbffb1190d07" file="9.go"]ขั้นตอนที่ 8 ว่าด้วยเรื่องของ Graceful shutdown
เมื่อต้องการที่จะลบหรือหยุดการทำงานของ API แล้ว สิ่งที่ต้องทำคือ อย่าไปหยุดหรือขัดการทำงานของงานที่ยังทำไม่เสร็จ ดังนั้นต้องรอจนไปกว่างานทั้งหมดจะทำงานเสร็จ โดยที่ package http.Server ในภาษา go ตั้งแต่ version 1.8 ขึ้นมาสนับสนุน แต่วิธีการเขียนจะยากนิดหน่อย เพราะว่านำ go routine/channel มาใช้ด้วย สามารถเขียนได้ดังนี้ [gist id="5d8a524111c8a6f453a3cbffb1190d07" file="10.go"] มาถึงตรงนี้จะเห็นได้ว่า ในการพัฒนาระบบ API นั้นจำเป็นต้องมีสิ่งต่าง ๆ มากกว่า feature นะครับ ซึ่งทีมพัฒนาต้องให้ความสำคัญด้วยมาก ๆ อย่าไปทำในช่วงท้าย หรือ ก่อนทำการ deploy ให้คิด วางแผน และ ลงมือทำตั้งแต่เนิ่น ๆ จะได้รู้และเข้าใจปัญหา เพื่อแก้ไขกันต่อไปเข้าสู่ขั้นตอนการ build, ship และ run หรือการ deploy
โดยขั้นตอนเหล่านี้มักจะเรียกว่า Continuous Integration และ Continuous Delivery/Deployment มาดูกันว่าเป็นอย่างไรบ้าง ? ซึ่งในบทความจะใช้ Docker และ Kubernetes มาเริ่มกันเลยขั้นตอนที่ 9 ทำการสร้าง Dockerfile เพื่อใช้สำหรับการสร้าง image สำหรับ deploy ต่อไป
เมื่อทุกอย่างพร้อมแล้ว สิ่งที่ต้องกำหนดคือ กระบวนการ build -> test -> run ที่เป็นมาตรฐาน เพื่อให้ทุก ๆ คนในทีมทำงานในรูปแบบเดียวกัน อีกทั้งยังได้ artifact หรือ software package เอาไว้ deploy ต่อไป ในส่วนนี้มีวิธีการมากมาย ทั้ง shell/bat script ทั้ง Makefile ทั้ง manual process แต่ในปัจจุบันสิ่งที่ได้รับความนิยมคือ Containerization เครื่องมือที่ใช้คือ Docker ดังนั้นเรามาทำการสร้าง Dockerfile เพื่อใช้สร้าง Docker Image กัน เพื่อใช้ในการ deploy ต่อไป สิ่งที่ต้องการคือ- สร้าง Dockerfile
- ทำการ compile -> test -> build software package
- ทำการสร้าง image ไว้สำหรับการ deploy