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

เรานำแนวคิดของ Continuous Integration มาใช้หรือไม่ ?

$
0
0

วันนี้อ่านหนังสือเรื่อง Continuous Integration ไปเจอชุดคำถามที่น่าสนใจว่า เรากำลังนำแนวคิดและแนวปฏิบัติของ Continuous Integration มาใช้งาน หรือเราเพียงนำเครื่องมือที่เรียกว่า Continuous Integration Tool มาใช้เท่านั้น ดังนั้นลองมาตอบคำถามเหล่านี้กันหน่อย

คำถามที่ 1

ในแต่ละวันทำการ check-in หรือ push code หรือ pull request ไปยัง branch หลักที่ทำงานร่วมกันกี่ครั้ง ? แนวคิดของ Continuous Integration นั้น เพื่อช่วยทำให้มั่นใจว่า การรวม code และสิ่งต่าง ๆ ที่เปลี่ยนแปลงนั้นถูกต้องหรือไม่ ดังนั้นถ้าเราไม่ทำการส่งการเปลี่ยนแปลงไปยัง branch หลักที่ทุกคนในทีมทำงานร่วมกันแล้ว คิดว่าปัญหาต่าง ๆ ยังคงอยู่ แม้จะมีการนำแนวคิดที่ดีมาใช้งาน แต่เรากลับไม่ปรับเปลี่ยนตัวเราเอง สุดท้ายสิ่งที่ผิดคือ อะไรก็ตามที่ไม่ใช่ตัวเรา !! ถ้าแต่ละคนมี branch ส่วนตัว เช่น feature branch แล้ว feature branch เหล่านี้ต้องมีอายุที่สั้น จากนั้นทำการรวมไปยัง branch หลักที่ทำงานกัน และลบ feature branch ไปซะ

คำถามที่ 2

มีชุดการทดสอบแบบอัตโนมัติหรือไม่ ? เพื่อใช้ตรวจสอบการเปลี่ยนแปลงต่าง ๆ ที่เกิดขึ้น ถ้าไม่มีหรือมีน้อยมาก ๆ นั่นหมายความว่า น่าจะกำลังไปผิดทาง เพราะว่า ไม่ได้ช่วยทำให้เรามีความมั่นใจต่อการเปลี่ยนแปลงเลย ดังนั้น เริ่มเขียนชุดการทดสอบแบบอัตโมัติได้แล้วนะ ไม่ว่าจะเป็น unit, integration, api และ end-to-end test เป็นต้น

คำถามที่ 3

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

สรุปเนื้อหาในช่วงเช้าของงาน React Bangkok 3.0.0

$
0
0

มีโอกาสมาร่วมงาน React Bangkok 3.0.0 จัดโดยทีม ReactJS Developer Thailand จัดงานที่ตึก Energy Complex ชั้น 6 ซึ่งครั้งนี้จัดยิ่งใหญ่กว่าเดิมมาก เพื่อไม่ให้เสียเวลา มาสรุปเนื้อหาของงานในช่วงเช้ากันดีกว่า ส่วนบรรยากาศไว้ตามมาทีหลัง ในส่วนของเนื้อหาช่วงบ่ายอ่านได้ที่นี่

เริ่มงานมาก็จะติดขัดนิดหน่อยสำหรับการลงทะเบียนเข้างาน

เพราะว่าออกมาจากลิฟท์ก็เจอกับเหล่า React Developer หลายร้อยชีวิตเข้าแถว เพื่อลงทะเบียน รับเสื้อและของที่ระทึก !! แถวยาวมาก ๆ ซึ่งเรื่องนี้เป็นปัญหาที่เกิดกับทุก ๆ event เลยนะ เราจะแก้ไขกันอย่างไรดี ส่วนชาว developer ก็มาสายเป็นปกติ เพราะว่า เมื่อคืนทีมชาติเยอรมันลงแข่งตอนตีหนึ่ง กว่าจะจบก็ปาไปจนตี 3 กันแล้ว !! แต่โดยรวมบรรยากาศกำลังดีมาก ๆ

เริ่มมาที่เนื้อหากันบ้าง

เปิดด้วย session แนะนำตัวของผู้สนับสนุนสถานที่หลักอย่างเป็นทางการคือ PTT Digital ซึ่งทำการแนะนำบริษัท ที่ไปที่มา รวมไปถึงเป้าหมายที่ได้ตั้งไว้ ว่ามีอะไรบ้าง เพื่อสร้างและพัฒนา service ใหม่ ๆ รวมทั้งการสร้าง digital platform สำหรับองค์กร ตลอดจนสิ่งที่กำลังทำเช่น Cloud, Analytic/Big data, Blockchain และ Security เป็นต้น ไม่รอช้าเริ่มเนื้อหาของ React กันเลย

หัวข้อแรก การเปลี่ยนแปลงที่สำคัญของ Reactในปี 2018

ในปี 2018 นั้น React จะมีการเปลี่ยนแปลงมากมาย แต่ทางผู้พูดเลือกสิ่งที่น่าสนใจมา 3 เรื่องคือ
  1. React Async Rendering ซึ่งช่วยให้ react app มีการทำงานที่ดีขึ้นอย่างมาก
  2. สิ่งที่จะ deprecated ไปจาก React Life cycle มาจากผลของข้อที่ 1 นั่นเองคือ componentWilMount, componentWilREceiveProps และ ComponentWillUpdate ดังนั้นถ้าใครจะใช้อะไรก็ระวังด้วย เผื่อต้อง migrate กัน
  3. การ Re-architecture ของ React Native เป็นการยกเครื่องใหม่ เพื่อปรับปรุงประสิทธิภาพการทำงาน รวมทั้งการทำงานร่วมกันกับส่วนต่าง ๆ ดีขึ้น น่าจะเป็นอีกเรื่องที่ดีสำหรับอนาคต รอดูกัน

หัวข้อที่สองและสามคือ Gataby.js vs Next.js

ทำการรวมสองหัวข้อเข้าด้วยกัน เนื่องจากเป็นสองเครื่องมือที่นำมาใช้คล้าย ๆ กันคือ การทำ Static Site Generator หรือ Static Site Content โดยเครื่องมือทั้งสองตัวมีแนวคิดและแนวทางเดียวกันต่างเพียงวิธีการ รวมทั้งมีข้อดีและเสียต่างกันไป ยกตัวอย่างเช่น Gataby.js จะเหมาะสมกับการเริ่มต้น เหมาะสำหรับ usecase ทั่วไปที่ไม่ยากและซับซ้อน ส่วน Next.js นั้นจะใช้กับ use case ที่เฉพาะทางและมีความซับซ้อนสูง แต่การใช้งาน Next.js ด้วยค่าพื้นฐานนั้น ประสิทธิภาพจะแย่มาก ๆ ดังนั้นจำเป็นต้องเอาแนวคิดจาก Gataby.js มาใช้ด้วย ทั้งเรื่องของ Data splitting และ pre-fetch
ดังนั้นการใช้งานแนะนำให้นำแนวคิดจากทั้งสองมาใช้งาน เพื่อสร้างสิ่งที่เราต้องการขึ้นมาตามงานนั้น ๆ ไป Build app, Not War

หัวข้อที่สี่คือ ประสบการณ์การใช้งาน GraphQL บน production

อธิบายสิ่งที่น่าสนใจ 3 เรื่องคือ
  1. ​การออกแบบเพื่อให้มีความปลอดภัย
  2. การจัดการและดูแลรักษาที่ง่าย
  3. การ monitoring ระบบ
การออกแบบเพื่อให้มีความปลอดภัยนั้นสำคัญมาก ๆ ทั้งเรื่องของการออกแบบ type อย่าให้มี circular type รวมทั้งจำกัดขนาดสูงสุดของ response ที่จะส่งกลับไปด้วย มิเช่นนั้นระบบน่าจะถูกระดมยิง และ ล่มได้เลย ต่อมาเรื่องการดูแลรักษาไฟล์ resolver ซึ่งจะประกอบไปด้วย type จำนวนมาก ถ้าระบบเรามีเพียงไฟล์เดียวแล้ว ทำให้การดูแลรักษายากมาก ๆ ดังนั้นแยกกันซะ แล้วตอน build ค่อยนำมารวมกัน นั่นคือการใช้งาน Split schema เรื่องสุดท้ายคือ การ monitoring ระบบ ซึ่งแนะนำให้ใช้งาน Apollo engine แนะนำให้อ่าน Best Practice of GraphQL เพิ่มเติม

หัวข้อที่ห้า KotlinJS love React

เป็นอีกหัวข้อที่แปลกแหวกแนว เนื่องจาก Kotlin นั้นคือภาษาที่ทำงานบน JVM (Java Virtual Machine) แต่ว่าตั้งแต่ Kotlin 1.2 ขึ้นมานั้นมี Kotlin Multi-Platoform ซึ่งทำให้สามารถแยก common code ออกมาอยู่ตรงกลาง จากนั้นเราก็สามารถเขียน code ด้วยภาษา Kotlin ตามแต่ละ device ได้เช่น KotlinJS สำหรับการทำงานผ่าน browser Kotlin สำหรับ Android และ Application ทั่วไป ที่สำคัญ Kotlin นั้นถูกประกาศให้เป็น Official Language ของ Android app ด้วยนะ
อีกสิ่งที่สำคัญ web ของ Kotlin นั้นพัฒนาด้วย React ด้วยนะ รวมทั้งได้สร้างเครื่องมือชื่อว่า Create React Kotlin App สำหรับสร้าง react app ด้วย KotlinJS
สำหรับตัวอย่างของ Multi-platform ด้วย Kotlin สามารถดูได้จาก Kotlin Academy App

หัวข้อที่หก ผมขอเปลี่ยนชื่อเป็น สวัสดี Clojurescript

เป็นอีกหัวข้อทางเลือกสำหรับการพัฒนา web application ด้วยแนวทางใหม่ ๆ นั้นคือ Clojurescript ซึ่งมีพื้นฐานมาจากภาษา Clojure นั่นเอง ซึ่งตัวภาษาบอกไว้ว่า
  • ​Simplicity
  • Data-oriented
  • Pure function
ดังนั้นเมื่อนำมาเขียน web application แล้ว จะยิ่งช่วยเหลือและจัดการปัญหาต่าง ๆ ได้เยอะ เช่นการนำ Redux มาใช้ มันก็คือการนำเอาแนวคิดของภาษา Clojure มาพัฒนาในรูปแบบของ JavaScript นั่นเอง แต่จะดีกว่าไหม ถ้ามาเขียนด้วย Clojurescript ไปเลย แต่ปัญหาอย่างหนึ่งคือ เรื่องของตัวภาษานั่นเอง ที่อาจจะต้องปรับตัวและทำความเข้าใจกันหน่อย แต่ผมเชื่อว่า ถ้าผ่าน JavaScript มาได้หรือทนมาได้แล้ว Clojurescript ไม่น่ายากนะ !!
ติดตามดูบรรยากาศของงานได้จาก #reactbkk ได้เลย ส่วนถ้าใครอยากดูแบบสด ๆ ทาง Gucode ก็มีให้ด้วย

สรุปเนื้อหาในช่วงบ่ายของงาน React Bangkok 3.0.0

$
0
0

เนื่องจากเนื้อหาของงาน React Bangkok 3.0.0 นั้นเยอะและแน่นมาก จึงทำการแยกเนื้อหาในช่วงบ่ายออกมาเป็น blog ที่สอง ดูรายละเอียดของ session ช่วงเช้าได้ ซึ่งประกอบไปด้วยหัวข้อดังนี้
  • การจัดการ State ด้วย MobX
  • Animating in React (ภาษาอังกฤษ)
  • ว่าด้วยเรื่อง React Design Pattern
  • ประสบการณ์ในการใช้งาน Expo และ GraphQL
  • ประสบการณ์การพัฒนาระบบงานด้วย React ของ Telenor
  • การ Tuning performance ของ React app
  • การทดสอบสำหรับ React app
  • ว่าด้วยเรื่องการจัดการ State ของ React app ประเด็นคือเลือกใช้แต่ละอย่างด้วยเหตุผลอะไร
ทำการสรุปแบบสั้น ๆ ไว้นิดหน่อย มาดูกันเลย

เรื่องแรก การจัดการ State ของ React App

เนื่องจากในช่วงบ่ายนั้นมี session ที่พูดถึง การจัดการ State ใน React app เยอะมาก เนื่องจากมีวิธีการและ library เพียบ ยกตัวอย่างเช่น
  • React เพียว ๆ นั่นคือใช้ props นั่นเอง
  • Redux และผองเพื่อน
  • MobX
ประเด็นสำคัญคือ เราทำการเลือกใช้งานสิ่งต่าง ๆ เหล่านี้ด้วยเหตุผลอะไร ? ความชอบ ? อยากใช้ ? ตามคนอื่น ? ตามความนิยม ? รู้แค่ตัวเดียว ? สิ่งที่น่าสนใจจาก session สุดท้ายคือ พยายามอธิบายว่า ก่อนที่เราจะเลือกใช้อะไรนั้น ควรต้องเข้าใจเป้าหมายทาง business ของระบบ จากนั้นต้องรู้ว่า ระบบเรานั้นมี data-flow ที่ใช้งานนั้นเป็นอย่างไร ? ยกตัวอย่างเช่น ถ้าระบบงานมีข้อมูลที่ใช้งานแยกกันหรือแบ่งตามหน้าจอแล้ว การใช้งานเพียง React เพียว ๆ หรือใช้งาน MobX ก็เพียงพอ แต่ถ้าข้อมูลในหนึ่งหน้ามีการใช้ข้อมูลจำนวนมาก ๆ แล้ว และมีการ share ข้อมูลระหว่างหน้าเยอะมาก ๆ ดังนั้นการนำ Redux มาใช้น่าจะเหมาะสมกว่า ดังนั้นคำถามแรกคือ คุณรู้และเข้าใจข้อมูลที่ระบบต้องการหรือไม่ ?
สรุปคือ รู้ตัวเอง รู้ความต้องการ จากนั้นจึงเลือก

เรื่องที่สอง Animating in React

เป็น session ที่น่าสนใจมาก ๆ และ unique มาก ๆ เพราะว่า ไม่มีงานไหนพูดเรื่องของการจัดการ animation เลย เนื้อหาหลัก ๆ ประกอบไปด้วย
  1. ​ต้องรู้ปัญหาของการทำ animation
  2. การสื่อสารเรื่องของ animation ออกไป แยกออกเป็น trigger -> action -> quality
  3. การพัฒนา ซึ่งมี library เยอะมาก ๆ ทั้งแบบ native และ 3-party library
