Quantcast
Channel: cc :: somkiat
Viewing all articles
Browse latest Browse all 1997

สรุปขั้นตอนในการพัฒนาระบบ REST API ด้วยภาษา Go ที่น่าจะดี

$
0
0

จากบทความเรื่อง 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 ขึ้นมา
Code น่าจะดูดีขึ้นนะ [gist id="5d8a524111c8a6f453a3cbffb1190d07" file="2.go"]

ขั้นตอนที่ 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
เริ่มด้วยการสร้างไฟล์ handlers.go สำหรับจัดการ router [gist id="5d8a524111c8a6f453a3cbffb1190d07" file="3.go"] ต่อมาสร้างไฟล์ home.go สำหรับทำงานในส่วนของ endpoint ชื่อว่า /home [gist id="5d8a524111c8a6f453a3cbffb1190d07" file="4.go"] จากนั้นทำการแก้ไข main.go เพื่อให้ไปใช้ router ที่สร้างขึ้นมา [gist id="5d8a524111c8a6f453a3cbffb1190d07" file="5.go"] ก่อนใช้งานก็ต้องติดตั้ง github.com/gorilla/mux ก่อนผ่าน go get !!

ขั้นตอนที่ 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
ซึ่งเราสามารถใช้ Docker multi-stage build ได้ ยกตัวอย่างเช่น [gist id="5d8a524111c8a6f453a3cbffb1190d07" file="Dockerfile"] จะเห็นได้ว่า กระบวนการต่าง ๆ ทั้ง compile, test และ สร้าง software package อยู่ในนี้ ที่สำคัญ version ต่าง ๆ ของ software ถูกกำหนดไว้ชัดเจนอีกด้วย ดังนั้นปัญหาน่าจะลดไปได้มาก การใช้งานก็ง่ายมาก ๆ ดังนี้ [code] $docker build -t api:1.0 . $docker run --rm -p 8080:8080 api:1.0 [/code] ตอนนี้เราได้ Docker Image ที่พร้อมเอาไป deploy แล้วนะ ทั้งใช้ Docker (ในตัวอย่าง run ไปแล้ว) ทั้งใช้ Docker Swarm ทั้งใช้ Kubernetes เอาที่สบายใจนะครับ

ขั้นตอนที่ 10 ทำการ deploy ระบบ API ด้วย Kubernetes

ในการ deploy ด้วย Kubernetes ต้องจัดเต็ม ทั้ง service ทั้ง deployment ทั้ง ingress ซึ่งสามารถทำการ configuration ได้ดังนี้ ซึ่งสามารถแยกไฟล์ หรือ รวมไฟล์ได้ประมาณนี้ [gist id="5d8a524111c8a6f453a3cbffb1190d07" file="tmp.yaml"] เมื่อทุกอย่างพร้อม ทำการ deploy ด้วย Kubernetes ในตัวอย่างจะใช้ minikube เพื่อให้ run แบบ local/stanalone ได้ และทดสอบซะ [gist id="5d8a524111c8a6f453a3cbffb1190d07" file="11.txt"]

เพียงเท่านี้เราก็ได้ระบบ API แบบง่าย ๆ

ที่พัฒนาด้วยภาษา Go มีทั้ง logging, health check และ graceful shutdown ไปจนถึงการสร้าง Docker Image และ deploy ด้วย Kubernetes อีกด้วย น่าจะทำให้เห็น workflow หรือขั้นตอนการพัฒนาที่ดีกว่าเดิม ขอให้สนุกกับการ coding ครับ ปล. สิ่งที่ไม่ได้อธิบายคือ เรื่องของ versioning และ Makefile นะครับ

Viewing all articles
Browse latest Browse all 1997

Trending Articles