Vapor

ไม่ได้เขียน blog ทาง  technical หลายเดือน เพราะในช่วงนี้ผมต้องเขียน api backend  สำหรับ mobile app ตัวหนึ่ง หลังจากการลองผิด ลองถูกอยู่นาน ก็เลยเลือกเขียนด้วย Vapor และบทความนี้ ผมคงไม่ได้เขียน tutorial การใช้ vapor อย่างเช่นให้แสดง Hello world อะไรง่ายๆแบบนั้น แต่ผมจะมาเล่าให้ฟังถึง ปัญหา , สิ่งที่เจอ , feature ต่างๆจากที่ได้ลองเขียน Vapor มาประมาณเดือนหนึ่ง

ก่อนจะเล่าถึง Vapor ผมขอย้อนกลับไปก่อนแล้วกันว่าทำไมถึงเลือกเขียน backend ด้วย swift เผื่อเป็นข้อมูลในการตัดสินใจสำหรับคนจะใช้ Vapor เป็น backend

คือในช่วงหลายเดือนที่ผ่านมา ผมได้ทำโปรเจคอยู่ตัวหนึ่ง ซึ่งเป็นโปรเจคใหญ่ที่ประกอบไปด้วยโปรเจคย่อยๆสามอย่างหลักๆด้วยกันคือ อย่างแรกเป็น api backend ทำหน้าที่เป็นตัว core service หลัก ในส่วนต่อมาคือ web front end  และสุดท้ายคือ mobile app ซึ่งสองตัวหลังนี้จะเชื่อมต่อไปยัง api backend ตัวเดียวกัน

ในช่วงที่เริ่มโปรเจค ด้วยความที่ไม่เคยทำ backend มาก่อน จึงได้ตัดสินใจเลือกที่จะใช้ Go Language ตามคำแนะนำของเหล่าทวยเทพ และเหล่า Gopher เซียน backend ว่ามัน เจ๋งงงง สุดยอด .. ดีกว่า  NodeJS, เป็น type safty, ทำงานได้เร็วมาก, concurrency เจ๋งๆ,  blah blah ๆ ชาบู Google อะไรก็ว่ากันไป

ด้วยความที่ไม่เคยเขียน Go มาก่อน ก็ต้องมาเริ่มต้นเขียน  Go และเรียนรู้ คอนเซ็ปของ Go อย่างเช่น go pointer ที่ไม่เหมือน c pointer หรือการที่มันเป็น paradigm แบบ structure ไม่ใช่แบบ OOP ที่คุ้นเคย รวมไปถึงสไตล์การเขียนอะไรย่อๆ อย่างชื่อตัวแปร ตามสไตล์ Go ซึ่งมันขัดกับสาย Swift ที่ชอบเขียนชื่อยาวๆ (แอบ แซะไปเยอะ 555+) จะอะไรก็ตาม นั่นไม่ใช่ปัญหาใหญ่สำหรับผม เพราะผมเรียนรู้มันได้

แต่ปัญหาหลักๆที่ผมเจอคือ ปริมาณงานที่ต้องทำมันเยอะมาก .. มันทำไม่ทัน เมื่อมันทำไม่ทันดังนั้น ผมจึงตัดสินใจที่จะหา Developer และ Freelance เพิ่ม แต่ปัญหาที่ใหญ่มากคือ .. คนที่เขียน Go มีน้อยมากกกกก ย้ำว่า น้อยยยยมาก  ในระยะเวลกลายเป็นว่า โปรเจคมันดีเลย์ไปหลายเดือนมาก เพราะคนไม่พอ จะไปจ้างคนเขียน ก็หาคนยากมากกก นี่ผมใช้เวลาไป 3 เดือน ยังไม่ได้ซักคน

ทำไงดีละ ?

อย่างที่บอกไปคือ โปรเจคมันทั้งหมด 3 ส่วนคือ  web front end กับ backend  แล้วก็มีส่วน mobile app ดังนั้น ผมจึงเอา api บางส่วนที่ mobile ต้องใช้งาน แยกออกมาเขียนเป็นอันใหม่ กลายเป็น backend 2 ตัว (เหมือนงานจะเพิ่ม แต่เดี๋ยวผมมีเหตุผลที่แยกออกมา ซึ่งจะกล่าวต่อไป) ในส่วนของ web front end ก็ยังเชื่อมต่อกับ backend ที่เขียนด้วย  GO เหมือนเดิม จะมีก็แต่ mobile app ที่มันจะเชื่อมต่อกับ backend ตัวใหม่ที่เขียนด้วย swift