มาดูรายละเอียดกัน สิ่งที่สำคัญมาก ๆ คือ ปัญหาที่เกิดจากการทำ Animation ซึ่งเราต้องรู้และจัดการให้ได้ทั้ง
  • เมื่อใดที่ animation จะทำงานเสร็จ (Done)
  • เมื่อใดที่ animation กำลังทำงานอยู่ (In progress)
  • Animation ทำงานงานเท่าไร (How long ?)
  • ผู้ใช้งานไม่ต้องการรอ จัดการอย่างไร
  • ต้องแสดงสิ่งที่ผู้ใช้งานต้องการจะเห็นก่อนเสมอ
  • Animation ที่ดีต้องมีความเป็นธรรมชาติ
  • Animation ต้องไม่น่าเบื่อ !!
เรื่องที่สองคือ เราจะสื่อสารเรื่องของ animation ออกไปอย่างไร ซึ่งใน session แบ่งออกเป็น 3 ส่วนคือ ส่วนที่ 1 คือ Trigger นั่นคือจะเกิดเหตุการณ์ต่าง ๆ อย่างไร เช่นเมื่อ page loaded เสร็จแล้ว และการกดปุ่มเป็นต้น ส่วนที่ 2 คือ Action สิ่งที่จะต้องทำหลังจากที่เกิดเหตุการณ์ต่าง ๆ ขึ้นมา ตรงนี้นั่นเองที่เราต้องพัฒนาขึ้นมา ส่วนที่ 3 คือ Quality ว่าด้วยเรื่องของคุณภาพของ animation ที่สร้างขึ้นมา ทั้งใช้เวลาการทำงานเท่าไร ทั้งการทำงานของ animation เป็นธรรมชาติหรือไม่ ทั้งการใช้งานง่ายหรือไม่ ทั้งประสิทธิภาพของการทำงานเป็นอย่างไร ซึ่งจะสอดคล้องกับ property ที่เลือกใช้งาน เช่น สี ขนาด และ ตำแหน่งเป็นต้น เรื่องที่สามคือ การพัฒนา โดยสามารถพัฒนาด้วย native library ได้ เช่น CSS, Canvas และ webGL เป็นต้น แต่การพัฒนาและจัดการไม่ง่ายเลย ดังนั้นจึงมี library ต่าง ๆ เกิดขึ้นมามากมายเช่น

เรื่องที่สาม ว่าด้วยเรื่องของ React Design Pattern

ปัญหาของการพัฒนาระบบส่สวนใหญ่คือ เมื่อระบบใหญ่ขึ้น จำนวน feature มากขึ้นแล้ว จำนวน code ก็เยอะขึ้น ถ้าจัดการและออกแบบ code ไม่ดีแล้ว อาจจะทำให้เกิดปัญหาในการดูแลรักษาก็เป็นได้ หรือเราอาจจะเรียก code ที่มีปัญหาว่า Legacy code หรือ Spaghetti code
ใน session ได้อธิบายวิวัฒนาการของ design pattern ที่ใช้งาน พร้อมอธิบายข้อดีข้อเสีย รวมทั้งแนวทางการแก้ไข มาดูกันว่ามีอะไรบ้าง
เริ่มต้นเราก็จะใช้งานตาม React standard ปกติ แต่เมื่อ code เยอะขึ้น จำนวน component เยอะขึ้น สิ่งที่เกิดขึ้นคือ ความซ้ำซ้อน เช่น เรามักจะมี Dumb component จำนวนมาก ในแต่ละ component อาจจะใช้ data ชุดเดียวกัน ในแต่ละ component อาจจะมี function การทำงานหรือพฤติกรรมการทำงานเหมือนกัน คำถามคือ เราจะลดความซ้ำซ้อนนี้ลงไปอย่างไร ? เพราะว่า มันเป็นปัญหาที่การพัฒนาระบบงานต้องพึงระวัง หนึ่งในวิธีการแก้ไขจาก session คือ HOC (Higher-Order Component) เป็นรูปแบบของ function ที่รับ component เข้าไป แล้วได้ component ใหม่ออกมาพร้อมกับข้อมูลที่จำเป็นต่อการใช้งาน แต่ก็ยังมีข้อเสีย เมื่อ component มีความซับซ้อน เช่น A -> B -> C-> D โดยที่ A ต้องส่งข้อมูลบางอย่างไปให้ D แต่ B กับ C ไม่ใช้งาน ทำให้เกิดงานที่ไม่จำเป็นจำนวนมาก การตั้งชื่อก็สำคัญมาก ๆ สำหรับ HOC ถ้าตั้งชื่อแย่แล้ว ของที่ดี ๆ จะเสียหมดเลย รวมไปถึงชื่อ props ต้องต่างกันด้วยนะ ไม่งั้นเกิดปัญหาแน่ ๆ (Props collision) ยังไม่พอนะ ถ้าใช้งานผิดทาง ซึ่งเกิดได้ง่ายมาก จะทำให้มีแต่ปัญหามากกว่าประโยชน์ ดังนั้นต้องใช้งานอย่างระมัดระวัง อย่างเข้าใจ ใน session จึงขอแนะนำวิธีการใหม่ ๆ คือ Function as Children หรือ Render Props วิธีการนี้ใช้ความสามารถของ props ซึ่งสามารถส่งข้อมูลชนิดอะไรไปก็ได้ วิธีการนี้จึงทำการส่ง function ผ่าน props เข้าไปยัง Child component นั่นเอง ดังนั้นในการออกแบบ React component จะแบ่งเป็นดังนี้
  • Parent component จะมี function การทำงาน เช่นการดึงข้อมูล เป็นต้น
  • Child component หรือ Dumb component ทำการรับ function ผ่าน props จาก Parent component
ใน session ยังได้บอกอีกว่า จะใช้วิธีการใดก็ตาม แนะนำให้เข้าใจมันจริง ๆ รวมทั้งทีมต้องเข้าใจด้วย ถ้าทำงานเป็นทีม ปิดด้วยให้สร้าง Dumb component (Stateless component) ให้เยอะที่สุด
แต่ทั้งหมดทั้งมวลใช้ React Context ก็ได้นะ ซึ่งมันเป็น Render props นี่แหละ ลองใช้งานกันดูได้

เรื่องที่สี่ การ Tuning performance ของ React app

เป็นการแบ่งปันประสบการณ์ของการปรับปรุงประสิทธิภาพการทำงานของ React app ซึ่งเป็นระบบที่พัฒนาด้วย Apache Cordova นั่นคือ Hybrid app นั่นเอง (iOS และ Android) โดยเลือกใช้ React ในการเขียน เมื่อเริ่มต้นพัฒนานั้น ทุกสิ่งอย่างดูสวยงาม น่าพัฒนาอย่างมาก ทำงานเร็วมาก แต่เมื่อเวลาผ่านไประบบทำงานช้าลงมาก code แก้ไขยากมาก ระบบงานแย่ลงอย่างต่อเนื่อง ดังนั้นจึงเข้าสู่จุดเริ่มต้นของการปรับปรุง code กันแล้ว เริ่มจากต้องทำความรู้และเข้าใจการทำงานของระบบกันก่อน ด้วย Google Chrome Dev Tools และ React Perf Dev Tools จากนั้นจึงลงมือแก้ไขปัญหากัน ใน session สรุปปัญหาที่แก้ไขมาให้ดูดังนี้
  • ทำการ render ใหม่ทั้งหมดเมื่อข้อมูลตัวใดตัวหนึ่งเปลี่ยนแปลง ด้วยการใส่ key label และ shouldComponentUpdate และทำการ caching ข้อมูลพวก state และ props ด้วย React Memoize
  • ทำการ mount ข้อมูลที่จะถูกแสดงผลในหน้าจอเท่านั้น ด้วยการใช้งาน React Virtualized

เรื่องที่ห้า การทดสอบ React App

เป็นอีกเรื่องที่พูดถึงกันน้อยมาก แต่ทุกครั้งในงาน React Bangkok จะมีเรื่องนี้เสมอ โดยในครั้งนี้ session ประกอบไปด้วยหัวข้อต่าง ๆ ดังนี้ ทำไมถึงต้องทดสอบ ? เพื่อช่วยให้การแก้ไขระบบเร็วขึ้น ถ้าชุดการทดสอบดีนะ เพื่อช่วยอธิบายการทำงานของ code ในส่วนต่าง ๆ สุดท้ายที่สำคัญมาก ๆ คือ เพิ่มความมั่นใจต่อระบบนั่นเอง (Confidence) โดยใน session นี้จะเน้นในเรื่องของ confidence เป็นพิเศษ ทำการอ้างอิงไปยัง Test Pyramid ประกอบไปด้วย Unit, Integration และ UI test คำถามที่ตามมาคือ ทำไมไม่ทดสอบแต่ Unit test ไปเลย ? เพราะว่า ทำงานก็เร็ว ค่าใช้จ่ายก็ถูกกว่า คำตอบคือ เรื่องของความเชื่อมั่นล้วน ๆ ไงละ ยิ่งทดสอบในระดับที่สูงขึ้น ทั้ง Integration และ UI test ยิ่งเพิ่มความเชื่อมั่นให้สูงขึ้น โดยใน session แนะนำให้ทดสอบในระดับ integration ขึ้นมา และอย่าลงไปทดสอบในระดับ detail of implementation มากไป เพราะว่า ถ้าเปลี่ยนนิดหน่อย ก็จะทำให้ชุดการทดสอบพังเยอะมาก ๆ ดังนั้นให้ทดสอบผ่าน API/Interface แทนจะดีกว่า รวมทั้งเน้นว่า ให้ทดสอบจากมุมมองของผู้ใช้งานเป็นหลัก เครื่องมือและ library ที่ใช้ประกอบไปด้วย ​Enzyme และ React DOM โดยตามจริงใช้เพียง React DOM ก็ได้ และใช้งานร่วมกับ react-testing-library ช่วยทำให้เข้าถึง element ต่าง ๆ ได้ง่ายและสะดวกมากยิ่งขึ้น
ปิดท้ายด้วยเครื่องมือสุดแจ่มคือ Cypress  คือ End-to-End test framework สำหรับ JavaScript ซึ่งประกอบไปด้วย library ที่จำเป็นต่อการทดสอบมาให้ครบ เช่น Mocha, Chai และ Sinon เป็นต้น รวมทั้งมีความสามารถที่จำเป็นเช่น Screenshot และ VDO record การทดสอบ

ปิดด้วยการประกาศจากผู้จัดงานว่า

ไม่มีอีกแล้วสำหรับงาน React Bangkok เจอกันกับ JavaScript Bangkok ในครั้งต่อไป

ว่าด้วยเรื่องของ Burnout Programmer

$
0
0

เพิ่งคุยเล่น ๆ กับกลุ่ม programmer นิดหน่อย ได้พูดคุยเรื่องของ Burnout Programmer ว่าเป็นอย่างไร ? เป็นเรื่องที่น่าสนใจมาก ๆ และมันอาจจะกลายเป็นปัญหาและวิกฤติได้เลย (หรือเป็นอยู่แล้ว) ประเด็นหลัก ๆ ที่คุยกันคือ ปัญหาของการ burnout มีอะไรบ้าง ?

Programmer มีความรู้สึกเหล่านี้ไหม ?

รู้สึกขี้เกียจที่จะไปทำงาน ไม่อยากทำอะไรเลย แต่อยากมีงานทำ ตอนเช้าก็เข้างานสาย หรือมาเร็วแต่ลงไปร้านกาแฟนาน ๆ ตอนเที่ยงก็ลงเร็วกลับมาทำงานช้า บ่าย ๆ มีพัก break ยาว ๆ และตอนเย็นก็รีบกลับ พูดง่าย ๆ คือ มาสายกลับเร็ว งานไม่ค่อยอยากจะทำ แต่กลัวไม่มีงานทำ เพราะว่าไม่รู้ว่าจะไปทำงานอะไรที่ไหน แต่จะทำงานสาย programming ก็เหนื่อย ไม่อยากทำอีกเลย !! สุดท้ายไปทำอย่างอื่นดีกว่า !! ขอแสดงความยินดี เราได้สูญเสีย programmer ไปอีกคนแล้ว

สาเหตุมาจากอะไรบ้างนะ ?

ทำงานเดิม ๆ ซ้ำแล้วซ้ำเล่า เป็นเดือน เป็นปี ใช้แต่เทคโนโลยีเดิม ๆ ไม่เปลี่ยนแปลง จนทำให้รู้สึกเบื่อ ไม่ว่าจะกี่งานก็มี deadline มากำหนดตลอด นั่นคือ คนทำไม่ได้คิด คนคิดไม่ได้ทำ แถมคนที่ไปรับงานมาก็ไม่ได้ปฏิเสธอะไรเลย ทำงานแบบเร่งรีบ หามรุ่งหามค่ำ มีแต่งานเร่ง งานด่วน และงานด่วนมาก ส่วนคนที่ไม่ได้ทำก็เร่งจัง จิกจัง เร่งมาก ๆ ก็มักจะผิดพลาด ก็โดนทั้งขึ้นทั้งร่อง ต้องทำงานแบบหามรุ่งหามค่ำมาอย่างยาวนาน ซึ่งส่งผลกระทบต่อการใช้ชีวิตอย่างมาก เพราะว่าเวลามีแต่งานที่ต้องทำ ยิ่งเวลาไปผ่านไปนาน ร่างกายและจิตใจที่เหนื่อยล้า ทำงานเยอะ กินถ่ายไม่เป็นเวลา ไม่มีเวลาออกกำลังกาย ไม่สนใจตัวเอง ส่งผลคือ สุขภาพแย่ลงเรื่อย ๆ สิ่งที่หนักมาก ๆ คือ ทำงานใหญ่ ๆ ยาก ๆ แล้วผลที่ออกมาคือ พัง หรือ ไม่สำเร็จ จนทำให้รู้สึก fail กับการทำงานไปทั้งหมด ไม่อยากทำงานเหล่านั้นอีกแล้ว
แล้วเราจะแก้ไขปัญหาเหล่านี้ได้อย่างไรบ้างนะ ?
Reference Websites https://hackernoon.com/what-is-programmer-burnout-651aa48984ef https://medium.com/@karolisram/preventing-burnout-for-programmers-12b4968adbaa https://simpleprogrammer.com/avoiding-burnout-software-developer/

