รู้จักกับภาษา Go แบบสั้นๆ
- สร้างโดย Google บางครั้งเรียกว่า golang
- สร้างขึ้นเพื่อแก้ไขข้อบกพร่องของ C++
- ใช้สำหรับ: การเขียนโปรแกรมระบบและเซิร์ฟเวอร์ที่ปรับขนาดได้
- ประสิทธิภาพสูง
- มีไวยากรณ์ที่อ่านง่าย
เขียนโดย
Sirasit Boonklang – BorntoDev Co., Ltd.
Serverless architecture เป็นการพัฒนาแอปแบบเรียกใช้ logic ซึ่งจะใช้งานบนระบบคลาวด์ โดยมีการจัดการ infrastructure ของเซิร์ฟเวอร์น้อยลง
Azure Functions คือบริการหนึ่งใน Microsoft Azure สำหรับการใช้งาน Serverless architecture โดยจะมีการเรียกใช้โค้ดหรือชุดคำสั่งตามที่ความต้องการ โดยไม่ต้องจัดเตรียมเซิร์ฟเวอร์เอง
โดย Azure Functions จะมีรันไทม์หลากหลายภาษา ซึ่งหากไม่มีภาษาที่ต้องการให้เราเลือกใช้ตัวจัดการแบบกำหนดเองหรือที่เรียกว่า Custom handlers ได้
Custom handlers คืออะไร
Custom handlers คือเว็บเซิร์ฟเวอร์ที่รับ events จาก Functions host
จากนั้นเราจะเขียนโค้ดในภาษาที่เรา Request เพื่อรอรับ response ต่อ events นั้น ๆ และภาษาที่ใช้งานได้ก็คือภาษาที่รองรับ HTTP นั้นเอง ซึ่ง Go ก็สามารถใช้งานได้นะครับ
Concepts and flow ที่สำคัญของ Azure Functions
- Triggers คือ events ที่เริ่มเรียกใช้ฟังก์ชัน
ทริกเกอร์โดยทั่วไปๆ เช่น HTTP requests, queue messages, หรือการเปลี่ยนแปลงข้อมูลในฐานข้อมูล - Bindings คือ โค้ดตัวช่วยที่เชื่อมต่อฟังก์ชันกับบริการคลาวด์อื่น เชื่อมโยงอินพุตและเอาท์พุต สามารถส่งข้อมูลเข้าและออกจากฟังก์ชันได้
- Functions host เป็นควบคุม event flow ของแอปพลิเคชัน เมื่อ host จับ events ตัวจัดการจะถูกเรียกใช้และส่งคืนการตอบสนองของฟังก์ชัน
เรามาเริ่มสร้าง REST API ด้วย Go กันเลย
1.เริ่มจากการสร้าง REST API โดยใช้ Go การใช้งานไลบรารี fmt และ net/http สำหรับจัดการ routes และ requests ที่เข้ามา โดยใช้คำสั่งต่อไปนี้
import ( "fmt" "net/http" )
2. การตั้งค่ากำหนด routes ประกอบด้วยส่วน logical ที่เรียกว่า routes หรือ เส้นทาง
routes คือที่อยู่ของ respond ในแอป ในการตั้งค่า routes ให้เรียกใช้เมธอด HandleFunc() บนอินสแตนซ์ http และกำหนด routes เพื่อตอบสนองต่อคำขอ โดยในกรณีนี้ จะต้องสร้างฟังก์ชัน handleRoute เพื่อจับคู่ requests ที่เข้ามากับ routes “/”
http.HandleFunc("/", handleRequest)
3. โดยการจัดการกับ requests ที่เข้ามาและจะต้องมีตัวอ่านสิ่งต่าง ๆ ที่เข้ามาอีกด้วย เช่น
เราเตอร์ พารามิเตอร์หรือเนื้อหาต่างๆ จากนั้นจะ respond ไปยัง ฟังก์ชันที่จัดการ requests ดังตัวอย่างนี้
func handleRequest(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello") }
4. สร้างเซิร์ฟเวอร์เพื่อให้สามารถฟังคำขอได้ โดยการเริ่มการทำงานของเซิร์ฟเวอร์ จะต้องระบุส่วนที่สามารถส่งคำขอได้ โดยโค้ดต่อไปนี้จะแสดงวิธีการสร้างเซิร์ฟเวอร์
package main import ( "fmt" "net/http" ) func handleRequest(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "My Rest API") } func main() { http.HandleFunc("/", handleRequest) http.ListenAndServe(":3000", nil) }
5. เซิร์ฟเวอร์ทำงานแล้วและสามารถรับ requests บนพอร์ต 3000 ได้
การใช้ custom handler ในการสร้าง serverless app ด้วย Azure Function
6. เปิด Visual Studio Code แล้วเลือก View > Command Palette
7. เลือก Azure Functions: Create New Project
8. เลือกโฟลเดอร์ โฟลเดอร์ปัจจุบัน
9. ในเลือกภาษาเป็น Custom Handler
10. เลือกเทมเพลตสำหรับฟังก์ชันแรก โดยเลือกเป็น HttpTrigger
11. ตั้งชื่อแอปของเรา โดยตัวอย่างนี้ชื่อว่า “myapp”
12. เลือกระดับการให้สิทธิ์เป็น anonymous (สามารถเปลี่ยนได้ในภายหลัง)
13.โดยระบบจะสร้างไฟล์เริ่มต้นแอปลักษณะดังนี้
14.ขั้นตอนถัดไปคือการสร้างแอปที่ตอบสนองต่อ HTTP trigger ได้
สร้างไฟล์ชื่อ server.go ที่ root ของโปรเจกต์
15. เรียกใช้ไลบรารีสำหรับสร้างแอป HTTP ด้วยโค้ดดังต่อไปนี้
package main import ( "fmt" "io/ioutil" "log" "net/http" "os" )
16. เพิ่มโค้ดต่อไปนี้หลังคำสั่งเรียกใช้งานไลบรารี
func main() { customHandlerPort, exists := os.LookupEnv("FUNCTIONS_CUSTOMHANDLER_PORT") if !exists { customHandlerPort = "8080" } mux := http.NewServeMux() fmt.Println("Go server Listening on: ", customHandlerPort) log.Fatal(http.ListenAndServe(":"+customHandlerPort, mux)) }
17. โดยฟังก์ชั่น main() จะถูกเรียกใช้โดยเริ่มต้น และจะอ่านตัวแปรสภาพแวดล้อมจาก FUNCTIONS_CUSTOM_HANDLER_PORT ดังโค้ดด้านล่าง
customHandlerPort, exists := os.LookupEnv("FUNCTIONS_CUSTOMHANDLER_PORT")
18. ต่อจากนั้นฟังก์ชันจะเช็คว่ามีพอร์ตอยู่ไหม ถ้าไม่ฟังก์ชันจะกำหนดพอร์ตเป็น 8080
if !exists { customHandlerPort = "8080" }
19. สร้างอินสแตนซ์ของ HTTP server
mux := http.NewServeMux()
20. บรรทัดสุดท้ายคือเริ่มฟังพอร์ตเฉพาะและส่งสัญญาณว่าพร้อมที่จะรับ requests ด้วยเมธอด ListenAndServe():
log.Fatal(http.ListenAndServe(":"+customHandlerPort, mux))
21. ระหว่างโค้ดเรียกใช้ไลบรารีและฟังก์ชัน main() ให้เพิ่มโค้ดต่อไปนี้
func helloHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") if r.Method == "GET" { w.Write([]byte("hello world")) } else { body, _ := ioutil.ReadAll(r.Body) w.Write(body) } }
ฟังก์ชัน helloHandler() ตั้งค่าประเภทเนื้อหาเป็น application/json โดยจะตอบกลับด้วยคำว่า “hello world”
เมื่อเขียนโค้ดเสร็จแล้ว ต่อไปจะกำหนดค่าเพื่อบอกว่าไฟล์ exe อยู่ที่ไหน เพื่อให้โฮสต์ Function สามารถหาได้ โดยต้องกำหนดค่า routing และระบุว่าแอปนี้เกี่ยวข้องกับ HTTP triggers และไม่มีการเชื่อมโยงประเภทอื่น
22. เปิดเทอร์มินัลรันคำสั่ง go build server.go ใน root โปรเจ็กต์ จะได้ไฟล์ server.exe เพิ่มขึ้นมา
23. เปิดไฟล์ host.json และหา defaultExecutablePath ภายใน customHandler เพิ่ม.\server
24. ใน customHandler ให้เพิ่ม enableForwardingHttpRequest และกำหนดค่าเป็น True
25.จากนั้นเปิดเทอร์มินัลให้รัน func start ใน root โปรเจ็กต์ เพื่อเริ่มการทำงานของ Functions app
ยินดีด้วยครับ! ตอนนี้คุณได้ลองสร้าง serverless app ด้วย Go เบื้องต้นเสร็จเรียบร้อยแล้ว 🚀
สามารถเรียนรู้เพิ่มเติมเกี่ยวกับการสร้าง serverless app ด้วยภาษา Go ได้ที่
Build Serverless Apps using Go with Chris Noring | Web Wednesday | Channel 9 (msdn.com)