การเริ่มต้นใหม่นี้ ผมเลือกเอา Swift มาเขียนเป็น backend ก็นับว่าความเสี่ยงอยู่มาก เพราะด้วยตัวภาษา Swift เองที่มันเปลี่ยนอยู่ตลอด และยังเป็นเรื่องค่อนข้างใหม่สำหรับการนำเอา swift มาใช้เขียนเป็น backend ผิดกับภาษา GO, Node ที่ได้ออกแบบมาสำหรับ การเขียน backend โดยเฉพาะ

มีคนถามผมนะว่า ในเมื่อมันเสี่ยง ทำไมเลือกเอา Swift ละ ไม่ใช้ Node , PHP , Ruby, JAVA บลาๆๆๆๆ ?

ผมเลือกใช้ Swift ด้วยปัจจัยหลักๆคือ

  • Node, PHP, Ruby สำหรับผม ต้องเรียนรู้ใหม่ กว่าจะทำความเข้าใจ เขียนให้คล่อง โปรเจคก็คงเลื่อนไปอีก
  • แม้ว่าจะเขียน Java พอได้ และ Java ก็มีเฟรมเวิร์คทาง backend หลายตัวเช่น spring boot แต่ผมไม่ชอบ JAVA เป็นการส่วนตัว (ผมเขียน Android ด้วยนะ แต่ใช้ Kotlin) ดังนั้นการเลือกใช้ Java จึงไม่ใช่คำตอบสำหรับผม
  • จำนวนคนที่เขียน Swift เป็นนั้น มีเยอะกว่า Go ในกรณีที่เราต้องจ้าง Freelance , Outsource นั้น หาคนง่ายกว่ามาก
  • Backend ที่จะเขียนใหม่ เป็นของ mobile ถ้าหากต้องแก้ไข ก็ให้ Mobile Dev แก้ไขทันที เพราะใช้ภาษาเดียวกัน ( Full-Stack )

ปัจจัยที่สำคัญที่สุดของผมคือ สอง อย่างหลัง เพราะ การหาคน เป็นอะไรที่ยากมากจริงๆ ถ้าหากเป็น บริษัทใหญ่ๆ มีเงินจ้างคนแพงๆ คงไม่ใช่ปัญหา แต่ว่าถ้าหากมีคนน้อยๆ งบน้อยๆ ผมขอให้พิจารณา ให้ถี่ถ้วนก่อนนะครับ ว่า กำลังในทีม เพียงพอ หรือเปล่า บางทีการตัดสินใจเลือก technology บางตัว มันกระทบ กับ การหาคนมาเขียน รวมไปถึงการ maintain code ในอนาคตด้วยนะครับ

Vapor

ก่อนหน้านี้ผมเคยลอง Kitura มาสักพัก แต่หลายๆของ Kitura มันยังไม่ค่อยโอเค เท่าไหร่ อย่างเช่น การเชื่อมต่อ postgres และสุดท้ายก็นั่นแหละ มันก็มาลงเอยด้วยการใช้ vapor และหลังจากการเขียน Vapor มาสักพัก ผมจะเล่าถึงประสบการณ์ ที่ได้ใช้ Vapor เป็น API และสิ่งต่างๆที่ได้เจอออกเป็นหัวข้อละกันนะครับ และเนื่องจากผมใช้มันเป็น API Backend ไม่ได้ใช้เป็น Web Server ดังนั้นในส่วนที่เกี่ยวข้องกับ web อย่าง server rendering , web template นี่ผมขอไม่พูดถึงนะครับ

Tools

Vapor มีเครื่องมืออำนวยความสะดวกมาให้ คือ Vapor Command Line ซึ่งมันจะช่วยให้เราเริ่มต้นสร้างโปรเจคได้ง่าย เลือกได้ว่าจะเอา template แบบไหน เป็น web หรือ แค่ api และมันยังมีคำสั่งในการ update package , dependency ต่างๆ รวมอยู่ในตัวเอง รวมไปถึงการสร้าง xcode project คืออันที่จริงเราไม่ต้องใช้ xcode project เพราะ backend มันมักจะถูก compile และทำงานบน linux (คงไม่มีใครใช้ Mac OS เป็น Server กันเท่าไหร่จริงไหม ?) แต่เราต้องวาง source code folder อะไรต่างๆให้ให้ถูกต้อง แต่เหตุผลหลักที่เรายังต้องการ xcode project เนี่ย ก็เพราะว่า เราพัฒนาบน Mac เป็นหลัก การใช้ Xcode เป็นเครื่องมือในการเขียน code มันดีกว่าการไปเขียนด้วย text editor ตัวอื่นๆ และถ้าหากเราไม่ใช้ command line tool  คุณก็ต้องมาจัดการ กับ dependency และ source code ใน xcode project ด้วยตัวเอง ซึ่งมันเสียเวลา ดังนั้นการที่มีเครื่องมือมาให้ นับว่าเป็นข้อดีอย่างมาก