สรุปเรื่องของการพัฒนา Testable application ด้วยภาษา Go

$
0
0

มีโอกาสมาแบ่งปันความรู้เรื่อง การพัฒนาระบบด้วยภาษา Go ให้พัฒนาได้ง่าย ให้ทดสอบได้ง่าย ให้ดูแลได้ง่ายขึ้น โดยสิ่งที่แบ่งปันประกอบไปด้วย
  • เรื่องของโครงสร้างที่ต้องชัดเจน
  • เรื่องของหน้าที่การทำงานของแต่ละส่วน
  • เรื่องแนวคิดในการทดสอบ เพื่อเพิ่มความมั่นใจที่มีต่อระบบ
  • เรื่องแนวทางการพัฒนาด้วยภาษา Go
  • เรื่องของเครื่องมือและ library ต่าง ๆ ที่นำมาใช้งาน

ในแต่ละ project หรือบางครั้งอาจจะแบ่งเป็น service เล็ก ๆ

สิ่งที่สำคัญมาก ๆ คือ โครงสร้างของระบบงานที่ชัดเจน ในแต่ละระบบควรมีโครงสร้างไปในทิศทางเดียวกัน เพื่อให้ง่ายต่อการพัฒนาและการดูแล (ยิ่งทำงานเป็นทีมยิ่งสำคัญ) ผมจะอ้างอิงโครงสร้างมาจาก Microservices Testing โดยโครงสร้างที่แนะนำก็ประกอบไปด้วย
  • Controller/API/Handler/Router ทำการรับ request และส่งผลการทำงานกลับไปยังผู้เรียก
  • Service/Business flow สำหรับจัดการ flow การทำงานตาม business
  • Repository/Data Access Object สำหรับการจัดการข้อมูลใน Database
  • Gateway สำหรับการติดต่อผ่าน HTTP/TCP protocol
โดยแต่ละส่วนนนั้นจะต้องมี interface คั่นเสมอ นั่นคือ ControllerInterface -> Controller -> ServiceInterface -> Service -> RepositoryInterface -> Repository
อาจจะเยอะหน่อยนะ แต่สิ่งที่ได้รับกลับมาคือ สามารถแยกการทำงานแต่ละส่วนออกจากกันอย่างชัดเจน ส่งผลให้สามารถแยกทดสอบได้ง่ายขึ้น นั่นคือ ทำให้เรามีความมั่นใจต่อ code มากขึ้นด้วย

เมื่อแยกได้ ก็ต้องเขียน code ได้สิ !!

ดังนั้นมาลงมือเขียน code กันดวยภาษา Go แยกการทดสอบเป็นแต่ละส่วน พร้อม library ที่ใช้งานดังนี้ Repository หรือ Data Access Object ผมเลือกใช้งาน go-sqlmock สำหรับการจำลอง Database ที่ใช้งาน ซึ่งช่วยให้การทดสอบมีความยืดหยุ่มมากขึ้น เนื่องจากสามารถจำลองการทำงานของ Database ได้ทุกสถานการณ์ ทั้งการทำงานแบบปกติ ทั้งการทำงานแบบ fail/error ทั้งการค้นหาข้อมูลไม่เจอ ทั้งข้อมูลไม่ถูกต้องตามที่ต้องการ แต่สิ่งที่แนะนำได้คือ ถ้าสามารถควบคุม Database ได้ ก็ไม่จำเป็นต้องใช้พวก library เหล่านี้ก็ได้ เพราะว่า จะทำให้เรามั่นใจได้มากกว่า หนึ่งในการควบคุมก็คือ การใช้ Container มาช่วย Service หรือ Business flow ผมเลือกใช้งาน Interface ปกติมาใช้งานไม่มีอะไรซับซ้อน เนื่องจากในแต่ละส่วนจะคั่นด้วย interface อยู่แล้ว ส่วนการสร้าง instance นั้น จะต้องผ่าน method NewXXXService() เท่านั้น เพื่อกำหนดให้การสร้างมีรูปแบบเดียวกัน จากนั้นในส่วนของการทดสอบก็ mock กันไปเลย Controller หรือ API หรือ Handler หรือ Router ในส่วนนี้สามารถทดสอบได้หลายแบบ ทั้งการทดสอบเฉพาะการทำงานของ Controller หรือจะทดสอบแบบ end-to-end ก็ได้ เอาที่สบายใจ โดยสิ่งที่แนะนำไปคือ การทดสอบเฉพาะ Controller ก่อน จากนั้นทำการตัด dependency หรือสิ่งที่ Controller ใช้งานออกไป ซึ่ง Controller จะใช้งาน Service ต่าง ๆ ดังนั้น จึงทำการตัด Service เหล่านั้นไปด้วยการ mock ผ่าน interface เช่นเดิม แล้วทำการส่งหรือ Inject Service เหล่านั้นผ่าน Controller อีกที ทำให้เราสามารถทดสอบการทำงานของ Controller ได้แล้ว โดยไม่ต้องใช้ library ข้างนอกเลย

ในส่วนของการทดสอบนั้นได้นำ library testify มาใช้

เนื่องจากมี assertion ที่ใช้งานง่ายและอ่านสบาย รวมทั้งมีเรื่องของ mock ให้ใช้ด้วย หรือต้องการความสวยงามตาม style BDD ก็แนะนำ Ginkgo ได้ ปิดท้วยด้วยการ run test และดูค่า coverage ด้วย เพื่อให้เรารู้ว่า code บรรทัดไหนที่ยังไม่ทำการทดสอบ
วันนี้เขียน test กันหรือยัง ?
โดย code ตัวอย่างและ slide อยู่ที่ github:Up1::go-testable ขอให้สนุกกับการเขียน code ครับ

ระบบที่ดีควรมีสิ่งต่าง ๆ เหล่านี้บ้างนะ

$
0
0

ระหว่างรอรถกลับบ้าน ทำการสรุปสิ่งที่จำเป็นต่อการพัฒนาระบบงาน แต่ในปัจจุบันเราพยายามแยกระบบงานใหญ่ออกเป็น service เล็ก ๆ หรือบางคนอาจจะเรียกว่า Microservices สิ่งที่น่าสนใจคือ ในการพัฒนาระบบงานนั้น เราต้องคำนึงถึงอะไรบ้าง

Interface สำหรับการเชื่อมต่อกับ service หรือระบบอื่น ๆ

ซึ่งมีหลากหลายมาก ๆ เช่น
  • JSON
  • JSON-RPC
  • Thrift
  • Protocol Buffers
รวมไปถึง Protocol ของการติดต่อสื่อสาร โดยในปัจจุบันก็จะใช้ REST และ RPC ส่วน WebService ก็เห็นมีบ้างนะ แต่อาจจะมี overhead สูงหน่อย หรืออาจจะมี Legacy Protocol ซึ่งนิยมนำเอา 3 protocol ด้านบนมาครอบอีกชั้น !!

Pattern หรือรูปแบบที่ระบบงานน่าจะต้องมี

ยิ่งในโลกของ Microservices ยิ่งจำเป็นและมีการพูดคุยกันมา ยกตัวอย่างเช่น
  • Circuit breaking ถ้าปล่อยให้ผู้ใช้เรียก service ที่ทำงานแย่ ๆ เช่น ทำงานช้า ใช้ memory เยอะ ๆ คงไม่ดีแน่นอน
  • Service discovery/registry ถ้ามี service จำนวนมาก ๆ การนำ service เข้าและออก แบบง่าย ๆ น่าจะดีไม่น้อย รวมทั้งสามารถดูได้ด้วยว่ามี service อะไรบ้าง ก็น่าจะแจ่มมาก ๆ คนใช้งาน service ก็มีหาและเชื่อมต่อ service จากที่นี่เลย One Stop Service ชัด ๆ แต่ระวังเรื่อง Single Point of Failure นะ ย้อนกลับไป SOA มันก็คุ้น ๆ นะ
  • Health check ในทุก ๆ service หรือทุก ๆ ระบบควรมี health check เสมอ ทั้ง readiness และ liveness
  • Timeout ขาดไม่ได้เลย สำหรับการเชื่อมต่อไปยังส่วนต่าง ๆ ซึ่งต้องสามารถ configuration ได้ง่าย ไม่ใช้ไปแก้ไข code ตรง ๆ นะ
  • Load balancing สิ่งที่ควรต้องมีในการเรียกใช้ service จาก client ปัจจุบัน Load balance มีอยู่ในฝั่ง client หรือผู้เรียกใช้งานกันแล้ว
  • Routing สิ่งที่เราเลือกใช้งานนั้น จำเป้นต้องมีการจัดการ routing ที่ง่ายและยืดหยุ่น ทั้งแบบ static และ dynamic
  • Application monitoring ของระบบงาน ในแต่ละ flow และ scenario ในมุมมองของผู้ใช้งานและการทำงานของระบบงาน ไม่ใช่ Server หรือ System monitoring นะ
คำถามที่น่าสนใจคือ service หรือระบบของเรามีสิ่งต่าง ๆ เหล่านี้หรือไม่ ? ไม่ว่าจะพัฒนาด้วยภาษา program และ framework อะไร สิ่งต่าง ๆ เหล่านี้จำเป็นต้องมีเสมอ

เครื่องมือสำหรับจัดรูปแบบ code และ naming convention ในภาษา Go

$
0
0

เรื่องของรูปแบบ code และ naming convention เป็นสิ่งที่สำคัญมาก ๆ โดยในภาษา Go นั้นไม่ได้มีกฏเรื่องนี้มากนัก แต่ก็ได้สร้างเครื่องมือมาตรฐานสำหรับการจัดการมาให้ นั่นก็คือ gofmt ซึ่งนักพัฒนาภาษา Go น่าจะใช้กันทุกคน ไม่ว่าจะพิมพ์เอง ไม่ว่าจะให้ทำงานแบบอัตโมัติ หรือ ทำงานผ่าน Editor/IDE ต่าง ๆ เช่นทำการจัดรูปแบบ code ให้เมื่อทำการบันทึกเป็นต้น ผลที่ตามมาคือ รูปแบบของ code เหมือนกัน ไม่ต้องมาเถียงกัน และยังทำให้ code อ่านง่ายขึ้นอีกด้วย [code] $gofmt -w file.go $gofmt -w target_folder [/code] คำอธิบาย
  • -w ทำการแก้ไขและเขียนทับไปเลย
  • -d แสดงสิ่งที่แตกต่างระหว่างก่อนและหลังการใช้งาน

สิ่งที่ยังขาดไปคือ เรื่องของ naming convention

นั่นคือการตั้งชื่อทั้ง variable, constant, function, struct และ interface ซึ่งก็มีเครื่องมือชื่อว่า golint มาให้ใช้งาน จะแสดงว่า รูปแบบที่เราเขียนนั้นผิดตรงไหนบ้าง ซึ่งไม่มีใน gofmt น่าจะทำให้ code ของทีมไปในทิศทางเดียวกันทั้งหมด ที่สำคัญสามารถทำงานร่วมกับ Editor/IDE ทั่วไปได้เลย Golint นั้นเป็นเครื่องมือที่ทำการตรวจสอบด้วยกฏต่าง ๆ จาก มันคือแหล่งเรียนรู้ที่ดีมาก ๆ มาลองใช้งานกันดู ติดตั้งผ่าน go get [code] $go get -u golang.org/x/lint/golint [/code] มี code ตัวอย่างง่าย ๆ ลองเดาดูสิว่า golint จะด่าอะไรบ้าง ? [gist id="37b4186c2b88d74f5ca36d4c4a967818" file="main.go"] ผลที่ได้จาก golint เป็นดังนี้ [gist id="37b4186c2b88d74f5ca36d4c4a967818" file="result.txt"] คำอธิบายเพิ่มเติม ชื่อ function ขึ้นด้วยตัวใหญ่คือ เราตั้งใจให้เป็น public หรือให้ file อื่นที่อยู่ต่าง package ใช้งานได้ ดังนั้นสิ่งที่ควรต้องทำคือ การเขียน comment เพื่ออธิบายนั่นเอง จากนั้นก็แก้ไขซะ ให้เป็นไปตามรูปแบบของตัวภาษา เพียงเท่านี้การเขียน code ก็สนุกขึ้นอีกเยอะเลย
วันนี้ใช้งาน gofmt และ golint กันหรือยัง ?

ว่าด้วยเรื่องของ Law of Demeter

$
0
0

หลังจากทำการ review code ไปนิดหน่อย พบว่าได้เจอ code ที่น่าสนใจ เนื่องจากจะขัดกับ Law of Demeter พอควร ผลที่ตามมาคือ code ทำงานได้ แต่มีการเรียกต่อกันเป็นทอด ๆ ยาวมาก ๆ ยกตัวอย่างเช่น game.Board.Size.X และ g.Board.Slots[i][j].Number เป็นต้น แต่ตามจริงเราต้องการเพียงค่าสุดท้ายเท่านั้นเอง ทำไมเราต้องเขียน code ยาวขนาดนี้กันด้วย ? น่าคิดมาก ๆ หรือเราคิดว่า มันคือเรื่องปกติ เพราะว่า โครงสร้างของระบบเราเป็นแบบนี้ ? ดังนั้นมาปรับปรุง code ชุดนี้กันหน่อยดีไหม ?

เริ่มต้นด้วยการทำความเข้าใจกับ Law of Demeter

ง่าย ๆ คือ เราสามารถเรียกใช้งาน method จาก class ที่ต้องการตรง ๆ ได้เลย ไม่ต้องอ้อมค้อม ยกตัวอย่างเช่น ต้องการดึงข้อมูลที่อยู่ของพนักงานก็ใช้ผ่าน employee.getAddress() ได้เลย จะไม่มีการเรียกซ้อนกันไปเยอะ ๆ (Chain of message) ดังเช่นตัวอย่างเช่น employee.getAddress().getCountry().getName() employee.getAddress().getProvince().getName() employee.getAddress().getCurrentAddress() ผลเสียที่ตามมาคือ class ต่าง ๆ จะผูกมัดกันอย่างมาก เมื่อจะแก้ไขอะไรก็ตาม จะกระทบกันมากมาย อารมณ์คล้าย ๆ โครงสร้างขององค์ที่ที่มีลำดับชั้นเยอะ ๆ นั่นเอง เขียน code ก็เยอะ แก้ไขอย่างไรดี ? ถ้าสร้าง method ใน employee เพื่อส่งค่าที่ต้องการออกมาเลยดีไหม ? employee.getCurrentAddress() employee.getAddressCountry() employee.getAddressProvince() มุมมองของคนเรียกใช้งาน จะได้ไม่ต้องสนใจว่า employee ใช้งานอะไรบ้าง เพื่อแค่เรียก method ที่มีใน employee ก็ใช้ได้เลย ง่ายกว่าไหม ? อันนี้คงต้องตอบกันเองแล้วนะ

กลับมาดูในภาษา Go กันบ้าง

การใช้งาน struct มักจะมีการใช้งาน embedd type หรือ struct ซ้อน struct นั่นเอง แต่พอมาเจอ code จริง ๆ มีซ้อนกันจำนวนมาก ลึกมาก ๆ [gist id="28ccd86fe3ecf3d0d0ab211505adf1a4" file="1.go"] ถ้าต้องการดูข้อมูลของ state ต้องเรียกใช้งานผ่าน game.board.state แต่เราต้องการเพียง state นะ ดังนั้นมาแก้ไขกัน เพราะว่าเราเปิดเผยการทำงานมากไป การแก้ไขมีทั้งลบทิ้งไป กับทำการซ่อนไปซะ ตัวอย่างเป็นการซ่อนดังนี้ [gist id="28ccd86fe3ecf3d0d0ab211505adf1a4" file="2.go"] นี่เป็นเพียงการแก้ไขหรือปรับปรุง code ให้ดีขึ้นมาอีกนิด น่าจะทำให้ทีมเข้าใจ code ได้ง่ายขึ้น แต่ code จะดีเพียงใด แต่คนในทีมไม่เข้าใจ ก็ไร้ค่านะครับ ขอให้สนุกกับการเขียน code ครับ

เรียนรู้ภาษา Go สำหรับ NodeJS Developer

$
0
0

เห็นว่า NodeJS กำลังร้อนแรง เลยขอนำเสนอวิธีการเรียนรู้ภาษา Go สำหรับ NodeJS Developer กันหน่อย (เกี่ยวกันไหมนะ ?) ซึ่งเป็นการเรียนรู้ตามสิ่งที่ชาว NodeJS ต้องรู้และใช้งานเป็นปกติ แต่มาดูกันว่า ถ้าใช้ภาษา Go ต้องทำอย่างไรบ้าง น่าจะทำให้เรียนรู้ง่ายขึ้น

ก่อนอื่นต้องเข้าใจก่อนว่า

แต่ละภาษาโปรแกรมมีเป้าหมายที่แตกต่างกัน ปัญหาที่เกิดจากภาษาหนึ่ง ๆ อาจจะแก้ไขด้วยอีกภาษาได้หรือไม่ก็เป็นไปได้ ไม่มีภาษาใดดีกว่าไปทั้งหมด มีแต่เหมาะสมกับงานนั้น ๆ หรือไม่ (เราจะรู้ได้อย่างไร มันก็ต้องลองใช้งานก่อนสิ ฟังมาไม่พอหรอกนะ)
แต่การจะพัฒนาระบบด้วยภาษาใหม่ทั้งหมดเลย เป็นสิ่งที่น่ากลัวและซับซ้อน วุ่นวายมาก ๆ อย่าทำเลยนะ ถ้าไม่จำเป็น แยกเป็นส่วนเล็ก ๆ มาทำจะดีกว่า
จะเอามาเทียบกันตรง ๆ ก็ไม่น่าเหมาะ เพราะว่าภาษามันสร้างด้วยเป้าหมายที่ต่างกัน เช่นจะพูดเรื่องของการใช้งาน Memory แน่นอนว่า Go มันใช้เล็กกว่าแน่ ๆ เพราะว่า มันเกิดมาเพื่อสิ่งนี้ การ deploy ก็เช่นกัน รวมไปถึงการ run บน Docker ซึ่งมักชอบพูดถึงขนาดของ Image ซึ่ง Go นั้นไม่ต้องการใช้อะไรเลย ดังนั้น Image ในการ deploy จึงเล็กมาก ๆ

ส่วน NodeJS มี ecosystem ที่ดีมาก ๆ

เขียนด้วยภาษา JavaScript มีชุดเครื่องมือและ library ดี ๆ จำนวนมาก ก่อให้เกิด productivity สูงมาก ๆ เพราะว่า เราจะ focus ไปที่ส่วนการแก้ไขปัญหาเชิง business มากกว่า technical เมื่อพูดถึง NodeJS แล้วน่าจะมี 3 เรื่องหลัก ๆ ที่น่าสนใจคือ
  • การจัดการ dependency ซึ่งจะมี npm กับ yarn
  • การทำงานแบบ asynchronous มีทั้ง async-await, Promise และ callback เป็นต้น
  • การสร้าง RESTful API
มาดูกันว่าในภาษา Go ตอบโจทย์เหล่านี้กันอย่างไรบ้าง ?

เรื่องที่ 1 การจัดการ dependency

สำหรับภาษา Go จะมีตัว default คือ go get และ Go 1.6 ขึ้นมาสนับสนุน vendor directory แล้ว ทำให้เราสามารถ copy พวก dependency ต่าง ๆ ที่ download ผ่าน go get มาไว้ใน project ได้ รวมทั้งยังมีเครื่องมืออื่น ๆ จาก community หลายตัวเลยทั้ง และยังมีให้เลือกอีกมากมาย Package Management Tool for Go คำถามที่น่าสนใจคือ ใช้ตัวไหนดี ตอบยากมาก ๆ ประเด็นคือต้องลอง ว่าตัวไหนถูกใจเรา เหมาะสมกับเรา ยกตัวอย่างเช่นผมก็ใช้แค่ go get และ vendor directory เท่านั้นเอง แต่ถ้าตัวที่คล้ายกับ npm ใน NodeJS ก็คือ deps นั่นเอง มีการกำหนด library ที่ต้องใช้งานเหมือนกัน (package.json => toml) มี lock file เหมือนกัน (package-lock.json => toml) มีการ download ไว้คล้าย ๆ กันคือ node_modules directory แต่ deps เอาไว้ใน vendor directory

เรื่องที่ 2 การทำงานแบบ asynchronous

เป็นเรื่องธรรมชาติของ NodeJS ตัวอย่างเช่นการอ่านไฟล์ [gist id="4b666dfc648a0a511b4f464c88a3e14b" file="read_file.js"] แต่สำหรับภาษา Go นั้น จะทำงานแบบ sync เป็นปกติ ซึ่งเขียนได้แบบนี้ [gist id="4b666dfc648a0a511b4f464c88a3e14b" file="read_file.go"] แต่เราต้องการให้ทำงานแบบ async นะ ดังนั้นต้องใช้ความพยายามกันหน่อย โดย Go จะมี Go routine และ Channel ให้นะ แต่ต้องรอให้ทำงานจบก่อน ไม่เช่นนั้นจะไม่ได้ค่าอะไรออกมาเลย หรือจะใช้งานพวก errorgroup มาจัดการก็ได้นะ สบายขึ้นเยอะ [gist id="4b666dfc648a0a511b4f464c88a3e14b" file="read_file_async.go"] เพียงเท่านี้ก็จัดการได้ตามที่ต้องการแล้ว ง่ายไหมละ ? ไม่ง่าย ...

เรื่องที่ 3 การสร้าง RESTful API

ใน NodeJS นั้นเรื่องของการสร้าง RESTful API นั้นง่ายมาก ๆ แถมมี library จำนวนมากทั้ง Express, Koa, Loopback และ Hapi มาดูใน Go กันบ้าง ว่ามีอะไร ? เริ่มง่าย ๆ ด้วย net/http + encoding/json package ก็พอ ยากหน่อยสำหรับผู้เริ่มต้น ด้วยตัวภาษามันใช้ได้เลย แต่ต้องลงแรงเยอะหน่อย เมื่อมองไปหา library ใช้งานก็ถือว่าเยอะเลยทั้ง และอื่น ๆ อีกมากมาย ลองไปดูผลการทำ benchmark เพิ่มเติมได้ที่ Go HTTP Rounting Benchmark และหา library ต่าง ๆ จาก Awesome Go
วันนี้เขียน code แล้วหรือยัง ? พร้อมไปกับการเรียนรู้ภาษาโปรแกรมใหม่ ๆ

มาลองใช้งาน Cotton สำหรับทดสอบ RESTful API กัน

$
0
0

วันนี้ได้ลองใช้งาน Cotton เป็นเครื่องมือสำหรับการทดสอบ RESTFul API ได้รับแรงบันดาลใจมากจาก Silk (คนทำน่าจะเลิกทำหรือดูแลไปแล้ว) ดังนั้นทางพี่อูเลยพัฒนา Cotton ขึ้นมา ซึ่งยังคงเขียน test case ในรูปแบบไฟล์ Markdown เช่นเดิม เพิ่มเติมคือความสวยงามและการใช้งานที่ง่ายขึ้น ดังนั้นเรามาลองใช้งานกัน

ขั้นตอนแรกก็ติดตั้งสิ

[code] $go get github.com/chonla/cotton $cotton [/code]

การใช้งานก็เขียน test case ไม่ยาก มันคือไฟล์ Markdown นี่เอง

แต่มีรูปแบบนิดหน่อย ส่วนที่ใช้งานบ่อย ๆ มีดังนี้
  • ในแต่ละไฟล์เรียกว่า test suite
  • ในแต่ละไฟล์จะมีได้มากกว่า 1 test case ซึ่งแต่ละ test case จะขึ้นต้นด้วย #
  • กำหนด URI และ HTTP Method (verb) สำหรับ API หรือ Enpoint ที่ต้องการทดสอบ จะขึ้นต้นด้วย ##
  • ถ้า Request มาการส่งค่าผ่าน HTTP Request Header จะกำหนดในรูปแบบตาราง ซึ่งดูดีกว่า Silk มาก
  • ส่วนข้อมูลที่ต้องการส่งผ่าน body/payload ของ HTTP ให้ใช้  backtick 3 ตัว
  • ในส่วนการตรวจสอบ response จะอยู่ในส่วน ## Expectation
  • การตรวจสอบจะอยู่ในรูปแบบของตารางเช่นกัน ซึ่งใช้งานง่ายดี
  • การเข้าถึงข้อมูลใช้ตัวแปรชื่อ Data ได้เลย

อธิบายมากไปเสียเวลา มาลองใช้งานกันนิดหน่อย

สร้างไฟล์ Markdown ชื่อว่า httpbin.md ทำการทดสอบ RESTful API จาก httpbin.org จากตัวอย่างมีอยู่ 2 test cases คือ GET กับ POST ดังนี้ [gist id="daa98c351be27b7b4a0f0c6b556afabe" file="sample.txt"] จากนั้นก็ run สิ รออะไร [code] $cotton -u http://httpbin.org httpbin.md [/code] ผลที่ได้เป็นดังนี้ [code] Tests executed: 2 Tests passed: 2 (100.00%) Tests failed: 0 (0.00%) [/code] จากการทดสอบใช้งานพบว่า ยังไม่สามารถ parse 2 test cases ในไฟล์เดียวได้ แต่ก็แก้ไขด้วยการแยกไฟล์ละ 1 test case ได้ แต่ก็ได้แจ้ง issue#2 ไปยังผู้พัฒนาแล้ว สิ่งที่ทำให้ผมชอบ Silk และ Cotton คือ ชุดการทดสอบมันคือเอกสารที่มีชีวิต และทำความเข้าใจได้ง่าย ซึ่งมันอยู่ในตัวเดียวกัน และใคร ๆ ก็เขียนได้

บันทึกการ publish ระบบที่พัฒนาด้วย Angular 6 ขึ้น Github Pages

$
0
0

พอดีต้องทำการให้ส่งงานที่พัฒนาด้วย Angular 6 ขึ้น Github Pages ซึ่งพบว่า Angular 6 มีสิ่งที่เปลี่ยนไปนิดหน่อย เลยทำการสรุปขั้นตอนไว้นิดหน่อย ดังนี้ ขั้นตอนที่ 1 ทำการติดตั้ง Angular CLI สำหรับ Github Pages [code] $npm install -g angular-cli-ghpages [/code] ขั้นตอนที่ 2 ทำการ build Angular app และกำหนด base url ตามรูปแบบของ Github Pages [code] $ng build --prod --base-href https://<username>.github.io/<repository name>/ [/code] ปล. ต้องปิดท้ายด้วย / นะ ขั้นตอนที่ 3 ทำการ upload หรือ publish ขึ้น Github และ Github Pages [code] $ngh --dir dist/<project name> -S [/code] สิ่งที่เปลี่ยนไปหน่อยคือ หลังจากขั้นตอนที่สอง จะสร้าง folder ใน /dist ดังนั้นจึงต้องใส่ --dir ไปนิดหน่อย ก็จะทำให้การทำงานสำเร็จได้เลย เมื่อทุกอย่างพร้อมก็ไปตรวจสอบได้เลย สวัสดี

สวัสดี vgo (Versioned Go) จาก Go version ล่าสุด

$
0
0

เนื่องจากอยากลองใช้งาน vgo ทำหน้าที่จัดการ dependency หรือ library ต่าง ๆ เห็นบอกว่าเป็น feature ที่จะเพิ่มเข้ามาใน Go 1.11 ดังนั้นจึงไปลองเล่น feature นี้กันหน่อยว่าเป็นอย่างไร ว่าแล้วก็เริ่มกันเลย

ขั้นตอนที่ 1 ทำการติดตั้งก่อน

สิ่งที่ทำคือ ไป clone source code จาก repository ของ Go จากนั้นทำการ build จาก branch master ซึ่ง vgo นั้นได้ถูกเพิ่มเข้ามาให้แล้วดังนี้ [code] $git clone https://go.googlesource.com/go $cd go $cd src $./make.bash [/code] สวัสดี Go [code] $go version go version devel +5f5402b723 Tue Jul 24 23:54:08 2018 +0000 darwin/amd64 [/code]

ขั้นตอนที่ 2 มาลองใช้งาน vgo กัน