Code Style

ในการเขียน backend นั้นจะมี framework หลักๆ อยู่หลายเจ้า อย่างเช่น Kitura ของ IBM หรืออาจจะเป็น Perfect และ Zewo อะไรก็ว่ากันไป แต่ถ้าหากเทียบกันแล้ว Vapor นั้นมีการเขียน coding style ที่ดูเหมือนจะเป็นสไตล์ swift มากกว่าเจ้าอื่นๆ .. อย่างกรณีของ Kitura นั้น ได้ออกแบบมาให้เหมือนกับ express ของ Node JS ดังนั้นแล้ว วิธีการในการเขียนมันก็เลย เหมือนเขียน NodeJS  ผมว่า Vapor นี้มันเข้ากับสไตล์ของผมมากกว่า

Database Support

ในการเขียน backend แน่ๆคือมันต้องเชื่อมต่อกับ database สักตัว ข้อดีที่เห็นได้ชัดมากคือ มันมี framework ที่เรียกว่า fluent ซึ่งเราไม่ต้องไปจัดการเขียน code พวก sql เอง เราสามารถสร้าง model เพื่อให้มัน จัดเก็บลง database ได้เลย  และมันก็รองรับ postgres , mongo, sqlite โดยจะทำงานผ่านสิ่งทีเรียกว่า provider และข้อดีอีกอย่างของ fluent คือเขียน unit test ง่าย (ถ้าใครเคยเขียน  unit test ที่เชื่อมต่อกับ database จะเข้าใจว่ามันปวดหัวแค่ไหน)

JSON Suport

ข้อดีอีกอย่างของ fluent คือมันแปลง json เป็น model ได้ค่อนข้างง่าย รวมไปถึง การเปลี่ยน model กลับไปเป็น json ก็ง่าย มันสะดวกมากเวลาที่จะตอบ response กลับไปเป็น json

Authentication

การยืนยันตัวตน เป็นฟีเจอร์ที่แทบจะทุก service ต้องมี ซึ่งใน vapor มันจะทำงานผ่านทาง provider (เหมือนกับกรณี database) และมันก็รองรับการ authen หลายอย่างมาก ไม่ว่าจะเป็นจะเป็นแบบ username – password หรือว่า ใช้ token ก็ได้ และรองรับ JWT ด้วย ซึ่งตรงนี้ผมว่ามันค่อนข้างสะดวก ผมยังไม่เคยลองทำพวก third party authen นะ อย่างเช่น facebook , google ว่ามันทำงานได้ดีแค่ไหน

Route

การสร้าง Route ของ Vapor นั้นก็ค่อนข้างจะง่าย ไม่ว่าจะเป็นแบบ Rest หรือแบบ static path การเข้าถึง query หรือ parameter ของ request ที่เข้ามาก็มีฟังก์ชั่นมาครบ หรือถ้าหากต้องการจะกำหนด สิทธิการเข้าถึงแต่ละ path ก็ทำได้ค่อนข้างสะดวก

REST

หากต้องการจะให้ api เป็น แบบ rest ตัวของ vapor เองก็ทำได้ง่ายๆผ่านทาง controller builder ยิ่งถ้าใช้ร่วมกับ fluent แล้ว มันเป็นอะไรที่แจ่มมาก เพราะมันลดงานในการเขียน code ลงไปได้เยอะมาก แค่กำหนดว่า PUT , POST , UPDATE เรียกฟังก์ชั่นอะไรก็จบละ (คือมันลดการเขียน code DB sql แล้วยังลดการเขียน code ในส่วนของ route อีก)

Middleware

ใน vapor มี middleware ให้ใช้งานอยู่หลายตัว อย่าง redis ,facebook auth , realm และการเขียน middle ware ขึ้นมาใช้งานเอง ผมว่ามันง่ายนะ เพราะว่ามันมี protocol รองรับไว้อยู่แล้ว

Deployment

ในส่วนของการ deploy นั้น ตัว vapor เราจัดการ environment ได้ด้วย config ไฟล์ ซึ่งใน Vapor นี้มัน แยก มาให้เราเลยว่า เป็น development, staging หรือว่า production มันทำให้ เรากำหนดสิ่งต่างๆที่จำเป็นได้สะดวกมาก อย่างเช่นว่า ตอนพัฒนา ให้มันไปต่อกับ DB เครื่องตัวเอง แต่ตอน deploy จริงๆให้มันไปต่อกับ AWS แบบนี้ รวมไปถึงการจัดการ secret key ต่างๆ มันก็แยกให้เรา