Code ตัวอย่างเป็นการพัฒนา RESTful API ด้วย Gin [gist id="6f48a263f6e15ed7fffe59893560708f" file="main.go"] ทำการ run program ของเรา ลองไปลบ dependency ต่าง ๆ ของ Gin ออกจาก GOPATH ก่อนนะ เพื่อให้เห็นการทำงานของ vgo มา run กัน [code] $go run api.go go: cannot determine module path for source directory /my-code (outside GOPATH, no import comments) [/code] เกิด error ขึ้นมา มีคำว่า module ด้วยนะ นั่นคือ project อยู่นอก $GOPATH และ module ไม่เจอ ซึ่งเราจำเป็นต้องสร้างไฟล์ go.mod ขึ้นมาเพื่อกำหนด root ของ module ดังนี้ [gist id="6f48a263f6e15ed7fffe59893560708f" file="go.mod"] จากนั้นทำการ run อีกครั้ง ได้ผลดังนี้ [code] $go run api.go go: finding github.com/gin-gonic/gin v1.1.4 go: downloading github.com/gin-gonic/gin v1.1.4 go: finding github.com/manucorporat/sse latest go: finding github.com/mattn/go-isatty v0.0.3 go: finding github.com/golang/protobuf/proto latest go: finding golang.org/x/net/context latest go: finding gopkg.in/yaml.v2 v2.2.1 go: finding gopkg.in/go-playground/validator.v8 v8.18.2 go: downloading github.com/mattn/go-isatty v0.0.3 go: downloading github.com/manucorporat/sse v0.0.0-20160126180136-ee05b128a739 go: finding golang.org/x/net latest go: downloading golang.org/x/net v0.0.0-20180724234803-3673e40ba225 go: downloading gopkg.in/yaml.v2 v2.2.1 go: downloading gopkg.in/go-playground/validator.v8 v8.18.2 go: finding github.com/golang/protobuf v1.1.0 go: downloading github.com/golang/protobuf v1.1.0 go: finding gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 [/code] ไฟล์ go.mod นั่นคือ Go Module นะ เพื่อกำหนดให้เป็น module หลัก และจะทำการเก็บ dependency ต่าง ๆ ที่ใช้ หลังจากที่ run แล้วจะการตรวจสอบ, download และเก็บ depenedncy ที่ใช้งานไว้ดังนี้ [gist id="6f48a263f6e15ed7fffe59893560708f" file="go.mod-2"] รวมทั้งยังสร้างไฟล์ go.sum เพื่อเก็บค่า checksum ของ dependency แต่ละตัวอีกด้วย [gist id="6f48a263f6e15ed7fffe59893560708f" file="go.sum"]
ส่วน dependency นั้นจะถูก download ไว้ใน $GOPATH/mod นะ เปลี่ยนไปแล้วว
เพียงเท่านี้ก็ใช้งานได้แล้วนะ ไปลองกัน ขอให้สนุกกับการ coding ครับ

มาลอง Go Module ใน Go 1.11 beta

$
0
0

หลังจากที่ Go 1.11 beta 2 ถูกปล่อยออกมาให้ลองใช้งานกัน ซึ่งตัวเต็ม ๆ จะปล่อยมาในเดือนสิงหาคมนี้ feature ที่น่าสนใจคือ Go Module
จาก go get -> vendor -> vgo -> go mod ใน Go 1.11
ดูเอกสารเพิ่มเติมได้ที่ Release Note

มาเริ่มต้นใช้งานกันหน่อย

[code] $cd $GOPATH/src/module_name $go mod -init go: modules disabled inside GOPATH/src by GO111MODULE=auto; see 'go help modules' [/code] ทำการเปิด Go module feature ด้วยคำสั่ง [code] $export GO111MODULE=on [/code] ทำการสร้างไฟล์ go.mod สำหรับอธิบาย module [code] $go mod -init go: creating new go.mod: module main [/code] จากนั้นก็ทำการแก้ไขไฟล์ go.mod เพื่อระบุ dependency ที่ใช้งานดังนี้ [gist id="d222f569f58259b7f1e76f7bbbfc0d48" file="go.mod"] ทำการ build ระบบ จะทำการ download dependency ที่กำหนดไว้ใน go.mod ดังนี้ [code] $go build go: downloading github.com/gin-gonic/gin v1.1.4 go: finding github.com/manucorporat/sse latest go: finding github.com/mattn/go-isatty v0.0.3 go: finding github.com/golang/protobuf/proto latest go: finding golang.org/x/net/context latest go: finding gopkg.in/go-playground/validator.v8 v8.18.2 go: finding gopkg.in/yaml.v2 v2.2.1 go: finding golang.org/x/net latest go: downloading golang.org/x/net v0.0.0-20180724234803-3673e40ba225 go: downloading github.com/mattn/go-isatty v0.0.3 go: downloading github.com/manucorporat/sse v0.0.0-20160126180136-ee05b128a739 go: downloading gopkg.in/go-playground/validator.v8 v8.18.2 go: downloading gopkg.in/yaml.v2 v2.2.1 go: finding github.com/golang/protobuf v1.1.0 go: downloading github.com/golang/protobuf v1.1.0 go: finding gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 [/code]

สิ่งที่น่าสนใจคือ เรื่องของ version

การตั้งชื่อของ version ต้องเป็นไปตาม semantically versioned นั่นคือมีรูปแบบดังนี้ v(major).(minor).(patch) เสมอ ดังนั้นถ้า dependency ใด ไม่มี version ตามนี้จะไม่สามารถใช้งานได้ ยกตัวอย่างเช่น go-gin นั้น version ล่าสุดคือ v2.0 ดังนั้นจึงไม่สามารถกำหนดใน go.mod ได้ จะเกิด error ดังนี้ [code] go.mod:4: invalid module version "v2.0": no matching versions for query "v2.0" [/code] ถ้าต้องการ update depedency ใหม่ทั้งหมด ใช้คำสั่งดังนี้ [code] $go mod -sync go: downloading gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 go: finding github.com/stretchr/testify/assert latest go: finding golang.org/x/sync/errgroup latest go: finding gopkg.in/go-playground/assert.v1 v1.2.1 go: finding golang.org/x/sync latest go: downloading golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f go: finding golang.org/x/sys/unix latest go: downloading gopkg.in/go-playground/assert.v1 v1.2.1 go: finding golang.org/x/sys latest go: downloading golang.org/x/sys v0.0.0-20180724212812-e072cadbbdc8 go: finding github.com/stretchr/testify v1.2.2 go: downloading github.com/stretchr/testify v1.2.2 go: finding github.com/pmezard/go-difflib/difflib latest go: finding github.com/davecgh/go-spew/spew latest go: finding github.com/davecgh/go-spew v1.1.0 go: downloading github.com/davecgh/go-spew v1.1.0 go: finding github.com/pmezard/go-difflib v1.0.0 go: downloading github.com/pmezard/go-difflib v1.0.0 [/code] คำสั่งอื่น ๆ ของ go mod ประกอบไปด้วย [code] $go mod -sync $go mod -fmt #go fmt สำหรับไฟล์ go.mod และ go.sum $go mod -fix #จัดการไฟล์ go.mod $go mod -graph #สำหรับดู depedency ทั้งหมดที่ใช้งาน [/code] ยังไม่พอนะ ถ้ายังต้องทำการส่งมอบในรูปแบบ vendor นั่นคือสร้าง vendor folder ขึ้นมาในระบบ แน่นอนว่า Go Module ยังสนับสนุนด้วยคำสั่ง $go mod -vendor มาดูในไฟล์ go.mod กันดูบ้าง [gist id="d222f569f58259b7f1e76f7bbbfc0d48" file="go.mod-2"] โดยที่ require นั้นจะมี comment indirect มาให้ เป็นการบอกว่าคือ depedency ที่เราไม่ได้กำหนด แต่ว่าต้องใช้งานจาก depedency ที่เรากำหนดนั่นเอง แต่ไม่ใช่มีแค่ require นะ ยังมี exclude และ replace อีกด้วย อยากรู้มากขึ้นไปดูที่ [code] $go help modules [/code] เพียงเท่านี้น่าจะพอทำให้เข้าใจมากขึ้นสำหรับ Go Module มากขึ้น ว่าแล้วไปสร้าง Module และใช้งานกัน

Angular 6 ว่าด้วยเรื่อง Life Cycle ของ Component

$
0
0

ว่าง ๆ นั่งดู Life Cycle ของ Component ใน Angular 6 โดย component นั้นเป็นส่วนการทำงานหลัก ๆ ของ Angular เลยก็ว่าได้ เป็นสิ่งที่สำคัญมาก ทั้งการออกแบบเช่น Stateless และ Stateful component ทั้งการเข้าใจกระบวนการทำงาน ตลอดจน Life cycle ของมัน ใน blog นี้ไปดู Life cycle ของ component กัน พบว่ามันเยอะมาก ๆ นะ

Life cycle ของ component ประกอบไปด้วย 8 methods (จะเยอะไปไหน)

ซึ่งจะมีการทำงานเป็นลำดับที่ชัดเจนมาก โดยที่ constructor() นั้นจะถูกเรียกเมื่อ component ถูกสร้างขึ้นมาเสมอ เป็นความสามารถที่มีมาจากภาษา TypeScript อยู่แล้ว เราสามารถแบ่งกลุ่มของ method เป็น 2 กลุ่มคือ กลุ่มที่ 1 สำหรับ component หลัก
  • ngOnChanges
  • ngOnInit
  • ngDoCheck
  • ngOnDestroy
กลุ่มที่ 2 สำหรับ child component
  • ngAfterContentInit
  • ngAfterContentChecked
  • ngAfterViewInit
  • ngAfterViewChecked

มาดูว่าแต่ละ method นั้นถูกเรียกตอนไหนกันบ้าง ?

ngOnChanges จะถูกเรียก input หรือ output element ที่ binding ไว้มีการเปลี่ยนแปลงค่า ngOnInit จะถูกเรียกเมื่อ component ถูกสร้างขึ้นมา เรียกหลังจาก ngOnChanges() โดยใน method นี้ทำหน้าที่ในการ initial ค่าข้อมูลของ component ngDoCheck จะถูกเรียกทุกครั้งเมื่อเราไป focus ที่ element นั้น ๆ จากนั้นจะทำการตรวจสอบว่ามีการเปลี่ยนแปลงหรือไม่ ดังนั้นในส่วนนี้ใช้ไว้สำหรับดักจับการเปลี่ยนแปลงในรูปแบบที่ต้องการ ngOnDestroy จะถูกเรียกก่อนที่ component จะถูกทำลาย ใช้สำหรับการ unsubscribe พวก observable และ event ต่าง ๆ ที่ subscribed ไว้ เพื่อไม่ห้เกิดปัญหา memory leak ต่อไปเป็นกลุ่มของ method ที่ถูกเรียกหลังจาก ngDoCheck ngAfterContentInit จะถูกเรียกในการสร้าง view/content ครั้งแรก ngAfterContentChecked จะถูกเรียกเพื่อใช้ตรวจสอบการเปลี่ยนแปลงต่าง ๆ ของ child component ngAfterViewInit จะถูกเรียกเมื่อสิ่งต่าง ๆ ใน child component ทำการ initial เสร็จเรียบร้อย ngAfterViewChecked จะถูกเรียกเมื่อสิ่งต่าง ๆ ที่ binding ไว้ของ child component มีการเปลี่ยนแปลง ดังนั้นจะใช้สำหรับการรอค่าจะเปลี่ยนแปลงจาก child component นั่นเอง

อธิบายไปก็ยังงง ๆ ไม่เห็นภาพ เขียน code ดีกว่า

ก่อนอื่นนั้นต้องทำการ import และ implements interface ของ Life cycle ซึ่งเยอะมาก ดังนี้ [gist id="ee00755a33f40dad4d7309c8e7aaae17" file="app.component.ts"] จากนั้นก็ลอง run และ debug การทำงานดู ก็พบว่า เมื่อเริ่มต้นเข้าใช้งานครั้งแรก method ของ Life cycle ทำงานครบทั้ง 8 เลย แต่เมื่อทำการแก้ไขหรือ focus ไปยัง element หรือ child ต่าง ๆ ใน component จะทำการเรียก ngDoCheck, ngAfterContentChecked และ ngAfterViewChecked เสมอ
มาตรงนี้ถ้าอยากรู้อะไร อยากจัดการเรื่องอะไรตรงไหน ก็จะง่ายขึ้นอีก เมื่อเราเข้าใจ Life cycle ของ component

Part 1 :: สวัสดี Flutter ด้วยการติดตั้ง

$
0
0

เห็นมีการพูดถึงเยอะกับ Flutter เป็น open source platform สำหรับการพัฒนา mobile app แบบ cross platform ทั้ง Android และ iOS ด้วยภาษา Dart แน่นอนว่าส้รางโดยทีมของ Google นั่นเอง เมื่อไปอ่านเอกสารก็พบการขายของนิดหน่อยคือ
  •  Look and Feel ของ app จะเหมือนกับ native เลย
  • ประสิทธิภาพแจ่มมาก
  • ได้รับแรงบันดาลใจมาจาก Reactive framework
  • Debug ได้รวดเร็วมาก ด้วย hot reload นั่นคือ แก้ code ไปดูผลการทำงานไป
  • สามารถเข้าถึง feature ต่าง ๆ ของแต่ละ platform ได้ เช่น battery และ GPS แต่ต้องเขียน code เฉพาะไป
  • ที่ชอบคือ Flutter testing support ซึ่งใช้ทั้ง unit + mocking framework และ device testing ผ่าน Flutter Driver รวมทั้ง Widget testing ซึ่งทุกอย่างในหน้าจอจะเป็น widget ทั้งหมด ทำให้เราสามารถทดสอบ widget แต่ละตัวได้เลย น่าสนใจจริง ๆ
จริงหรือไม่ มาลองกันดีกว่า
ปล. Flutter ยังอยู่ในสถานะ beta นะ ดังนั้นอาจจะมีการเปลี่ยนแปลงครั้งใหญ่ได้ จะใช้ Flutter ก็ต้องศึกษาใหม่ รวมทั้งภาษา Dart ด้วย ความสามารถของภาษา Dart ยังไม่เท่าเทียวกับ Swift หรือ Kotlin นะ แต่ Dart 2 ก็ดีขึ้น สำหรับชาว Android นั้นสนับสนุน Android 4.1 ขึ้นไปนะ (Jelly Bean) สำหรับชาว iOS ก็ iOS 8 ขึ้นไป และไม่สนับสนุน device 32 bit ด้วยนะ

ขั้นตอนที่ 1 เริ่มต้นด้วยการติดตั้ง

สามารถติดตั้งได้ทั้ง Windows, MacOS และ Linux เลือกได้เลยจาก Get Started :: Install ผมติดตั้งบน MacOS นะ ต้องทำการ download Flutter SDK มีขนาด 621 MB ในตอนที่ติดตั้งเป็น version 0.5.1 beta จากนั้นทำการ extract และกำหนดในตัวแปร $PATH จะสามารถ run คำสั่ง Flutter ได้ใน command line ดังนี้ [code] $flutter [/code] จะบอกว่าสิ่งที่เราติดตั้งนั้นมัน out of date ดังนั้นทำการ update ซะ [code] $flutter upgrade [/code] จากนั้นจะทำการ upgrade และตรวจสอบให้ว่า ต้องทำการติดตั้งอะไรบ้าง ซึ่งตรงนี้ง่ายดี ทำให้เรารู้ว่าต้องทำอะไรบ้าง สามารถพิมพ์คำสั่งเองได้ด้วย (ให้หมอตรวจดูให้) [code] $flutter doctor -v [/code] จะทำการตรวจสอบสิ่งต่าง ๆ ดังนี้ให้
  • Flutter SDK และผองเพื่อน เช่นภาษา Dart
  • Android Toolchain ทั้ง Android SDK และ JDK
  • iOS Toolchain ทั้ง Xcode, iOS-deploy และ Cocoapods
  • Android Studio IDE ติดตั้งพวก plugin ให้ครบ
  • IntelliJ IDEA ติดตั้งพวก plugin ให้ครบ
  • VS Code ติดตั้งพวก plugin ให้ครบ
  • การเชื่อมต่อกับ device หรือพวก Emulator
ปล. สำหรับใครที่ติดตั้ง JDK หลาย version แนะนำให้กำหนด JAVA_HOME ให้เป็น JDK 1.8 ไปเลย เอาแค่ Flutter, Android และ iOS Toolchain และ Device/Emulator/Simulator ให้ผ่าน ก็เพียงพอต่อการเริ่มต้นแล้ว
ผลการติดตั้งต้องเป็นประมาณนี้นะ [gist id="d1acc9b4941cc5a1bb30f4fe4fbdc2eb" file="result.txt"]
เพียงขั้นตอนแรกก็จัดว่าลำบากน่าดู !!
Issues ต่าง ๆ ของการติดตั้ง Flutter ก็เพียบนะ !!

เมื่อทุกอย่างพร้อม ก็เริ่มพัฒนา app กันเลย

[code] $flutter create hello $cd hello $flutter run [/code] ผลที่ได้คือ การสร้างและ run app บน device/simulator/emulator น่าจะพอไปวัดไปวาได้ สำหรับการเริ่มต้นกับ flutter แถมมีความสามารถให้ใช้งานเพียบ เช่น
  • ทั้งการ capture หน้าจอด้วยการกดปุ่ม s
  • ทั้งการดูลำดับชั้นของ element ในหน้าจอด้วยการกดปุ่ม i
แสดงการทำงานดังนี้
สำหรับคนเริ่มต้น เหนื่อยแน่นอน !! แต่ Keep claim and coding/learning
ไว้มาพัฒนา app ด้วย Flutter กันต่อไปใน part 2

Part 2 :: มาสร้าง App ง่าย ๆ ด้วย Flutter กันหน่อย

$
0
0

หลังจากที่เราทำงานติดตั้ง Flutter กันไปแล้ว จาก blog :: Part 1 :: สวัสดี Flutter ด้วยการติดตั้ง  จากแนวคิดของ Flutter นั้นมาจาก React โดยทุก ๆ component จะเรียกว่า widget ประกอบไปด้วย
  • การแสดงผล
  • State
  • ทำงานตาม state ที่เปลี่ยนแปลงไป
มาเริ่มต้นพัฒนา app กันดีกว่า

ก่อนอื่นมาดูโครงสร้างของ Flutter project กัน

แสดงดังรูป คำอธิบาย
  • android สำหรับ code ของ Android app
  • ios สำหรับ code ของ iOS app
  • lib สำหรับไฟล์การทำงานหลักของ app เขียนด้วยภาษา Dart ที่เราจะทำความรู้จักและเขียนกัน
  • test สำหรับไฟล์ของชุดการทดสอบ ที่จะพูดกันใน blog ต่อ ๆ ไป
  • pubspec.yaml สำหรับ configuration ต่าง ๆ ของ app เช่น package หรือ dependency ต่าง ๆ

มาเริ่มเขียน code ในไฟล์ lib/main.dart

เนื่องจาก code ตัวอย่างที่สร้างมาจากตอนสร้าง project มันเยอะมาก ๆ แถมอ่านก็ไม่รู้เรื่องเลย !! ดังนั้นทำการลบแล้วเริ่มเขียนใหม่ดีกว่า เขียน code ตามระเบียบคือ Hello Flutter World กัน [gist id="8c266410792614cda8d4b0075508456e" file="main.dart"] คำอธิบาย
  • แสดงคำว่า Hello Flutter World ตรงกลางหน้าจอ
  • อยากให้ตัวอักษรหนา ๆ และขนาดตัวอักษรใหญ่ ๆ
แสดงการทำงานดังรูป การทำงานจะเริ่มต้นจาก function main() จากนั้นจะทำงานที่ function runApp() เพื่อกำหนด root ของ widget ของ app เรา code ตัวอย่างนั้น มี 3 widget คือ Center, Text และ TextStyle ดังนั้น Widget ต่าง ๆ จะถูกจัดการในรูปแบบ tree นั่นเอง แนวคิดเหล่านี้ไม่ได้ต่างจาก React และ Angular component มากนัก แสดงดังรูป

เรื่องต่อมา Flutter ได้เตรียม Widget พื้นฐานมาให้ใช้เยอะเลย

เราสามารถนำมาใช้ได้เลย ประกอบไปด้วย
  • Text สำหรับการแสดงผลข้อความต่าง ๆ
  • Row, Column เรียกว่า Flex widget สำหรับการสร้าง layout แบบยืดหยุ่นทั้งแนวตั้งและแนวนอน ซึ่งการออกแบบก็ตาม Flexbox ใน web นั่นเอง
  • Stack สำหรับการสร้าง layout ที่ทับกันได้ (overlap)
  • Container ตามเชื่อเลยคือ ที่รวบรวม widget ต่าง ๆ เข้าด้วยกัน
  • ยังมีตัวอื่น ๆ อีกนะ ทั้ง Listview และ GridView และอื่น ๆ อีกมากมาย
ถ้าเราต้องการสร้าง Widget เอง ก็สามารถทำได้ โดยสามารถสร้าง Widget ใหม่ด้วยการ extend มาจาก 2 class คือ
  1. StatelessWidget
  2. StatefulWidget
จะทำการ extend จาก class ไหนดีละ ? ตอบง่าย ๆ ตามชื่อเลย นั่นคือ ถ้าต้องการจัดเก็บ state ต่าง ๆ ของการทำงานไว้ ก็ใช้ StatefulWidget กันเลย ถ้าไม่จัดเก็บ state ก็ใช้ StatelessWidget ซะ เช่นพวกการแสดงผลเป็นต้น ดังนั้นเรามาสร้าง Widget และ app เล่นกันดีกว่า

มาสร้าง Widget แรกชื่อว่า HelloApp กัน

ลองใช้งาน Material design ที่มีให้มาอยู่แล้วกัน ทำการแสดงผลในรูปแบบเดิม เพิ่มเติมคือใช้ Scaffold widget ของ Material Design เป็น layout ง่าย ๆ ทำให้เรากำหนดชื่อของ title ในส่วนของ App bar ได้เลย เนื่องจาก widget ที่จะสร้างไม่มีการจัดเก็บข้อมูลหรือ state อะไรเลย ดังนั้นจึงทำการ extend จาก class StatelessWidget พวก property ต่าง ๆ ของ class ต้องเป็น immutable ด้วยนะ นั่นคือเปลี่ยนแปลงไม่ได้ นั่นคือ ต้องทำการใส่ keyword final เข้าไปด้วย การแสดงผลจะทำงานใน function build() ถ้าเป็น React จะทำงานใน function render() นั่นเอง [gist id="8c266410792614cda8d4b0075508456e" file="main2.dart"] ผลการทำงานเป็นดังนี้ ดูสวยงามขึ้นเป็นกองนะ

เพื่อทำความเข้าใจมากยิ่งขึ้น มาลองสร้าง App จริง ๆ กันหน่อย

สิ่งที่ต้องการประกอบไปด้วย
  • ดึงข้อมูลของเบียร์จาก PUNK API
  • นำข้อมูลมาแสดงใน ListView widget
มาเริ่มกันเลย โดยปัญหาของมือใหม่แบบผมจะเยอะมาก ๆ มาพัฒนาด้วยปัญหาหรือคำถามกัน แล้วไปลองค้นหาดู

ปัญหาที่ 1 จะดึงข้อมูลจาก API ผ่าน internet อย่างไร ?

เอกสารของ Flutter ก็มีให้เช่นกันคือ Fetch data from the internet ซึ่งจะใช้งาน http package เมื่อได้ข้อมูลมาจาก API แล้ว จะทำการแปลงมาอยู่ในรูปแบบของ Dart object โดยใช้ package dart/convert มาเขียนกันเลย ในภาษา Dart ได้เตรียม Future class สำหรับการทำงานแบบ Asynchronous เขียนในรูปแบบ async-await ได้ดังนี้ [gist id="8c266410792614cda8d4b0075508456e" file="main3.dart"] ผลการทำงานเป็นดังนี้  อ่านไม่ค่อยรู้เรื่องเท่าไร !!

สิ่งที่อยากทำต่อไปคือ การแปลง JSON ให้อยู่ในรูปแบบของ Dart object ว่าแต่ทำอย่างไรละ ?

ใน function getBeers() จะต้องทำการ return ข้อมูลเป็น List ของ Beer object !! ดังนั้นมาสร้าง class Beer กัน ซึ่งจะสร้างอยู่ในไฟล์ใหม่ชื่อว่า beer.dart ดังนี้ [gist id="8c266410792614cda8d4b0075508456e" file="beer.dart"] คำอธิบาย
  • Constructor จะรับ 3 ค่า สำหรับการสร้าง object ตรงนี้แล้วแต่เราต้องการ
  • มี static function/method สำหรับการแปลงจาก JSON message มาอยู่ในรูปแบบของ Beer Object ซึ่งในภาษา dart จะใช้ keyword ว่า factory
  • ทำการ override function toString() สำหรับการแสดงผลข้อมูลของ Beer แบบสวย ๆ ตามที่ต้องการ
กลับมาที่ไฟล์หลักคือ main.dart ใน function getBeers() ทำการเพิ่ม code การแปลงข้อมูล JSON message ให้มาอยู่ในรูปแบบ List ของ Beer กัน รวมทั้งเปลี่ยนชนิดข้อมูลที่จะ return กลับด้วย ยังไม่พอนะ ต้องทำการ import beer.dart ด้วย มิเช่นนั้นจะใช้งานไม่ได้ มี code ดังนี้ [gist id="8c266410792614cda8d4b0075508456e" file="main4.dart"] แสดงผลการทำงานแบบสวย ๆ กันแล้ว ดังนี้
มาถึงตรงนี้เขียนไปเขียนมา นึกว่าเขียนภาษา Java อยู่นะ !!!

เมื่อเรื่องข้อมูลที่จะนำมาใช้งานเรียบร้อยแล้ว ก็มาถึงในส่วนของการแสดงผล

เป็นส่วนที่ยากที่สุดสำหรับผมแล้ว !!
ใน blog นี้จะไม่มีการเก็บค่าใด ๆ ดังนั้นจะสร้าง Widget แบบ Stateless ส่วนการแสดงผลจะอยู่ในรูปแบบของ ListView ใน ListView นั้นประกอบไปด้วย Item ซึ่งจะนำข้อมูล Beer มาแสดง ตอนนี้เอาแค่ชื่อเบียร์มาแสดงก่อนก็แล้วกัน !! มาเริ่มกันเลย
ก่อนอื่นต้องออกแบบ Widget ที่จะสร้าง โดยผมทำการแยกออกเป็น 3 widget ตามหน้าที่การทำงาน
  1. MyApp เป็น widget เริ่มต้นหรือ root ของ app นั่นเอง ทำการกำหนดว่าจะใช้ Material design นะ
  2. Firstpage เป็น widget ลูกของ MyApp ทำหน้าที่กำหนด Layout ของหลักของ app รวมทั้งทำหน้าที่ดึงข้อมูลของ beer จาก PUNK API ด้วย ในส่วนนี้นี่เองที่ผมต้องการให้มี Progress bar ขึ้นมาในขณะที่กำลังดึงข้อมูล ซึ่งจะใช้ widget ชื่อว่า CircularProgressIndicator เราน่าจะเรียก widget นี้ว่า Smart/Container component/widget ก็ได้นะ
  3. ListBeer เป็น widget ลูกของ FirstPage ทำหน้าที่แสดงข้อมูลของ beer ทั้งหมด เราน่าจะเรียก widget นี้ว่า Dumb/Presentational component/widget ก็ได้นะ
มี code ดังนี้ [gist id="8c266410792614cda8d4b0075508456e" file="main5.dart"] ผลการทำงานเป็นดังรูป ลองเปลี่ยนไปใช้ GridView เพื่อแสดงรูปของ beer กันหน่อย ก็พอได้นะ
ยากจริง ๆ สำหรับการแสดงผล !!

ถ้าจะให้สวยต้องใช้พวก Flex และ Card widget เข้ามาช่วยอีกนะ

เป็นเรื่องที่ต้องศึกษาและนำมาใช้ต่อไป แต่เพียงเท่านี้ ก็น่าจะทำให้เห็นว่า Flutter มีหน้าตาอย่างไรบ้างแล้ว รวมไปถึง code ที่เขียนด้ววยภาษา Dart รวมกับ package ต่าง ๆ จะพัฒนา app ด้วย Flutter ให้ดี ต้องไปเรียนรู้ภาษา Dart เพิ่มเติมอีก ดังนั้น part ต่อไป มาทำความรู้จักกับภาษา Dart กัน ( Dart 2.0 ) รวมทั้งการพัฒนา app ที่ซับซ้อนและสวยงามขึ้น
Source code ตัวอย่างอยู่ที่ Github::Simple App with Flutter
ขอให้สนุกกับการ coding ครับ

สรุปการแบ่งปันเรื่อง Coding with Quality

$
0
0

มีโอกาสได้ไปแบ่งปันเรื่องของ Code with Quality มา 2 วัน คุณลักษณะของ Code ที่มีคุณภาพนั้นประกอบไปด้วย
  1. Efficiency
  2. Performance
  3. Integrity
  4. Recoverability
  5. Simplicity
  6. Maintainability
  7. Flexibility
  8. Valuable (Value to customer/user)