หรือถ้าอยากจะ deploy เป็นแบบ container ผ่านทาง docker ก็ทำได้ คือตัว vapor มันมี docker file ที่ community ทำไว้ให้อยู่แล้ว ดังนั้นเราเลยไม่ต้องไปเริ่มเขียน docker file จากศูนย์

Debug

จากประสบการณ์ในการเขียน GO และ NodeJS ผมบอกได้คำเดียวสองอย่างนี้ ห่วยแตกในการ debug มาก คือในช่วงแรกๆ นี่ผมถามคนที่เขียน backend หลายคน (ทั้ง Go, NodeJS) นะว่า debug กันยังไง เค้าบอกว่า ใช้ print log ดูค่าเอา ผมนี่ถึงกับร้อง WTF !!!! คือส่วนตัวผมไม่ชอบเลยกับการที่ต้องมาดู log ว่าค่า มันเป็นอะไร แม้ว่า Go มันจะมี Debugger อย่าง Delve อยู่ แต่มันต้องมา config ให้มันทำงานร่วมกันผ่าน IDE ได้ ( ใช้ Gogland IDE อาจจะง่ายกว่า VS Code หน่อยหนึ่ง) และประสิทธิภาพของ debugger นี่ก็อ่อนด้อยมาก ในขณะที่ Swift นั้นการ debug มันง่ายมาก ถ้าหากเราทำผ่าน Xcode

Unit test

เท่าที่ลองใช้งาน ตัว vapor มัน build in พวก function ในการทดสอบ route (request / response) อยู่แล้ว ไม่ต้องไปเขียน XCTest กับแบบเพียวๆเท่าไหร่ และก็อย่างที่ได้บอกไปว่า ถ้าหากใช้ fluent การเขียน unit test จะทำได้ง่ายมาก เพราะว่า เราไม่ต้องให้มันไปเชื่อมต่อกับ database server จริงๆ แค่กำหนดให้มันสร้าง db ใน memory ในตอนที่เรา run testing เท่านั้นเอง ซึ่งในบางครั้ง มันลดการเขียน mock ไปด้วยนะ

Document / Community / Sample / Tutorial

ในส่วนนี้ผมว่า มันดีมากๆ คือมันมีคนใช้เยอะ ทำให้เราหาตัวอย่างโค้ดได้ง่าย รวมไปถึง document ที่เขียนไว้ค่อนข้างจะครบ ทำให้เวลาติดปัญหาเนี่ย มันหาทางออกได้รวดเร็ว

Feature อื่นๆ

อันที่จริงมันมีอีกหลาย feature ที่ผมยังไม่เคยลองใช้งาน อย่างเช่น session , core หรือการใช้ให้มันเป็น web server ดังนั้นในส่วนนี้ก็เลยบอกไม่ได้ว่า เป็นยังไง

vapor.cloud

อันนี้ผมก็ไม่ได้ลองใช้งานนะครับ ที่ยกมาพูดถึงเนี่ย ผมแค่จะบอกว่า Vapor น่าจะมีอนาคตสดใสอยู่นะ เพราะว่า อาจจะเป็น cloud เจ้าแรก ที่ใช้ Swift เป็นหลัก

ข้อเสียละ ?

ข้อเสีย อย่างแรกของมันคือ เค้าบอกว่า มันทำงานได้ช้ากว่าตัวอื่นๆ ซึ่งก็มีคนลอง bench mark   ซึ่งก็มีผลว่า Vapor 2 ทำงานได้ค่อนข้างช้ากว่าคนอื่น เร็วสุดก็ Go และมั้ง แต่ว่าในส่วนนี้ผมไม่ค่อยแคร์เรื่อง performance สักเท่าไหร่ เพราะว่า จำนวนผู้ใช้งานอยู่แค่หลักพัน ไม่ได้ทำ server ที่จะรองรับผู้ใช้งาน หลักล้านคน ข้อเสียอย่างที่สองคือ ยังไม่มีค่อยมีคนเอา swift เป็น backend เจอปัญหาอาจจะต้องหาทางแก้เอาเอง

สรุป

ถ้าคุณสามารถใช้ firebase หรือพวก service สำเร็จรูปอื่นๆได้ก็ไม่ต้องเขียนเองหรอกครับ แต่ถ้าต้องเขียน backend เอง ผมว่า Vapor เป็นทางเลือกที่ดี ตัวหนึ่งเลยนะครับ เหมาะมากสำหรับทีม ที่มี iOS Dev เยอะๆ

ก่อนจะจากไป ผมคงบอกไม่ได้เต็มปากนักว่า ตัดสินใจถูกหรือผิดที่เลือกใช้ Vapor แต่คิดว่า ณ สถานการณ์ในปัจจุบัน มันเหมาะกับโปรเจคที่ผมทำอยู่มากที่สุดแล้ว

Leave a Reply