โดยสิ่งที่ไปแบ่งปันนั้น จะเน้นไปที่ Maintainability, Simplicity และ Efficiency จึงสรุปรวมให้เป็น Coding for Human ไปเลย นั่นคือ มาเขียน code สำหรับคนอื่น ๆ กัน ว่าจะเป็นอย่างไรบ้าง

เริ่มด้วยเป้าหมายของการ coding

ว่าเราเขียน code เพื่ออะไร ? ว่าเราเขียน code ไปทำอะไร ? code ที่เราเขียนออกมานั้นเป็นอย่างไร ? แก้ไขปัญหาที่เราต้องการได้หรือไม่ ? ทำงานได้อย่างถูกต้อง ตามที่คาดหวัง ? สามารถดูแลรักษาได้ง่าย ? สามารถอ่านและทำความเข้าใจได้ง่าย ? ถ้ามีการเปลี่ยนแปลงแล้ว เราสามารถรู้ได้ทันทีว่า การเปลี่ยนแปลงเหล่านั้น ส่งผลต่อระบบเดิมอย่างไร ?
ถ้า code เราไม่ตอบโจทย์ต่าง ๆ เหล่านี้แล้ว คิดว่า น่าจะเป็น code ที่ก่อให้เกิดปัญหา มากกว่า ประโยชน์หรือไม่ ? อันนี้ก็ขึ้นอยู่กับตัวบุคคลแล้วนะ
สำหรับการแบ่งปันในครั้งนี้ จะเน้นไปที่การเขียน code ที่ง่ายต่อทำความเข้าใจ เขียน code แบบตรงไปตรงมา เขียน code ให้ตรงกับ requirement เขียน code เพื่อให้ทำงานได้
Make it Work Make it Right

โดยปัญหาที่นักพัฒนาพบเจอมาก ๆ คือ

เรามักจะต้องไปดูแล code ที่ตัวเองไม่ได้เขียน แน่นอนว่า เมื่อเปิด code ขึ้นมาดูครั้งแรก อาจจะร้องอุทานว่า code ... อะไรเนี่ย ... สิ้นดี จากนั้นสิ่งที่เราทำคืออะไร ? แก้ไขให้มันดีขึ้น ? เขียนใหม่ ? ทำแบบเดิมต่อไป ? หรือออกไปที่อื่นดีกว่า ? กลับมาที่ปัญหากัน เรามักใช้เวลาในการอ่านและทำความเข้าใจกับ code นานมาก ๆ เนื่องจากอ่านเข้าใจยาก แถมซับซ้อนอีกด้วย
เรามักจะบอกว่า เดี๋ยวค่อยกลับมาแก้ไขก็ได้ แบบนี้มันก็ทำงานได้อยู่นะ ผลที่ตามมาคือ code ชุดนี้มันจะคงอยู่ตลอดไป เพราะว่า Later == Never อย่างแน่นอน
ที่สำคัญ เรามักจะยุ่งเสมอ ไม่มีเวลาทำอะไร เพราะว่ามีแต่งานเร่งด้วยและด่วนมาก ๆ และด่วนที่สุด หรือทำเดี๋ยวนี้เลย ทำให้เราเดินหน้าไปเรื่อย ๆ ไม่เคยหยุดหรือมาดูสิ่งที่สร้างกันเลย เปรียบเหมือนกับการขุดหลุมหรือเดินเข้าไปไปเรื่อย ยิ่งขุดยิ่งลึก ยิ่งเดินเข้าไป ยิ่งลึก สุดท้ายแล้วก็พบว่า เราอยู่ในหลุ่มที่ลึกมาก ๆ ขึ้นมาไม่ได้ หรืออยู่ในป่าลึก จนหาทางออกไม่ได้ สุดท้ายแล้วเราจะทำอย่างไร ? ดังนั้นอยากขอแนะนำว่า อย่าทำกันเลยนะ มาทำแบบที่ดี ๆ กันดีกว่า

โดยเรื่องของ Coding for Human นั้น สามารถสรุปด้วยรูปนี้

ช่วยทำให้เข้าใจได้ว่าพื้นฐานสำคัญคือ Clean Code จะเอื้อประโยชน์ให้สิ่งต่าง ๆ เกิดขึ้นมา ทั้ง
  • SOLID แนวคิดในการออกแบบที่ดี
  • Automated testing ชุดการทดสอบแบบอัตโนมัติเพื่อทำให้เรามั่นใจต่อ code
  • Refactoring การปรับปรุงโครงสร้างของ code โดยไม่ส่งผลกระทบต่อคนใช้งาน
  • DDD (Domain-Driven Design) การแบ่งงานออกเป็นกลุ่ม ๆ รวมทั้งการติดต่อสื่อสาร เป็นพื้นฐานของระบบแบบ modular มาก ๆ
  • Design Pattern คือรูปแบบของการแก้ไขปัญหา ดังนั้นถ้ายังไม่เกิดปัญหาก็อย่าเพิ่งใช้
  • TDD (Test-Driven Development) คือการคิดก่อนที่จะทำ
สิ่งที่จะเน้นมาก ๆ คือเรื่อง Clean Code, Automated testing และ Refactoring รวมไปถึงแนวคิด Simple Design Rule ประกอบไปด้วย
  1. All test pass
  2. Express intent
  3. No duplication
  4. Small part/function
โดยที่ผมหยิบเอา Simple Design Dynamo มาอธิบาย นั่นคือทุกกสิ่งอย่างมันจะเกิดจากการปรับปรุงชื่อ และ ลด code ที่ duplication แล้วจะจะก่อให้เกิดการเปลี่ยนแปลง ทั้งเรื่องของโครงสร้างและ abstraction layer ต่าง ๆ แต่จะทำได้อย่างปลอดภัยและมั่นใจ เราจะต้องมีชุดการทดสอบแบบที่ดีและเร็ว นั่นอาจจะพูดถึง Automated testing แบบอ้อม ๆ ก็ได้  

Workshop ที่ทำนั้นประกอบไปด้วย

  • การ Refactoring code จาก Kata Tennis ลองไปฝึกกันดู สนุกมาก ๆ
  • การ Refactoring Legacy Code โดยนำแนวคิด Simple Design Rule มาใช้งาน เริ่มตั้งแต่การลบ code ที่ไม่ใช้งานออกไปด้วย IDE/Editor จากนั้นทำการ review code ว่ามีอะไรที่แปลก ๆ ไหม ทั้งการ comment รวมไปถึงชื่อและ abstraction layer ต่าง ๆ และทำการทำความเข้าใจ Legacy code ด้วยการเขียน Automated test รวมถึงการนำ code coverage มาช่วยทำความเข้าใจ code และปลอดภัย สุดท้ายจึงลงมือ refactoring code ต่อไป

หนังสือที่แนะนำให้อ่าน มี 3 เล่มดังนี้

สิ่งที่อยากจะฝากไว้มีอยู่ 2 แนวคิดคือ

  1. Boy Scouts Rule
  2. No Broken Windows
ง่าย ๆ คือ ถ้าเห็นว่าอะไรมันไม่ดีแล้ว พูดได้ ว่าได้ ด่าได้ แต่คุณต้องทำให้มันดีขึ้นกว่าเดิมด้วย
ขอให้สนุกกับการ coding ครับ

บันทึกการพัฒนาระบบงานด้วย Angular 6 และ Golang

$
0
0

พอดีเพิ่งทำระบบ web application แบบเร็ว ๆ ซึ่งมี feature ไม่เยอะ จึงเลือกใช้เทคโนโลยีที่ไม่ค่อยใช้งานหรือถนัดมากนัก เพื่อลองฝึกฝน แต่ฝึกบนงานจริง ๆ น่าจะทำให้เราศึกษาได้รวดเร็วขึ้น หรือไม่ก็ล่มไม่เป็นท่า !! โดยเทคโนโลยีที่เลือกใช้งานเป็นดังนี้
  • Frontend พัฒนาด้วย Angular 6
  • Backend พัฒนาด้วยภาษา Go
  • จัดการ source code ด้วย Git
  • ทำการ build และ deploy ด้วย Docker (ใช้งาน docker-compose)
  • ทำการ deploy ระบบงานบน Google Cloud แบบฟรี 300 USD เป็นเวลา 1 ปี
มาดูว่าการพัฒนาเป็นอย่างไรบ้าง ?

เริ่มจากส่วนที่ง่ายที่สุดสำหรับผม แต่ทำสุดท้ายเลยนั่นก็คือ Backend

โดยเลือกใช้งานภาษา Go เนื่องจากเล็กดี ใช้ resource น้อย เนื่องจากต้องไป deploy บนระบบ Google Cloud เพื่อลดค่าใช้จ่ายก็ใช้แบบเล็กสุด ๆ ไปเลย ทำการพัฒนาฝั่ง Backend เป็น RESTful API ประมาณ 5 APIs ดังนั้นใช้งาน net/http package ก็พอ ส่วนการจัดการข้อมูลในรูปแบบ JSON ก็ใช้งาน encoding/json package ก็พอ การเก็บข้อมูลนั้นในตอนแรกว่าจะเก็บลงใน RDBMS หรือ พวก NoSQL แต่พอดูแนวโน้มของจำนวนข้อมูลกับ feature ต่าง ๆ แล้ว ถ้าใช้สิ่งที่คิดไว้ คงจะขี่ช้างจับตั๊กแตนมากไป ดังนั้นจึงเริ่มง่าย ๆ ด้วยการเก็บข้อมูลลงไฟล์ก็พอ คำถามต่อมา คือ จะเก็บข้อมูลในรูปแบบไหนดี ยกตัวอย่างเช่น CSV และ JSON เป็นต้น แต่เมื่อคุยไปคุยมาแล้ว พบว่าต้องมีการจำข้อมูลเหล่านี้ไปใช้งานต่อ ดังนั้นในมุมมองของคนเท่าไป CSV น่าจะตอบโจทย์มากกว่า แต่ตอนแรกทำเป็น JSON นะ เพราะว่ามันง่ายมาก ๆ สำหรับนักพัฒนา แต่ไม่ค่อยสะดวกฝั่งคนใช้งานทั่วไปมากนัก จึงทำการเปลี่ยนซะเลย ลดงานที่ต้องทำไปเยอะ การจัดการข้อมูล CSV ทั้งอ่านและเขียนข้อมูลผ่าน encoding/csv package
ส่วนการ monitoring พวก RESTfule API ก็ไปเพิ่ม Health check ไว้ใน Google Cloud ไป สบายใจ
ในส่วนการ build และ deploy ก็ใช้งาน Docker compose ไป เนื่องจากง่ายสุด ๆ แล้วไม่ต้องทำอะไรมาก โดยในการ build image จะทำแบบ Multi-stage build ไป สุดท้ายได้ image เล็ก ๆ พร้อมต่อการ deploy แล้ว
ลืมไปเลยเรื่องของการทดสอบก็ทำผ่าน net/http/httptest package กับ unit test เล็กน้อย รวมไปถึงทดสอบด้วย Robotframework นิดหน่อย

ส่วนที่สองคือส่วนที่ยากมาก ๆ สำหรับผม คือ Frontend พัฒนาด้วย Angular 6

เห็นว่าหลาย ๆ คนเลือกใช้งาน Angular 6 กัน ดังนั้นอยากศึกษาให้มากขึ้นก็เลยเลือกซะเลย เนื่องจากก่อนหน้านี้ใช้งานแต่ React !! ดังนั้นจึงเริ่มศึกษาสิ่งต่าง ๆ ที่จำเป็นต่อการพัฒนา ประกอบไปด้วย
  • การสร้าง Angular application ด้วย Angular CLI
  • เรียนรู้เรื่องเกี่ยวกับ Module, Routing, Component, Service และ Class ต่าง ๆ
  • การติดต่อไปยัง RESTful API ด้วย http package ซึ่งเป็น common library ของ Angular
  • เรื่องของการทดสอบ ซึ่งจากการสร้างส่วนต่าง ๆ ด้วย Angular CLI มันจะสร้างชุดการทดสอบมาให้ด้วยเสมอ ดังนั้นเขียนซะ
เมื่อศึกษาทุกอย่างเรียบร้อยผ่านไปเร็วมาก ๆ ประมาณ 1 วัน ถามว่าเขียนได้เลยไหม ตอบเลยว่าไม่ !! แต่ก็พอทำให้เข้าใจภาพรวม และน่าจะพอเริ่มทำงานได้ แต่ ... ส่วนงานที่ต้องทำก่อนเลยก็คือ User Interface ที่ดูดี ใช้งานง่าย สิ่งที่ทำคือ ไปหา theme ที่ดูเข้าท่า เมื่อไปค้นหาพบว่า พวก HTML Template ส่วนใหญ่จะมี Stylesheet เป็น SASS/SCSS/LESS ทั้งหมดเลย ชีวิตเริ่มเศร้าแล้ว เพราะว่า แค่ CSS ยังไม่รู็เรื่องเลย ยิ่ง JavaScript ไม่ต้องพูดถึง ส่วนไอ้ 3 ตัวข้างต้น ไม่ต้องคิด คืออะไรยังไม่รู้ แต่ก็กัดฟันใช้ก็แล้วกัน ในส่วนนี้ใช้เวลาไป 3 วันเต็ม ๆ ปวดหัวสุด ๆ !! เมื่อเลือก HTML Template ได้ ก็มาถึงสิ่งที่ยากรองลงมาคือ เอามายัดใส่ Angular Project สิ ตอนแรกก็คิดว่าง่าย ๆ พอทำจริงเท่านั้นแหละ งงกันไปเลย ดังนั้นจึงนั่งทำความเข้าใจพวก Module และ Routing ใหม่อยู่ครึ่งวัน จึงทำการออกแบบได้ดังรูป ดูเหมือนจะวุ่นวายมากหน่อย แต่ความจริงมันวุ่นวายมาก ๆ สำหรับการเริ่มต้น !! แต่สิ่งที่ทำไปนั้น เปลี่ยนไปมาอยู่สัก 5-6 รอบ เพื่อให้ได้สิ่งที่ต้องการ และทำให้ง่ายต่อการเพิ่มหน้าใหม่ ๆ ซึ่งการทำงานจะต้องผ่านการ authentication ในหน้า login ก่อนเสมอ หน้าการทำงานของแต่ละ feature จะอยู่ภายใต้ module Main โดยในแต่ละ module จะมี routing เป็นของตัวเอง ทำให้ชีวิตการพัฒนาง่ายขึ้นมาก ในส่วนนี้ใช้เวลาไป 1 วัน
ทั้งสองส่วนนี้ใช้เวลาและพลังงานไปสูงมาก ๆ สำหรับมือใหม่แบบผม ก็ทุลักทุเลสุด ๆ แต่ผลที่ออกมาก็น่าพอใจ
ในส่วนของการเขียน code ของ component ก็ไม่มีอะไรมาก การจัดการ Form ง่าย ๆ ผ่าน FormBuilder และ Validator ไป ส่วนการติดต่อไปยัง RESTful API ก็ไปเขียนใน service จากนั้นทำการ injection เข้ามายัง component ซึ่งตรงนี้ Angular สนับสนุนอยู่แล้ว ไม่ต้องทำอะไร มีการนำ Pipes มาใช้งาน สำหรับทำการกรองข้อมูลที่ได้รับมาจากฝั่ง Backend พอใช้งานแล้วพบว่า มันสะดวกดีนะ ทำให้ระบบงานมันเร็วมาก ๆ ในมุมมองของผู้ใช้งาน แต่งานด้านหลังไม่ง่ายเลย ในส่วนนี้ใช้เวลาไปสักครึ่งวัน เนื่องจากเอกสารของ Angular มันดีมาก ๆ อธิบายชัดเจน พร้อม code ตัวอย่าง ดังนั้นคนเริ่มต้นที่พออ่านภาษาอังกฤษได้ น่าจะพอทำได้เลย การจัดการ state แทบไม่ต้องจัดการเลย เพราะว่าในแต่ละหน้าก็ทำงานแยกกัน ไม่ต้องมี state ใด ๆ ที่ต้อง share หรือใช้ร่วมกัน ตามจริงมักจะตัดเรื่องนี้ออกไป เพราะว่า เหนื่อยในการจัดการที่ฝั่ง Frontend นั่นเอง แต่ต่อไปถ้า feature เริ่มเยอะ อาจจะต้องกลับมามอง และ ศึกษาต่อไป ข้อมูลบางอย่างเช่นพวก Token ของการ login ก็ทำการเก็บง่าย ๆ ไปก่อนที่ Local Storage ส่วนการ validate และตรวจสอบหรือ Authorization ยังไม่ทำเลย !!

เมื่อพัฒนาทุกอย่างพร้อมแล้ว บนเครื่องทำงานได้ตามที่ต้องการ ชิวมาก ๆ

แต่พอต้อง build ใน production mode ก็เจอปัญหาสิ ทำไม build แล้วไฟล์ CSS มันเล็ก ๆ แปลก ๆ ? ทั้งที่ไฟล์ SCSS นั้นเยอะแยะมากมาย เช่น Bootstrap เป็นต้น ? ยิ่งพอไปลองทดสอบสิ่งที่ Angular มัน build ให้ยิ่งชัดเลยคือ CSS ของผมหายไปไหน ? พอไปดูเอกสารของ ng build พบว่า ต้องเพิ่ม parameter --extract-css=false เข้าไปด้วย จากนั้นทำการ build ใหม่ก็จบพิธีการ build ก็ดูง่ายดีนะ !!

มาถึงการ deploy กันบ้าง

ก็ใช้ Docker compose เช่นเดิม ใช้ Multi-stage build เช่นเดิม ในขั้นตอนแรกทำการ build จาก image ของ NodeJS ตรงนี้ช้าสุด ๆ ในขั้นตอนที่สองก็ใช้ nginx ไปเลย มันเล็กมาก ๆ แต่สิ่งที่ต้องทำเพิ่มอีกหน่อยคือ ทำการ config nginx ให้เป็น reverse proxy นิดหน่อย เพื่อให้สามารถเรียกใช้งาน Backend ได้ โดยที่ไม่เปิด Backend เป็น public ก็ได้ใช้ความรู้อันน้อยนิดที่มีจัดการเขียนไฟล์ nginx.conf ไปประมาณ 5 บรรทัด เป็นอันจบขั้นตอนการพัฒนา
การทดสอบก็เขียนด้วย Robotframework จัดไป 2 test case พอให้มั่นใจว่าทำงานได้นะ

เมื่อทุกอย่างพร้อมทั้ง Frontend และ Backend ก็ deploy ขึ้น production สิครับ

ด้วยคำสั่งเดียวคือ docker-compose up -d เพียงเท่านี้ก็จบการพัฒนาและ deploy ต่อไปก็รอดูผล และ moniroting ต่อไป รวมทั้งการพัฒนา feature อื่น ๆ ขอให้สนุกกับการ coding ครับ

DevSecOps ของมันต้องมี มันจึงมา

$
0
0

หลังจากที่ดู VDO จากงาน DevSecOps พบว่า มีหลาย ๆ เรื่องที่น่าสนใจ หนึ่งในนั้นคือ Effective DevSecOps ทำการอธิบายเรื่องของ Security ในบริบทของ Development และ Operation ไว้อย่างน่าสนใจ เลยนำมาสรุปไว้หน่อย

เรื่องของ Security นั้น

ไม่ควรแบ่งแยกให้ใครดูแลไปเลย หรือแบ่งเป็นทีมหรือแผนก ไม่ควรมีแต่เอกสาร มีแต่กฏและนโยบายออกมา เพื่อให้ทุก ๆ คนทำตาม ยกเว้นคนสร้างกฏ ไม่ควรมาเถียงกันว่าใครทำผิด ว่าใครไม่ทำตามกฏ แต่ทุกคนคือทีม หรือ cyber-security team ไม่รอที่จะมายิง มาเจาะหรือมา hack ระบบอย่างเดียว ดังนั้นเรื่องของ Security มันเป็นเรื่องของทุกคน ขึ้นอยู่กับว่า ใครรับผิดชอบในส่วนไหนบ้าง แต่โดยรวมต้องทำงานกันเป็นทีม ที่สำคัญเรื่องของ Security มันต้องเข้ามาเป็นส่วนหนึ่ง ในการ Development และ Operation ด้วยเสมอ
คำถามที่น่าสนใจจาก VDO เรามาสนใจเรื่อง security กันตอนไหน ตอนที่โดนโจมตีแล้วใช่ไหม ?
ดังนั้น Security all the time, everywhere by anyone นะครับ

มาดูกันว่า จะทำอย่างไรให้มันมีประสิทธิภาพมากขึ้น

การมีเอกสาร มีกฏมากมาย มีนโยบายมากมายเป็นสิ่งที่ดี แต่คำถามคือ แล้วการนำไปใช้งานเป็นอย่างไร ? มีทีมตรวจสอบ รอให้ตรวจสอบเพียงฝ่ายเดียวหรือไม่ ? หรือทีมตรวจสอบมาตรวจและให้ความรู้ในส่วนอื่น ๆ ขององค์กร เพื่อให้ตระหนักรู้ถึงเรื่อง Security !!
การนำมาใช้งานยิ่งสำคัญ ควรมีการตกลง ควรมีเครื่องมือที่เหมาะสม ในแต่ละขั้นตอนของการทำงาน ดังนั้นเมื่อคิดได้ ทำต้องได้ เครื่องมือต้องพร้อม และวัดผลเพื่อปรับปรุงได้เสมอ

ขั้นตอนที่ 1 กำหนดเป้าหมายให้ชัดเจน

ตัวอย่างเช่น
  • ข้อมูลที่เป็นความลับต้องไม่รั่วไหลออกไป เช่น password, certificate หรือ private key เป็นต้น
  • พวก certificate ต่าง ๆ ต้องไม่หมดอายุ
  • พวก library ต่าง ๆ ต้องไม่ล้าสมัย
  • พวก source code ต้องไม่มีช่องโหว่ให้โจมตี
  • ต้อง compliance ไปกับ OWASP TOP 10 เสมอ

ขั้นตอนที่ 2 สร้างกรอบและขั้นตอนการทำงาน

เป็นส่วนที่ยากมาก ๆ ซึ่งต้องทำการสร้างแบบแผนการทำงานทั้งฝั่ง Development และ Operation ทำอย่างไรให้ทั้งสองฝ่ายรู้และเข้าใจเกี่ยวกับเรื่องของ Security ยกตัวอย่างเช่น เรื่องของความลับต้องไม่รั่วไหล ต้องทำการสรุปกฏและนโยบายออกมาที่จับต้องได้ เช่น
  • ต้องไม่เก็บไว้ใน repository
  • ต้องไม่อยู่ในรูปแบบของ plain text
ต้องสรุปการบังคับใช้งานให้ชัดเจน เช่น
  • ทำการ scan repository อยู่เสมอ
  • ทุก ๆ ข้อมูลที่เป็นความลับต้องมีเครื่องมือจัดการเสมอ
ยังไม่พอ ต้องสรุปเครื่องมือที่จะใช้งานแบบชัดเจนไปเลยอีกด้วย เช่น จากนั้นทำการสร้าง process หรือ pipeline ของการทำงาน ว่า Security จะเข้ามาอยู่ในตรงไหนอย่างไร เช่น
  • Code
  • Build
  • Test
  • Deploy
  • Operate

ขั้นตอนที่ 3 ประกาศหรือแจ้งออกไป ให้รับทราบทั้งองค์กร

เนื่องจากถ้าคุณมีแผนงานที่ยอดเยี่ยมมาก ๆ แต่ไม่มีใครรู้ หรือ เข้าใจ หรือ ไม่สนใจ หรือ ไม่ได้นำมาใช้งาน ก็เป็นเพียงแผนงานขยะชิ้นหนึ่งเท่านั้นเอง ดังนั้น นี่คือเวลาขายของ แต่ก่อนอื่นคุณต้องมีผู้สนับสนุนที่แข็งแกร่ง ซึ่งจะช่วยทำให้การใช้งานมีประสิทธิภาพที่ดีขึ้น นี่มันเรื่องของการเมืองในองค์กรชัด ๆ คนในองค์กรควรที่จะต้องมีความรู้ความเข้าใจต่อสิ่งที่กำลังจะนำมาใช้งาน รวมไปถึงประโยชน์ที่จะได้รับ ดังนั้นในขั้นตอนนี้มันเรื่องใหญ่และสำคัญมาก ๆ ส่วนใหญ่มักจะทำให้เป้นงานใหญ่โต ทั้งการจัดงาน workshop ทั้งการติดป้ายประกาศ ทั้งการทำเสื้อ และ สิ่งต่าง ๆ ที่ช่วย promote ทั้งการประชาสัมพันธ์ถึงผลที่จะได้รับ ทั้งการเข้าไปช่วยเหลือ ทั้งเรื่อง Roadmap ขององค์กร

ขั้นตอนที่ 4 การบังคับให้ใช้งานตามกฏและนโยบาย

ซึ่งต้องบอกด้วยว่าต้องทำอย่างไรบ้าง ต้องจับต้องได้ มีทั้งงานที่ต้องทำเอง และงานที่ต้องใช้เครื่องมือมาช่วย

ขั้นตอนที่ 5 ต้องมีการวัดผลอยู่เสมอ

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

ถ้าทำได้ประมาณนี้ น่าจะทำให้ Security เข้ามาอยู่ในทุก ๆ ส่วนของการทำงาน

น่าจะทำให้เราได้เห้นถึงความสำคัญของ Security มากขึ้น วันนี้คุณพร้อมหรือยังกับ DevSecOps เมื่อถึงเวลา ของมันก็ต้องมา และต้องมี
พูดกันเยอะแล้ว ลงมือทำเถอะครับ

NodeJS ลองทำ Hot Reload แบบง่าย ๆ

$
0
0

เมื่อมาพัฒนาระบบด้วย NodeJS หรือ JavaScript ฝั่ง Backend แล้ว สิ่งที่ติดมาจากการเขียน JavaScript ในฝั่ง Frontend นั่นก็คือ Hot Reload (เมื่อ code เปลี่ยนแปลงแล้ว ไม่ต้อง restart server ใหม่) แต่พอไปค้นหาวิธีการดูพบว่า ทำไมมันวุ่นวายจัง ทั้ง webpack ทั้งการ config ที่เยอะไปหมด ดังนั้นเลยลองนั่งหาวิธีการที่ง่ายกว่ามีไหม ซึ่งก็เจอหลายวิธี หนึ่งในนั้นที่ชอบหน่อยคือ การใช้ watcher มาลองใช้กันดู

ขั้นตอนแรก code ที่เราเขียนนั้นต้องดูดีหน่อย

นั่นคือ แยก router ออกมาจากส่วนไฟล์หลักก่อน เนื่องจากการเปลี่ยนแปลงบ่อย ๆ จะเกิดในไฟล์การทำงานไม่ใช้ไฟล์หลัก ดังนั้นโครงสร้างของระบบเป็นดังนี้
  • server.js
  • src/index.js

ขั้นตอนที่สอง เมื่อมีการเปลี่ยนไฟล์ใน folder src แล้วจะทำการ Reload ให้ใหม่

จากสิ่งที่ต้องการนั้น เราจำเป็นต้องใช้งาน watcher แน่นอนว่าใน NPM ก็มี package ให้ใช้ชื่อว่า Chokida แต่ว่า ถ้าเกิดการเปลี่ยนแปลงแล้ว เราจะทำอะไรต่อไปดีละ ? ก็ไปค้นหาต่ออีก ยากจริง ๆ ไปเจอว่า การทำงานของ NodeJS นั้น จะทำการสร้าง caching ไว้ ดังนั้นก็ไปทำการลบ cache ของ Object ต่าง ๆ มันซะเลย [gist id="bf9a1798d20c7b66873de45f9a293a7b" file="1.js"] ลอง print ค่าของ object ที่ caching ใน folder src ออกมาดู พบว่ามีการทำ caching ไว้เพียบเลย ดังนั้นลบไปซะ

ขั้นตอนที่ 3 ยังใช้ไม่ได้นะ

เพราะว่า เราต้อง require ไฟล์ใน folder src ทุกครั้งด้วย เนื่องจากในไฟล์หลักผมไม่สนใจ ดังนั้นมันจะได้รูปแบบการเขียน code ที่ไม่ดี !! ระวังด้วยนะ อย่าเอาขึ้น production ดังตัวอย่าง [gist id="bf9a1798d20c7b66873de45f9a293a7b" file="2.js"] แค่นี้ก็ได้ Hot Reload แบบง่าย ๆ ละ ลองดูครับ ขอให้สนุกกับการ coding Reference Websites https://hackernoon.com/hot-reload-all-the-things-ec0fed8ab0 https://codeburst.io/dont-use-nodemon-there-are-better-ways-fc016b50b45e
Viewing all 1997 articles
Browse latest View live