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

ปัญหาการ build ของ project ที่สร้างด้วย Angular 8

$
0
0

ปัญหาที่เจอ

เกิด error message หลังจากการ build ของ Angular 8 project ดังนี้

Failed to load module script: The server responded with a non-JavaScript MIME type of "text/plain". Strict MIME type checking is enforced for module scripts per HTML spec

การแก้ไขปัญหาในเบื้องต้น

ไปดูใน GitHub issue ของ Angular เจอการแก้ไขปัญหา
ทำการแก้ไขไฟล์ tsconfig.json
ด้วยการเปลี่ยนค่าของ target จาก es2015 เป็น es5
จากนั้นทำการ build ให้ ปัญหาก็จะหมดไป !!

ปัญหานี้จะมีปัญหากับ Web server บางตัว
ยกตัวอย่างเช่นผมใช้ผ่าน NGINX บน Docker
จาก issue นั้นมีคนสังเกตุว่า ใน tag javascript นั้นใน Angular 8
จะไม่ใส่ type=text/javascript มานั่นเอง


ว่าด้วยเรื่องของ Consumer-Driven Contract

$
0
0

หลังจากที่ไปร่วมงาน ThougthWorks Talks Tech 
เรื่อง Sanely Grow your Microservices with Consumer-Driven Contract
จึงทำการสรุปและขยายความของ Consumer-Driven Contract 
เพื่อให้เข้าใจว่าเป็นมาอย่างไร
และมีความแตกต่างจากการทดสอบแบบอื่น ๆ อย่างไร

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

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

ประเด็นที่สำคัญคือ เราจะทำการทดสอบอย่างไรได้บ้าง ?

จาก slide เรื่อง Testing Strategies in a Microservice Architecture 
แบ่งการทดสอบออกเป็น 5 แบบคือ

  1. Unit test
  2. Integration test
  3. Component test
  4. Contract test
  5. End-to-End test

การทดสอบที่น่าสนใจและมักทำให้สับสนมีดังนี้

1. Integration testing

เป็นการทดสอบระหว่างผู้ให้บริการ (Provider) และผู้ใช้บริการ (Consumer)
เพื่อทำให้มั่นใจว่า provider นั้นส่งผลลัพธ์ (Response)
ตามคำร้องขอ (Request) ที่ส่งมาจาก consumer
ทำการกำหนดรูปแบบของ request และ response ไว้อย่างชัดเจน (Pre-defined)
สิ่งที่เตรียมไว้จะถูกเรียกว่า contract

แสดงขอบเขตการทดสอบแบบ Integration ไว้ดังรูป

https://martinfowler.com/articles/microservice-testing/#testing-integration-diagram

2. End-to-End testing

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

โดยที่ interface ของการทดสอบอาจจะเป็น User Interface
เช่น Web browser และ mobile เป็นต้น
หรืออาจจะเป็น API เช่น WebService และ RESTFul API เป็นต้น
แน่นอนว่า
ต้องมีการกำหนด contract ระหว่าง consumer กับ provider ไว้เช่นเดิม
แต่เป็น contract ผ่าน interface นั่นเอง

แสดงขอบเขตของการทดสอบดังรูป

https://martinfowler.com/articles/microservice-testing/#testing-end-to-end-diagram

3. Component testing หรือ Mock/Stub testing

ปัญหาหลักของการทดสอบแบบ integration และ end-to-end
คือ การทดสอบบน environment จริง หรือทำการทดสอบกับ provider จริง ๆ
ส่งผลให้การจัดการและเตรียมสำหรับการทดสอบยาก
แถมบ่อยครั้งยังมีปัญหามากมาย
ทั้งข้อมูลที่เปลี่ยนแปลงตลอดเวลา
ทั้งการเชื่อมต่อมีปัญหา เช่นระบบ network ล่มเป็นต้น
ทั้งไม่สามารถทดสอบซ้ำ ๆ ได้เร็วตามที่ต้องการ

ดังนั้นจึงเป็นที่มีของการจำลองฝั่ง provider ขึ้นมา
บ่อยครั้งเราจะเรียกว่าการ Mock หรือ Stub provider
ทำให้เราสามารถทดสอบในแต่ละส่วนงานได้ง่าย
แถมทดสอบซ้ำแล้วซ้ำเล่าได้ตามที่ต้องการ
ทั้งในกรณี success และ failure

การทดสอบในลักษณะนี้ จะเรียกว่า Component testing
ซึ่งมีความใกล้เคียงกับ integration test อย่างมาก
แต่ต่างกันที่เป้าหมายของมันนั่นเอง

แสดงขอบเขตของการทำงานดังรูป

https://martinfowler.com/articles/microservice-testing/#testing-component-in-process-diagram

4. Contract testing

จากการทดสอบทั้ง 3 แบบที่ผ่านมานั้น
สิ่งที่มีเหมือนกันคือ contract
หรือชุดการทดสอบที่ประกอบไปด้วย  Request จากฝั่ง consumer และ response ที่ได้รับจาก provider

ปัญหาที่ตามมาคือ 
เราจะมั่นใจได้อย่างไรว่า contract เหล่านี้
ยังคงเป็นไปตามที่เราคาดหวัง และถูกต้องเสมอ

ยกตัวอย่างเช่น จาก Component testing นั้น
เราทำการ mock provider ขึ้นมา
ถ้า response จากฝั่ง provider จริง
มีการเปลี่ยนแปลง เราจะทำอย่างไร ?

ถ้าไปตรวจสอบหรือสร้าง contract ระหว่าง consumer กับ provider แบบแปะ ๆ
ก็จะเป็น integration test ไป ซึ่งก็เกิดปัญหาเดิม ๆ
ดังนั้นถ้าเราทำการบันทึก contract ของ provider ใหม่เมื่อมีการเปลี่ยนแปลง
และตอนทดสอบให้จำลอง provider จาก contract นั้น ๆ ขึ้นมา
น่าจะมีประโยชน์กว่าไหม

รวมทั้งการตรวจสอบ response จาก provider นั้น
ไม่จำเป็นต้องตรวจสอบข้อมูลแบบเป๊ะ ๆ
แต่ทำการตรวจสอบในเครื่องของโครงสร้างข้อมูลที่ควรจะเป็น
หรือเฉพาะข้อมูลที่สนใจและสำคัญเท่านั้น
การทดสอบแบบนี้จึงเรียกว่า Contract testing

https://martinfowler.com/bliki/ContractTest.html

การสร้าง contract นั้นจะทำบน consumer และ provider จริง ๆ
โดยเริ่มจากการบันทุกหรือ record contract ขึ้นมาก่อน
จากนั้นจึงทำการทดสอบผ่าน contract นี้เท่านั้น

ที่สำคัญเราสามารถนำ contract ของการทดสอบแบบนี้
มาทดสอบหรือจำลองขึ้นมาตาม contract ที่สร้างขึ้นมาจาก provider จริง ๆ ได้อีกด้วย แสดงดังรูป

เมื่อ provider มีการเปลี่ยนแปลง
จะทำการตรวจสอบหรือ verify ว่า response จาก provider
ในแต่ละ request ของ contract ต่าง ๆ ตรงกันหรือไม่
ถ้าไม่ก็จะ fail ซึ่งเราจะรู้ว่า การเปลี่ยนแปลงนั้นทันที
จากนั้นก็ทำการบันทึก contract ไหม่ต่อไป
ซึ่งตรงนี้เราสามารถ integrate ไปกับระบบ Continuous Integration ได้เลย
แสดงดังรูป

Library ของ Contract testing นั้น มีดังนี้

จะเห็นได้ว่า การทดสอบแต่ละแบบนั้น

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

วันนี้เราทำการทดสอบแล้วหรือยัง

Golang :: มาทำ Live-reload เมื่อ code เปลี่ยนแปลง

$
0
0

ว่าง ๆ เขียนโปรแกรมด้วยภาษา Go
อยากให้โปรแกรมที่เขียนทำการ reload ทันที
หลังจากที่ทำการเปลี่ยนแปลง code 
นั่นคือทำการ build และ run ใหม่นั่นเอง
มาลองหาวิธีกันดู

ปกติพัฒนาฝั่ง Frontend ทั้ง React/Angular/Vue นั้นมีให้แบบชิว ๆ

แต่ในฝั่ง backend ไม่ค่อยมีเท่าไร
ปกติจะใช้ watch คอยดูว่ามีอะไรเปลี่ยนแปลง
จากนั้นจึงทำการ build และ run ใหม่

มาลองดูสิว่า สำหรับภาษา Go มีอะไรให้ใช้บ้าง ?

เมื่อลองไปค้นหาดูพบว่า มีเพียบเลย ทั้งทำเอง
ทั้งใช้ library ยกตัวอย่างเช่น

มาลองใช้ Air เล่น ๆ กันดู

เริ่มต้นด้วยการติดตั้ง มีทั้ง command line ให้ใช้ และ Docker Image
มาใช้แบบ command line ก็แล้วกัน

การติดตั้งสำหรับ MacOS

[gist id="44a0e5eaf8346e4e7dfb00c7973e9186" file="2.txt"]

ทำการ setup project และใช้ Air ดังนี้

ถ้าต้องการแก้ไข configuration ของ Air
ทำการสร้างไฟล์ .air.conf ขึ้นมา
จากนั้นก็ไป copy มาจากไฟล์ .air.conf.example
แล้วทำการแก้ไขตามที่ต้องการ

ยกตัวอย่างเช่น
ผมทำการย้าย main.go ไปไว้ใน folder cmd ดังนี้

[gist id="44a0e5eaf8346e4e7dfb00c7973e9186" file=".air.conf"]

เมื่อทุกอย่างพร้อมก็ run Air เลย
ถ้าแก้ไขไฟล์ใด ๆ จะทำการ reload ใหม่
นั่นคือการ build และ run นั่นเอง ได้ผลดังนี้

[gist id="44a0e5eaf8346e4e7dfb00c7973e9186" file="1.txt"]

เพียงเท่านี้ก็สามารถมี Live reload ของระบบงานที่พัฒนาด้วยภาษา Go แล้ว
ง่าย ๆ มาก

ตัวอย่างของ project ที่ลองใช้อยู่ที่ GitHub:Up1

มาดูคำสั่งใหม่ ๆ ใน Git 2.23

$
0
0

หลังจากที่ทำการ update Git มาเป็น version 2.23
พบว่ามี command ใหม่ ๆ ที่น่าสนใจ เข้ามาแทนที่ command เดิม
จากที่ใช้มานั้นพบว่า มันทำให้เข้าใจได้ง่ายขึ้น
และลดความสับสนใจลงไป
มาดูกันว่ามี command อะไรบ้าง ?

ปกติเราจะใช้ git checkout สำหรับ

  • เปลี่ยน branch คือ git checkout -b other_branch
  • ทำการยกเลิกการเปลี่ยนแปลงไปยัง commit ล่าสุดด้วยคำสั่ง git checkout - <file/directory>

ทำให้คนใช้งานสับสนมากมาย
โดยใน version นี้เปลี่ยนมาใช้ command ใหม่ดีกว่าคือ

  • git switch other_branch
  • git restore <file/directory>

ผลจากการใช้งาน git status ก็เปลี่ยนข้อความ
โดยให้มาใช้ git restore ดังนี้

[gist id="af0aebbccd632a22bf5cdfff6673fdec" file="1.txt"]

ชีวิตดีขึ้นเยอะเลย
แต่ก็ยังมี command อื่น ๆ ทั้งเพิ่มใหม่และเปลี่ยนแปลงพฤติกรรมการทำงานเช่น

  • git for-each-ref
  • git merge --quit
  • git cherry-pick
  • git diff/grep -p
  • git diff/grep -W

มาใช้งานกันครับ

Reference Websites

ใน Go 1.13 มีอะไรที่น่าสนใจบ้าง ?

$
0
0

ผ่านมา 6 เดือนทางทีมพัฒนาก็ได้ปล่อย Go 1.13 ออกมาให้ใช้งาน
ซึ่งมีหลายเรื่องที่น่าสนใจ
แต่หนึ่งในนั้นคือ เรื่อง commpatability กับ Go 1 เสมอ (แต่ถ้า Go 2 ก็ไม่แน่นะ)
มาดูว่ามีอะไรบ้าง ?

  • การปรับปรุงเรื่อง number literal
  • เรื่องของ Error wrapping สำหรับจัดการ error
  • ในการ download module ต่าง ๆ จะผ่าน Go module mirror และ Go checksum database แล้ว
  • เปิดใช้งาน TLS 1.3 by default แต่ก็สามารถปิดได้ด้วยการกำหนด tls13=0 

การปรับปรุงเรื่อง number literal

ซึ่งเริ่มต้นจาก Proposal: Go 2 number literal changes ประกอบไปด้วย

  • เลขฐาน 2 (binary) จะขึ้นต้นด้วย 0b หรือ 0B 
  • เลขฐาน 8 (octal) จะขึ้นต้นด้วย 0o หรือ 0O
  • เลขฐาน 16 เป็น floating-point ได้ด้วย ขึ้นต้นด้วย 0x หรือ 0X
  • Digit separator ด้วย _ ทำให้อ่านง่านขึ้น เช่น 1,000 สามารถเขียนใหม่ได้ 1_000

ดูตัวอย่างเพิ่มเติมได้

[gist id="ddc0e884ed3b42c1b85992d1610e6d81" file="sample.go"]

เพิ่ม Environment variable เข้ามา คือ

  • GOPRIVATE สำหรับกำหนด path ของ module ที่ใช้ภายในทีม ไม่ต้องไป download จากข้างนอก
  • GONOPROXY กำหนดว่าต้องผ่าน proxy หรือไม่ สำหรับการ download module

ตัวอย่างการใช้งาน

GOPRIVATE=*.corp.example.com
GOPROXY=proxy.example.com
GONOPROXY=none

สามารถกำหนดค่าของ Environment variable ผ่านคำสั่ง
$go env -w GOPROXY=direct
$go env -w GOSUMDB=off

ตัวอย่าง code การใช้งาน Error wrapping/unwrap

[gist id="ddc0e884ed3b42c1b85992d1610e6d81" file="try_error.go"]

ทำการ download หรือ upgrade ได้แล้วนะครับ

Reference Websites

สรุปเรื่องของ Modular Monolith จากระบบของ Shopify

$
0
0

จาก VDO เรื่อง Deconstructing the Monolith (Shopify Unite Track 2019)
ทำการอธิบายถึง architecture ระบบของ Shopify
ว่ามีความเป็นมาอย่างไร
ตั้งแต่แบบ Monolith เมื่อระบบมีขนาดใหญ่และซับซ้อน 
จึงเกิดปัญหาและส่งผลกระทบต่อระบบ บริษัท
รวมไปถึง productivity ในการพัฒนาระบบงาน
ดังนั้นทาง Shopify จึงต้องทำการแก้ไขและปรับปรุงนั่นเอง

จาก VDO สรุปได้ว่า

ระบบแบบ Monolith นั้น มันไม่ใช่ architecture ที่แย่ไปเสียหมด
ยังมีข้อดีต่าง ๆ มากเช่นกัน
ทั้ง code อยู่ที่เดียวกัน
ทั้งการทดสอบง่าย 
ทั้งการ deploy ระบบ เพราะว่ามีที่เดียว
แน่นอนว่า ช่วยทำให้พัฒนาและส่งมอบ feature ได้อย่างรวดเร็ว

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

มันคือเรื่องของ Design Payoff Line นั่นเอง

โดยทาง Shopify นั้นก็ได้ทำการปรับปรุงเช่นกัน
ไม่ใช่การเปลี่ยนไปยังรูปแบบของ Microservices
แต่เป็นการปรับไปใช้แนวคิดของ Modular Monolith แทน

มันคืออะไรสำหรับ Modular Monolith ?

จาก VDO อธิบายไว้ว่า
มันคือการนำข้อดีของ Monolith และ Microservices มาใช้ร่วมกัน
ทั้ง code อยู่ที่เดียวกัน
ทั้งการทดสอบและ deploy ที่ง่าย
ส่วน Microservices ก็เช่นเรื่องของ modular
และความเป็นอิสระของแต่ละ services

แสดงดังรูป


https://engineering.shopify.com/blogs/engineering/deconstructing-monolith-designing-software-maximizes-developer-productivity

เป้าหมายหลัก ๆ ของการปรับปรุงก็ไม่มีอะไรซับซ้อน

นั่นคือ ต้องการให้แต่ละส่วนการทำงานแยกกันชัดเจนและอิสระ
แต่ไม่เพิ่ม effort ของการ deploy หรือส่งมอบระบบงาน
รวม ๆ คือ เพิ่ม productivity ของการพัฒนาระบบนั่นเอง

การปรับเปลี่ยนครั้งนี้มีส่วนที่สำคัญคือ

  • โครงสร้างของ code
  • การแยก dependency ให้ชัดเจน
  • กำหนดกรอบการทำงานของแต่ละ module และไม่ให้ทำการเรียกใช้ข้ามกรอบหรือขอบเขตที่กำหนด

การปรับเปลี่ยน architecture ครั้งนี้

สิ่งที่ได้รับกลับมาคือ 
สามารถตอบรับกับความต้องการจากทาง business ได้เป็นอย่างดี
นั่นคือ เป้นการปรับปรุงที่เหมาะกับงานหรือ context นั้น ๆ
ดีที่อื่น อาจจะไม่ดีที่นี่ก็ได้
หรือในทางกลับกัน คือ ดีที่นี่ อาจจะไม่ดีกับที่อื่น
เพราะว่าต่าง context หรืองานนั่นเอง

สุดท้ายแล้ว ถ้าการปรับปรุง

กลับทำให้การดูแลรักษายากขึ้น
กลับทำให้การพัฒนายากขึ้น
กลับทำให้การทดสอบยากขึ้น
กลับทำให้การ dpeloy ยากขึ้น
กลับทำให้ productivity แย่ลง
คิดว่า น่าจะไม่ใช่การปรับปรุงนะ ว่าไหม ?

Reference Websites

สรุปการแบ่งปันเรื่อง React ไว้นิดหน่อย

$
0
0

หลังที่ช่วงนี้แบ่งปันเรื่อง การพัฒนา Frontend app ด้วย React นิดหน่อย
พบว่ามีหลายอย่างเปลี่ยนไปและน่าสนใจมากยิ่งขึ้น
แต่ก็พบว่า เรื่องพื้นฐานยังคงสำคัญ
จึงทำการสรุปสิ่งที่แบ่งปันไว้นิดหน่อย

เริ่มจากแนวคิดการแบ่งส่วนทำงานเป็น Component

นั่นคือ UI ในแต่ละหน้าจะแบ่งเป็น component ย่อย ๆ
จากนั้นก็นำมารวมกัน หรือ composition เพื่อทำงานตามที่ต้องการ 
รูปแบบของ component เป็นดังนี้

[gist id="750211ed51fee1d198a8c4ccc5ffb31a" file="1.js"]

โดยที่ class HelloComponent นั้น
จะทำการซ่อนส่วนของการแสดงผลไว้ภายใน
ผ่าน method ชื่อว่า render() ซึ่งเป็น method จาก React Component
นี่มันโลกของ Object-Oriented ชัด ๆ

React component ทุก ๆ ตัวจะต้องมีส่วนของการ render
หรือส่ง output ออกมาเสมอ

แต่สามารถสร้าง Component ในรูปแบบของ function ได้

[gist id="750211ed51fee1d198a8c4ccc5ffb31a" file="2.js"]

จากตัวอย่างพบว่า
การสร้าง component ด้วย function นั้น
จะสั้นกระชับ และ สะดวกกว่ามาก
โดยที่ยังทำงานเหมือนกับ Component class
แต่ในรายละเอียดมีความแตกต่างกัน
อ่านเพิ่มเติมได้ที่ blog :: How Are Function Components Different from Classes?

ทั้ง Class และ function component ยังคงส่งข้อมูลระหว่าง component ผ่าน props ได้เหมือนกัน

โดยที่ข้อมูลใน props นั้น สามารถอ่านได้อย่างเดียว
ไม่สามารถทำการแก้ไขได้ (Immutable)
ซึ่งความสามารถนี้ ป้องกัน side effect หรือผลกระทบจากการแก้ไขข้อมูลได้สบาย ๆ

ส่วนการส่งข้อมูลระหว่าง component หรือ Data flow ก็เป็นแบบทางเดียว (Unidirectional data flow)
หรือเป็นการส่งข้อมูลทางเดียว จากบนลงล่างเท่านั้น

[gist id="750211ed51fee1d198a8c4ccc5ffb31a" file="3.js"]

ต่อมาเรื่องของ Higher-Order Component (HOC)

เป็นอีกรูปแบบหนึ่งที่ได้รับความนิยมจากเหล่า React developer
เพื่อง่ายต่อการ reuse component 
เราสามารถส่ง component เข้าไปยัง compoenent หนึ่งได้
เหมือนกับการส่ง parameter ไปยัง function หนึ่ง ๆ นั่นเอง

รูปแบบของ HOC เป็นดังนี้

[gist id="750211ed51fee1d198a8c4ccc5ffb31a" file="4.js"]

  แต่เพื่อให้เป็น Higher-Order Function (HOF)

เปลี่ยน class มาเป็น function ได้ดังนี้

[gist id="750211ed51fee1d198a8c4ccc5ffb31a" file="5.js"]

ตอนต่อไปว่าด้วยเรื่องของ Hooks

ซึ่งช่วยทำให้หลายสิ่งอย่างง่ายขึ้น
ทั้งการจัดการ state และ life cycle ของ component
รวมทั้งทำงานร่วมกับ Function component ได้สะดวกอีกด้วย

แต่จาก web ของ React ไม่แนะนำให้ migrate มาทั้งหมด
แต่บอกให้ค่อย ๆ ทำไปตามความเหมาะสม
เนื่องจาก Hooks ยังเป็นของใหม่ และ ไม่มีแนวทางที่ดีมากนัก
จำเป็นต้องศึกษาและใช้งานกันต่อไป

สรุปจาก VDO เรื่อง Modern Continuous Delivery

$
0
0

ปัญหาในการพัฒนา software ส่วนใหญ่ที่พบเจอคือ

"It didn’t work in production”

นั่นคือทุกอย่างมันจะดูดีมาก ๆ 
เมื่อไม่ทำการ deploy ไปยัง production server !!

สาเหตุของความผิดพลาดประกอบไปด้วยอะไรบ้าง ?

  • มีขั้นตอนที่ยุ่งยาก มากมาย
  • มี script ต้อง run เยอะ
  • ทำการ deploy แบบ manual

หมายความว่า
เรากำลังหลอกตัวเองอยู่ตลอดเวลาใช่ไหม
ว่าระบบงานของเราเสร็จแล้ว
และพร้อมทำการ deployเพื่อส่งมอบระบบงานไปให้ผู้ใช้งาน !!

ดังนั้นเราน่าจะต้องมีกระบวนการและระบบอะไรบางอย่าง
มาช่วยจัดการเรื่องเหล่านี้นั่นคือ
ที่มาที่ไปของ Continuous Delivery
และเหล่าเครื่องมือต่าง ๆ ให้ใช้งาน

เมื่อมีขั้นตอนและเครื่องมือสำหรับการส่งมอบระบบงานที่ดีแล้ว

ทั้งการ reproduce software ขึ้นมาใหม่
ทั้งการนำ automation process มาใช้
ทั้งการนำ automation test มาใช้
ทั้งการนำ automation deployment มาใช้

แต่เมื่อมาดูที่ระบบงานพบว่า

Architecture ของระบบนั้นยังเป็น Monolith และ service ย่อย ๆ มีขนาดใหญ่
ทำให้เมื่อมีการเปลี่ยนแปลงในครั้งหนึ่ง ๆ
ต้องทำการ build, test และ deploy ระบบเกือบจะทั้งหมดพร้อม ๆ กัน
รวมทั้งอาจจะยังต้องมี manual process บางอย่างอีกด้วย
เช่นการเปิดปิด firewall หรือพวก load balance
หรือหนักกว่านั้น 
การ rollback เมื่อการ deploy มีความผิดพลาด ทำได้ยาก
การทดสอบในระดับ UI พังง่าย หรือไม่เสถียรเลย    
การส่งมอบและ deploy ยังเป็นแบบ Big bang

ทำให้เกิดแนวคิดในการแก้ไขปัญหาเหล่านี้ขึ้นมา

ทั้ง Microservices
ทั้ง Infrastructure as a Code
ทั้ง Testing framework ใหม่ ๆ ที่ช่วยให้การทดสอบมีความเสถียรมากขึ้น

ส่งผลให้เกิดคือ
แยก service ใหญ่ ๆ ออกเป็น service เล็ก ๆ
โดยแต่ละ service จะมีขั้นตอนการทำงานตั้งแต่ build, test และ deploy ไปเลย
แสดงดังรูป

แต่แนวทางของ Microservices ก็มีปัญหาเช่นกัน

เนื่องจากในแต่ละ service ต้องมีทีมที่ดูแล
แต่ละคนจะต้องมีความสามารถในเรื่องต่าง ๆ ที่จำเป็นต่อการพัฒนาและส่งมอบระบบ
ทั้ง Dev, QA/Tester และ Operation เป็นต้น
ทำงานร่วมกัน ไปด้วยกัน มีเป้าหมายเดียวกัน
เพื่อส่งมอบระบบที่มีคุณภาพสูงและรวดเร็ว
นี่มันคือแนวคิด DevOps ใช่ไหม ?

ที่สำคัญกระบวนการทำงานและเครื่องมือก็เปลี่ยนไป

เพื่อให้เหมาะสมกับงานและคนอีกด้วย  ประกอบไปด้วย

  • Develop และ Build เช่น CI/CD pipeline, Container (Docker, Kubernetes), Feature toggle และ Trunk-based development
  • Test ประกอบไปด้วย Unit, Integration, Component, Contract และ End-to-end testing
  • Deploy จาก script หรือ manual process เปลี่ยนมาเป็น declarative deployment แทน ทำให้ repeat ได้ง่ายขึ้น (Help, Ks) รวมไปถึง strategy ในการ deploy เพื่อลดเวลา downtime เช่น Rolling update, Blue green deployment และ Canary deployment ไปจนถึง dynamic environment อีกด้วย
  • Monitor  เช่น observability ต่าง ๆ คือ Centralize logging, Distributed tracing และ Metric ต่าง ๆ ของระบบ

โดยแต่ละส่วนนี้ จำเป็นต้องมีความปลอดภัย (Security) ด้วย
เพื่อป้องกันการโจมตีหรือบุกรุกในจุดต่าง ๆ
รวมทั้งเรื่องการจัดการ secret ต่าง ๆ

Reference Websites


สวัสดี GitHub Package Registry

$
0
0

วันนี้ได้รับ email ให้เข้าใช้งาน GitHub Package Registry ซึ่งอยู่ในสถานะ beta
โดยจะเป็น service สำหรับจัดเก็บ dependency/package ของภาษาโปรแกรมต่าง ๆ
จะเหมือนกับ

นั่นทำให้ code ที่จัดเก็บใน GitHub
สามารถใช้จัดเก็บ dependency ต่าง ๆ ได้อีกด้วย
เป็นเหมือนกับ One-stop service ไปเลย

ความสามารถพื้นฐานประกอบไปด้วย

  • เรื่องความปลอดภัยก็เช่นเดียวกับ Github นั่นเอง
  • สามารถใช้ได้ทั้ง public และ private
  • สามารถจัดการ permission ในการใช้งานได้
  • แน่นอนส่าจัดเก็บได้หลากหลายรูปแบบ
  • มีข้อมูลการใช้งานต่าง ๆ ทั้งการเปลี่ยนแปลงและการ download เป็นต้น
  • ทำงานร่วมกับ GitHub APIs, Action และ web hooks ได้
  • สามารถค้นหา package ที่มีในระบบทั้งหมดได้

รูปแบบของ package ที่สนับสนุนประกอบไปด้วย

  • Npm
  • Gem
  • Apache Maven
  • Docker
  • Nuget

มาดูการใช้งาน เพื่อเก็บ Docker Image กัน

ขั้นตอนที่ 1 ทำการสร้าง token อนุญาตให้ใช้งาน read และ write package ดังรูป

นำ token ที่ได้มาทำการ login เข้าระบบผ่าน docker ดังนี้

[code] $docker login docker.pkg.github.com -u USERNAME -p PASSWORD/TOKEN [/code]

ขั้นตอนที่สอง 

ทำการสร้าง repository ใน GitHub สำหรับนำ Docker Image ไปเก็บ
จากนั้นทำการสร้าง Docker Image ที่มีรูปแบบตามที่กำหนดคือ

[code] docker.pkg.github.com/OWNER/REPOSITORY/IMAGE_NAME:VERSION [/code]

จากนั้นทำการ push ขึ้นเป็นเป็นอีกเรียบร้อย ยกตัวอย่างเช่น

[code] $docker image push docker.pkg.github.com/up1/demo-package/hello-world:0.1 [/code]

เมื่อทุกอย่างเรียบร้อย ก็ไปดูผลงานที่ GitHub ได้เลย
แสดงดังรูป

เพียงเท่านี้ก็สามารถใช้งานได้แล้ว มาลองใช้กันดู

สวัสดี Java 13

$
0
0

ในที่สุดก็ถึงเวลานัดของ Java 13 
จาก blog ของ Oracle เรื่อง Java 13 นั้น
บอกว่า ทำการปิด issue ไป 2,126 ตัว โ
โดยมีผู้ร่วมแก้ไขจากบริษัทต่าง ๆ ดังนี้

ใน release นี้จะมี 5 feature

แต่มี feature ที่น่าสนใจสำหรับนักพัฒนา 2 ตัวแต่ยังอยู่ในสถานะ Preview คือ

  • JEP 354 :: Switch Expression มีมาตั้งแต่ Java 12 และยังอยู่ในสถานะ preview ต่อไป ซึ่งเคยเขียนการใช้งานไว้ที่ Blog:: Switch expression ใน Java 12
  • JEP 355 :: Text Blocks หรือการประกาศ string แบบ multiline นั่นเอง

มาดูตัวอย่างการใช้งาน JEP 355 :: Text Blocks

ใช้งานด้วย double quote 3 ตัวทั้งเปิดและปิด

[gist id="1db1ca426d01acda0f17b83f95deba9e" file="TextBlock.java"]

ทำการ compile และ run ด้วยคำสั่ง

[gist id="1db1ca426d01acda0f17b83f95deba9e" file="1.txt"]

ยังไม่พอนะ String ยังมี method ใหม่เพิ่มเข้ามาอีกคือ

  • stripIndent() ทำการเอา indent หน้าบรรทัดแรกและสุดท้ายออกไป
  • translateEscapes() ทำการแปลงอักขระพิเศษใน string ให้อยู่ในรูปแบบของ string ปกติ
  • formatted(Object... args) ซึ่งทำงานเหมือนกับ format() นั่นเอง แต่ใช้ร่วมกับ text block ได้เลย

มาดูตัวอย่าง นี่มัน template ชัด ๆ

[gist id="1db1ca426d01acda0f17b83f95deba9e" file="TextBlockFormatted.java"]

มาลองใช้งานกันดูนะ

เขียนไว้กันลืม เรื่องเปิด localhost ให้เข้าจากที่ไหนก็ได้

$
0
0

https://ngrok.com/

ปัญหาต้องการทดสอบระบบงานที่อยู่บน localhost
ให้สามารถเข้าจากที่ไหนก็ได้
หรือเหมือนผ่าน public ip นั่นเอง
เนื่องจากทดสอบระบบงานก่อนจะ deploy จริง
หรือทำการส่งให้ลูกค้าหรือผู้ใช้งาน
หรือต้องการจำลอง server ขึ้นมาให้เสมือนจริง
เพื่อเชื่อมต่อกับระบบต่าง ๆ ในขั้นตอนการพัฒนา
เช่นพวก Web Hooks หรือ API ต่าง ๆ จาก LINE, GitHub และ Slack เป็นต้น

การแก้ไขก็ไม่ยาก แต่มักลืมประจำ

จึงทำการบันทึกไว้หน่อยว่ามีอะไรให้ใช้งานบ้าง

ต่อไปไม่น่าลืมอีกแล้ว
ใครมีตัวไหนที่น่าสนใจ ช่วยบอกด้วยนะครับ

มาลองใช้งาน Tracking API ของ ไปรษณีย์ไทยกัน

$
0
0

เห็นใน timeline มีการ share เรื่องไปรษณีย์ไทย
เปิด API สำหรับการ tracking หรือติดตามสถานะของการส่งของได้
เป็นแนวทางที่ดีมาก ๆ และน่าจะทำมาตั้งนานแล้ว
ดังนั้นมาดูกันหน่อยว่ามีอะไรให้ใช้งานบ้าง ?
และใช้งานแล้วเป็นอย่างไร ?

ไม่ได้เข้า web นี้นานมาก ๆ  (Font ที่ใช้งานดูไม่น่าใช้เลย)
ก็เห็นว่าเปลี่ยนใหม่แล้วพัฒนาใหม่เป็น Single Page Application (SPA) ด้วย
แถม responsive อีกด้วย แจ่มเลยนะ
สนับสนุน 3 ภาษาไปเลยคือ ไทย อังกฤษ และ จีน
แต่เปลี่ยนภาษาเพียงเมนูนะ ส่วนข้อมูลภาษาไทยล้วน ๆ !!

ลองเข้าไปสมัครและใช้งานกันหน่อย

โดยผมสมัครแบบลูกค้าทั่วไป
จะมีข้อจำกัดในการใช้งาน API คือติดตามได้ 1,000 หมายเลขต่อวัน
ส่วนลูกค้าองค์กรได้ 10,000 หมายเลขต่อวัน

เมื่อ login เข้าไปก็มีเมนู 4 ส่วนคือ

  • Dashboard หรือ แผลงควบคุม
  • Track หรือการติดตาม
  • Analytic หรือการวิเคราะห์ ส่วนนี้ยังไม่เปิดให้ใช้งาน
  • Developer guide หรือสำหรับนักพัฒนา เราจะมาดูในส่วนนี้กัน

ในส่วนของ API ที่เปิดให้ใช้งานนั้นแบ่งเป็น 2 ส่วนคือ

  • Public API ประกอบไปด้วย SOAP API และ RESTful API
  • Webhook เอาไว้ integrate กับระบบงานของเรา ซึ่งทางระบบของไปรษณีย์ไทยจะส่งมาให้เมื่อมีการเปลี่ยนแปลง

โดย RESTful API ของรูปแบบ API ใหม่ที่แนะนำให้ใช้
เพราะว่า SOAP API มันเก่าละ แถมช้าด้วย
ขั้นตอนการใช้งานเป็นดังนี้

ขั้นตอนที่ 1 ก็สร้าง token ก่อนเลย (Static Token)

(ใช้ภาษาอังกฤษนะครับ เพราะว่าภาษาไทยอ่านยาก)

ขั้นตอนที่ 2 มาอ่าน API document กัน

เปลี่ยนเป็นภาษาอังกฤษ ก็ยังเป็นภาษาไทยอยู่ !!

การใช้งาน API ไม่ยากเป็นดังนี้

  1. ทำการ getToken โดยใช้ static token จากขั้นตอนที่ 1 ใส่ใน HEADER ของ HTTP POST ไปเลย แล้วจะได้ token มามีอายุการใช้งาน 1 เดือน (อย่าลืมขอใหม่ทุกเดือน)
  2. ทำการเรียกใช้งาน API อื่น ๆ ด้วยการส่ง token ที่ได้จากข้อ 1 ผ่าน HEADER ไปด้วย ประกอบไปด้วย GetItems(ครั้งละไม่เกิน 100 item) และ RequestsItems (ครั้งละมากกว่า 100 item ขึ้นไป)

แต่จากการใช้งานพบว่า GetToken API นั้นไม่มีปัญหาอะไร

ใช้งานได้ปกติ ได้ token กลับมาตามที่อธิบายไว้ในเอกสาร แสดงดังรูป

GetToken API with Postman

แต่เมื่อนำ Token ที่ได้จาก GetToken API มาใช้ในการดึงข้อมูลผ่าน GetItems API กลับไม่ได้ !!

แจ้งว่า HTTP Code 403 คือ HTTP 403 Forbidden
[เกิดในขั้นตอน Authentication] ไม่ผ่านการอนุญาติ
ไม่รู้ว่าเป็นเพราะว่าอะไร ฝากทีมงานพัฒนาดูให้ด้วยนะครับ
หรือต้องผ่านขั้นตอนอะไรอีกหรือไม่ ?

GetItems API with Postman

ใช้งานไม่ได้ ก็จบตรงนี้ดีกว่า

เพิ่มเติม คือใช้งาน API ได้แล้ว

จาก comment ใน Facebook บอกว่า
ค่าที่ใส่ตรง Authorization ใน HEADER นั้นต้องขึ้นต้นด้วย Token+ช่องว่าง 1 ตัว

ผมจึงมาลองใช้งานพบว่า ได้จริง ๆ ด้วย
และเมื่อกลับไปอ่านเอกสารก็มีจริง ๆ ด้วย
ส่วน GetToken API ไม่ต้องใส่คำว่า Token ไปก็ได้นะ !!!
แสดงว่าทั้ง 2 API มีเงื่อนไขการตรวจสอบต่างกันหรือไม่ ?

เพิ่มเติม
Collections ของ Postman เอาขึ้นไว้ที่ GitHub::Up1

[Golang] ทำการ export metric ต่าง ๆ ออกมาในรูปแบบของ Prometheus

$
0
0

จากที่ทำการแบ่งปัน
เรื่องการพัฒนาระบบงานด้วยแนวคิด Microservices ด้วย Java technology

มีคำถามว่า
ระบบงานที่พัฒนาด้วยภาษา Go นั้น
สามารถ export metric หรือค่าตัวเลขต่าง ๆ ของระบบงานที่พัฒนาได้หรือไม่
ทั้ง CPU/IO/Memory/Process 
รวมไปถึงการ custom metric ต่าง ๆ ของระบบงานอีก

โดยให้ออกมาอยู่ในรูปแบบของ Prometheus
เพื่อจะได้ง่ายต่อการจัดเก็บ
จากนั้นจึงเอามาแสดงผลในรูปแบบ graph ต่าง ๆ
รวมไปถึงการสร้าง rule และระบบ alert ต่าง ๆ ได้

ก็เลยบอกไปเลยว่าได้สิ

ที่สำคัญ Prometheus เตรียม client library ไว้ให้แล้วด้วย

มาดูตัวอย่างการใช้งานแบบง่าย ๆ

[gist id="b998e668de1f79707a957196d35e040f" file="demo.go"]

จากนั้นลอง run และเข้าไปที่ url=http://localhost:8009/metrics
จะได้ผลลัพธ์ดังนี้

[gist id="b998e668de1f79707a957196d35e040f" file="result.txt"]

ช่วยทำให้เราได้เห็นค่าตัวเลขต่าง ๆ ที่น่าสนใจ

ยกตัวอย่างเช่น

  • จำนวนของ Go_threads
  • จำนวนของ Go_routines
  • จำนวนของ memory ที่ระบบงานจองและใช้งาน
  • จำนวนการทำงานของ Garbage collector
  • จำนวนของ request ซึ่งแยกตาม response code ของ HTTP ให้อีก

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

ปล. การรับส่งค่า metric ระหว่างระบบงานของเรากับ prometheus มีทั้งแบบ push และ pull ลองเลือกใช้งานกันดู

ว่าด้วยเรื่อง 4P จากหนังสือ Lifelong Kindergarten

$
0
0

https://bookscape.co/books/education-and-learning-societies/lifelong-kindergarten

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

ในหนังสือเรียกกระบวนการนี้ว่า Creative Learning Spiral

ประกอบไปด้วย

  • Imagine การจินตนาการถึงสิ่งที่อยากจะทำ
  • Create การสร้างจากจินตนาการออกมาให้เป็นรูปเป็นร่าง
  • Play การได้ลองเล่น ทดลอง ทำสิ่งต่าง ๆ ของตนเองขึ้นมาแบบไม่รู้จบ
  • Share การได้แบ่งปันให้กับเพื่อน ๆ ได้ลองเล่นด้วยกัน ทำให้ได้รับความคิดเห็น เพื่อใช้ในการปรับปรุง เป็นกระบวนการที่สำคัญของการคิดเชิงสร้างสรรค์อย่างมาก (Learing to share)
  • Reflect การได้กลับมาคิดทบทวนจากสิ่งต่าง ๆ ที่ได้ทำไป จากการเล่น การทำงานร่วมกันและแบ่งปัน เพื่อปรับปรุงให้ดีขึ้น หรือผู้ที่ดูและหรือผู้สอน อาจจะนำสิ่งที่ได้รับมาพูดคุยทั้งเรื่องการคิดและออกแบบอีกด้วย
  • กลับมา Imagine อีกครั้ง ซึ่งกระบวนการแบบ iteration นั้นเป็นหัวใจของกระบวนการนี้เลย เพื่อนำไปสู่แนวคิดใหม่ ๆ ปรับปรุงให้ดีขึ้นอีกด้วย

แสดงดังรูป

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

ในหนังสือนั้นจะแบ่งการเรียนรู้เชิงสร้างสรรค์ไว้ 4 เรื่อง หรือ 4P คือ

  1. Project หรือโครงงาน ซึ่งคนเราจะเรียนรู้ได้ดีที่สุดเมื่อกำลังลงมือทำ project ที่สนใจหรือมีความหมายต่อเรามาก ๆ
  2. Passion หรือความหลงไหล เมื่อคนเรามีความใส่ใจและสนใจในเรื่องอะไรแล้ว จะสามารถทำสิ่งนั้นได้ยาวนาน ถึงแม้จะยากก็ตาม ทำให้ได้เรียนรู้สิ่งใหม่ ๆ มากมายแบบที่ไม่เคยเจอมาก่อน จะเรียกว่าเข้าสู่สภาวะ Flow
  3. Peers หรือเพื่อน การเรียนรู้จะเจริญเติบโตหรือขยายตัวมากขึ้นเมื่อมีกิจกรรมทางสังคม (Socail activity) เพื่อทำการแบ่งปันแนวคิด ทำงานและสร้าง project ต่าง ๆ ขึ้นมาด้วยกัน กลายเป็นชุมชนแห่งการเรียนรู้ขึ้นมา
  4. Play หรือการเล่นสนุก ขั้นตอนในการเรียนรู้มันคือการทดลองดังนั้น มันจึงต้องสนุก ถึงแม้จะเป็นเรื่องยากแต่ยังคงสนุก ทำให้เราได้ลองทำในสิ่งใหม่ ทดลองในสิ่งที่ไม่เคยทำ ได้ลองเสี่ยง จากนั้นก็ทำซ้ำไปเรื่อย ๆ ดังนั้นสภาะแวดล้อมสำคัญมาก ๆ สภาวะแวดล้อมควรเป้นสนามเด็กเล่นไม่ใช่คอกให้เด็กเล่น

ตามไปเจอ paper ที่ผู้เขียนเขียนไว้
เรื่อง GIVE P’S A CHANCE:PROJECTS, PEERS, PASSION, PLAY
ลองอ่านเพิ่มเติมดูครับ เป็นเรื่องที่น่าสนใจมาก ๆ
และอ่านเพิ่มเติมในหนังสือครับ
เป็นหนังสือที่ไม่อยากอ่านจบเลยจริง ๆ

เรื่องของ Console API ใน JavaScript

$
0
0

จากการพัฒนาระบบงานด้วย JavaScript และ NodeJS นั้น
พบว่ามีการใช้คำสั่ง console.log() เป็นจำนวนมาก
บ่อยครั้งการใช้งานไม่ได้ผลตรงที่ต้องการอีกด้วย
จึงทำการแนะนำการใช้งาน Console API เพิ่มเติมนิดหน่อย
มาเริ่มกันเลย

ปล. 
ตอนขึ้น production ก็เอาออกกันด้วยละ 

การใช้งาน Console API พื้นฐาน

ส่วนมากจะเจอในการ debug การทำงานของระบบงานดังนี้

  • console.log() เจอเยอะที่สุด
  • console.warn()
  • console.error()

มาดู method อื่น ๆ ที่มีประโยชน์กันบ้าง

1. Console.table()

ทำการแสดงข้อมูลของ object และพวก array ออกมาในรูปแบบตาราง
ซึ่งอ่านง่านและเข้าใจได้ง่าย

2. Console.assert()

ทำการตรวจสอบค่าที่ส่งเข้าว่า true หรือ false
ถ้าค่าที่ส่งเข้าไปได้ผลเป็น false แล้วจะเขียน log ออกมาให้เราได้เห็น
แต่ถ้าเป็น true จะไม่แสดงผล log ออกมา
ค่าที่เป็น false ประกอบไปด้วย 0, false, ค่าว่าง เป็นต้น

3. Console.count()

สำหรับการนับค่าหรือนับจำนวนครั้งในการทำงาน
มีประโยชน์ตอนที่เราจะ debug ระบบงานอย่างมาก
ยิ่งพวกที่มี life cycle แปลก ๆ จะทำให้เราเข้าใจการทำงานได้ง่ายขึ้น
ซึ่งจะใช้ควบคู่ไปกับ Console.countReset()

4. Console.group()

ทำการจัดกลุ่มของ log ให้อ่านเข้าใจได้ง่าย
โดยเริ่มด้วยการใช้งาน Console.group()
และปิดท้ายด้วย Console.groupEnd()

ยังมีอีกนะ
เช่นถ้าต้องการดู performace ของการทำงานของ code
สามารถใช้งาน console.time() และ console.timeEnd() ได้อีก

ยังไม่พอนะ Console.log() ยังใส่ style ได้อีกด้วยนะ

จะเห็นได้ว่า Console API นั้นมีความสามารถให้ใช้เยอะมาก ๆ

ลองศึกษาเพิ่มกันได้ครับ


เขียน test กันอย่างไร ?

$
0
0

จากคำถามใน Facebook group ว่าด้วยเรื่อง เขียน test กันอย่างไร ?
เลยกลับมาลองมองตัวผมเองว่า
ผมเขียน test อย่างไรบ้าง ?
เนื่องจากมีแนวทางเยอะมาก ๆ
และลองผิดลองถูกมาเรื่อย ๆ ส่วนใหญ่ก็จะผิดเสียด้วย

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

ทั้งเรื่องของ timing หรือเวลาในการเขียน test หรือเวลาในการทดสอบ
ทั้งทำหลังจากที่ระบบงานเสร็จสิ้น (Test-Last)
ทั้งทำก่อนจะเริ่มลงมือพัฒนา (Test-First)

ถ้าไปเจอ Legacy code ละ จะทำอย่างไร ?
เขียนและทดสอบกันอย่างไร ?

ถ้าไปเจอกับทีมที่ไม่เขียน test ละทำอย่างไร ?

ถ้าไปเจอ business ที่เปลี่ยนแปลงเร็วมาก ๆ จะทำอย่างไร ?

เนื่องด้วยบริบทหรือ domain มันหลากหลายมาก ๆ

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

ถ้าเริ่มเขียน test แรก ๆ

ผมก็จะเขียนมันไปให้หมด ไม่เชื่อมั่นอะไรก็เขียนมันไป
เขียนมากจนกลับมาดู
ยังด่าตัวเองว่า Test แบบนี้เขียนไปทำซากอะไร !!

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

แต่ถ้ายังไม่เคยทำ ก็ให้ทำก่อน อย่าเพิ่งไปเชื่อคำพูดของคนอื่น ๆ

โดย test ต่าง ๆ มักจะมาจาก acceptance criteria ของแต่ละ feature/flow ที่คุยกันไว้

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

อีกอย่างถ้าเรามี acceptance criteria แล้ว
เราต้องทำการแบ่งปัญหาใหญ่เป็นปัญหาเล็ก ๆ (Work breakdown)
เพื่อค่อย ๆ แก้ไขไป 
ตรงนี้เป็นความสามารถที่ต้องฝึกอย่างมาก
ถ้าเราไม่สามารถแยกได้แล้ว เราจะแก้ไขปัญหาได้ยากมาก ๆ หรืออาจจะออกทะเลได้ง่าย ๆ

ต่อมาในการเขียน test นั้น

จะมีหลาย level อีก ซึ่งแต่ละ level
นั้นก็เป็นเรื่อง ของความเชื่อมัน ของความไว้เนื้อเชื่อใจ
ทั้ง End-to-End testing สำหรับ UI
ทั้ง End-to-End testing สำหรับ API
ทั้ง Contract, Component test
ทั้ง Integration test
ทั้ง Unit test


จะทดสอบใน level ไหน ตรงนี้ผมคิดว่ามันมี trade-off ทั้งหมด
จะมาวางแนวทางกัน เพราะว่า มันไม่ใช่แค่การ test เพียงอย่างเดียว

หลัก ๆ ที่จะทดสอบมาก ๆ หรือละเอียดสุด ๆ คือ
ส่วนงาน business logic ที่มีความสำคัญและซับซ้อน
ในส่วนนี้จะพยายามตัดควบคุม dependency ให้ได้มากที่สุด
เพื่อทดสอบการทำงานว่า
เป็นไปตามเงื่อนไขที่กำหนดหรือไม่ ทั้งเหตุการณ์ดีและแย่

เพียงแค่การทดสอบอย่างเดียวไม่พอ !!

เรื่องของ environment ของการทดสอบก็สำคัญ
ว่าคล้ายหรือเหมือนจริงหรือไม่ ?
เพราะว่า ผมมักจะเจอว่าเรามี environment ต่าง ๆ เยอะมาก
ทั้ง dev, test, QA, SUT, SAT, UAT, Staging, Pre prod 
แน่นอนว่า ทดสอบผ่านมาทั้งหมด !!
แต่เมื่อขึ้น Production เมื่อใด มีปัญหาเมื่อนั้น ใช่หรือไม่ ?

รวมไปถึงเรื่องของ Monitoring system หรือพวก Observability ของระบบ
ทั้งค่าในเชิงตัวเลข หรือ metric ของระบบงาน
ไม่ใช่ตัวเลขทาง infrastructure เท่านั้น มีหรือไม่

ถ้ามีตัวเลขเหล่านี้แล้ว มีระบบการ alert ที่ดีหรือไม่
แจ้ง alert ตอนที่มีปัญหาแล้ว
หรือแจ้งก่อนที่จะเกิดปัญหา
หรือแจ้งเมื่อมีอาการแปลก ๆ หรือน่าสงสัย
เพื่อทำให้เรารู้ปัญหาได้อย่างรวดเร็ว

เป้าหมายหลัก ๆ ของการทดสอบคือ

เร็ว เพื่อให้ได้ feedback ที่เร็ว
ระบุจุดที่เกิดปัญหาได้เลย ไม่ต้องไป debug หา
ช่วยทำให้การพัฒนามี productivity สูงขึ้น
ไม่ใช่ว่า test ไป block การพัฒนาแบบนี้ก็ไม่ถูก
หรือถ้าจะ debug จะได้ระบุจุดไปเลย เพราะว่าบางครั้งระบบก็ไม่สามารถเข้าไป test ได้

สุดท้ายต้องเข้าใจสิ่งที่กำลังจะทำก่อนเสมอ

เครื่องไม้เครื่องมือที่ใช้ก็ต้องคล่องมือด้วย
ตลอดจนทีมและ environment ต่าง ๆ ก็ต้องสนับสนุนเช่นกัน

ตอบคำถามเรื่อง Contract testing

$
0
0

จากการแบ่งปันเรื่อง การทดสอบนั้น
มีคำถามเรื่องของ Contract testing มันคืออะไร ?
ทำไมต้องใช้ด้วย ?
ทำอย่างไรบ้าง ?
เลยทำการแบ่งปันให้กับทางทีมไว้นิดหน่อย

โดยปกติแล้ว service ต่าง ๆ จะติดต่อสื่อสารผ่าน API

และมักจะเป็น RESTFul API นั่นเอง
ดังนั้นทั้งผู้สร้างและผู้ใช้ API มั่นใจว่า
API มันยังคงทำงานตามที่ตกลงร่วมกัน ทั้งสองฝั่งคือ

  • ผู้สร้าง API หรือ Provider
  • ผู้ใช้งาน API หรือ Consumer

ทั้งสองฝั่งจำเป็นต้องมีขั้นตอนการทำงานร่วมกัน
หรือการติดต่อสื่อสารกันอยู่อย่างเสมอ ตั้งแต่เริ่มสร้าง API เลยว่าเช่น

  • Endpoint ชื่ออะไร
  • Request และ Response มีหน้าตาอย่างไร

ในขั้นตอนนี้ Provider จะทำการสร้าง specification ของ API ขึ้นมา

จากนั้นแต่ละ Consumer จะสร้างข้อตกลงหรือสัญญา (Contract) กับ Provider ขึ้นมาแต่ละ consumer จะมี API เท่าที่ใช้งานเท่านั้น

ดังนั้นถ้าฝั่ง Provider ทำการเปลี่ยนแปลง API ใด ๆ ก็ตาม
ก็จะรู้ทันทีว่า ส่งผลกระทบต่อ Consumer ใดบ้าง
ทำให้มีความมั่นใจก่อน publish API ออกมา
นี่มันคือการทำงานแบบ Proactive สุด ๆ

ไม่ใช่ Reactive คือให้ทาง Consumer แจ้งปัญหากลับมา !!

ส่วนฝั่ง Consumer ก็สามารถทดสอบผ่าน Contract ที่สร้างขึ้นมาได้เลย
ถ้า Contract test มีปัญหาหรือไม่ผ่านแล้ว
นั่นหมายความว่า การเปลี่ยนแปลงจากฝั่งของ Provider ก่อให้เกิดปัญหานั่นเอง

ประโยชน์ที่ได้รับคือ

เมื่อมีการเปลี่ยนแแปลง API ใด ๆ ก็ตาม
ทำให้เรารู้ปัญหาได้อย่างรวดเร็ว
แต่จำเป็นต้องกำหนดขั้นตอนการทำงานร่วมกัน
ว่าถ้ามีการเปลี่ยนแปลง specification ของ API ใด ๆ แล้ว
ต้องทำการทดสอบ Contract ต่าง ๆ ก่อนเสมอ
ในขั้นตอนนี้ ถ้าทำงานเป็นแบบอัตโนมัติจะดีมาก ๆ

ทำไมต้องใช้ Contract testing กันด้วย ?

เนื่องจากปัญหาที่เกิดจาก Integration และ End-to-End testing นั่นเอง
ที่ต้องใช้เวลาในการเตรียมการเยอะมาก
ทำให้กว่าจะรู้ว่ามีปัญหา
ต้องมีขั้นตอนการเตรียมการหรือพิธีกรรมมากมาย
ยิ่งเข้าสู่โลกของ Microservices แล้วนั้น
ยิ่งก่อให้เกิดปัญหามากมายตามมา แบบเท่าทวีคูณ

บางคนอาจจะบอกว่า เราก็ทำ Component testing ด้วยนะ

แต่มันคือการจำลอง API ต่าง ๆ ตามที่เราเข้าใจ
แถมถ้าฝั่ง provider เปลี่ยนแปลง มักจะไม่ update ให้ฝั่ง consumer รู้อีกด้วย !!
ส่งผลให้ผลการทดสอบมักจะไม่น่าเชื่อถือ
มันไม่ใช่ปัญหาของเครื่องมือ
แต่มันคือปัญหาเรื่อง collaboration และ communication ของทีมและองค์กร
ดังนั้นก็ต้องแก้ไขให้ตรงจุด !!

แนวคิดดูดี แต่ลองมาดูตัวอย่างกันนิดหน่อย

Contract testing มีเครื่องมือและ framework หลายตัวเลย
ทั้ง Pact, Pacto และ Spring Cloud Contract  เ
กิดมาเพื่อ Contract testing โดยเฉพาะ
แต่ดูท่าทางจะยากไปสักหน่อย
เลยลองใช้เครื่องมือง่าย ๆ เช่น Postman มาลองสร้างหน่อย
Postman สามารถทำได้แต่ไม่ดีเท่า 3 ตัวที่บอกนะครับ
มาเริ่มกันดีกว่า

ดังนั้นลองมาปรับปรุงขั้นตอนการทำงานตาม Contract testing กัน

มีขั้นตอนดังนี้

ขั้นตอนที่ 1 Provider ทำการสร้างและ publish API ออกมา

มักเป็นการออกแบบและสร้างจาก Provider
ใน Postman นั้นคือการสร้าง Collection + Request ด้วย
ในขั้นตอนนี้จะถูกเรื่องว่า Provider/Producer contract

ขั้นตอนที่ 2 ทั้งสองฝั่งทำการสร้าง contract หรือข้อตกลงรวมกัน 

เป็นการสร้างข้อตกลงร่วมกันระหว่าง Provider และ Consumer
นั่นคือการเขียน test และ assertion นั่นเอง
เพื่อใช้ตรวจสอบว่า Request และ Response มีข้อตกลงร่วมกันอย่างไร เช่น

  • โครงสร้างของข้อมูลที่ส่งกลับ
  • Response code
  • Parameters ต่าง ๆ
  • รูปแบบของข้อมูล

จากนั้นทำการบันทึกไว้ ซึ่งจะเรียกว่า Consumer contract
เป็น contract หรือข้อตกลงร่วมกันว่า
แต่ละ consumer นั้นตกลงการทำงานกับ provider อย่างไร

ใน Postman ก็คือการสร้าง Collection +Request ขึ้นมา
และทำการเขียน test ต่าง ๆ ขึ้นมา
รวมทั้งมี examples อีกด้วย

ขั้นตอนที่ 3 เมื่อทาง Provider ทำการเปลี่ยนแปลงหรือแก้ไขใด ๆ

ต้องทำการทดสอบ Consumer contract ที่มีให้ผ่านทั้งหมด
เพื่อทำให้มั่นใจว่า การเปลี่ยนแปลงการทำงานภายใน
ไม่ส่งผลต่อ consumer ทั้งหมด (Compatibility)
หรือถ้ามีปัญหาเกิดขึ้น จะได้คุยหรือเปลี่ยนข้อตกลงใหม่กับทาง comsumer นั้น ๆ

ขั้นตอนที่ 4 ทางฝั่ง Consumer สามารถใช้ Consumer Contract ไปใช้งานได้เลย

นำเอา contract ที่สร้างขึ้นมา ไปทำการสร้าง Mock หรือทดสอบได้เลย
ถ้าใน Postman ก็คือการสร้าง Mock Collection นั่นเอง

ตัวอย่างของ Colelction ดูได้จากที่นี่ GitHub:Up1

สรุปจากบทความเรื่อง Practical Ways to Write Better JavaScript

$
0
0

จากบทความเรื่อง Practical Ways to Write Better JavaScript
ทำการสรุปแนวทางของการเขียน JavaScript ที่ดี
เห็นว่าน่าสนใจเลยสรุปไว้อ่านนิดหน่อย
สายงาน JavaScript programming น่าจะต้องศึกษาไว้
มาเริ่มกันเลย

ใช้ TypeScript ซะ

สิ่งแรกสำหรับการเขียน JavaScript ให้ดีขึ้นคือ
การไม่เขียน JavaScript ตรง ๆ นั่นเอง
อ่านตรงนี้เจ็บปวดน่าดู
ซึ่งปัญหาหลาย ๆ อย่างของ JavaScript ถูกแก้ไขด้วย TypeScript

ใช้ modern features

เนื่องจากตัวภาษามีความสามารถเปลี่ยนแปลงไปอย่างมาก
ดังนั้นนักพัฒนาควรเรียนรู้และใช้งานกันด้วย
ประกอบไปด้วย

  • Async-await
  • Let และ const
  • Arrow function
  • Spread operator
  • Template literal
  • Object destructing

ใช้ Lint เสมอ

การทำงานร่วมกันเป็นทีม
สิ่งที่สำคัญคือ รูปแบบของ code ในทางเดียวกัน
เพื่อให้เข้าใจและทำงานร่วมกันได้ง่ายขึ้น
ถ้าเรื่องของ formmat code จะใช้งาน Prettier
ส่วน ESLint จะทำงานมากกว่า คือตรวจสอบความถูกต้องของ code ตามมาตรฐานด้วย

เขียนชุดการทดสอบเสมอ

การเขียน test เป็นอีกแนวทาง สำหรับการปรับปรุง JavaScript ที่เราเขียนขึ้นมา
โดยใน ecosystem ของ JavaScript นั้น
มีเครื่องมือในการทดสอบมากมายให้เลือก
เสียอย่างเดียวคือ ไม่ใช้และไม่เขียนกัน

สุดท้าย อย่าหยุดที่จะเรียนรู้และพัฒนาอยู่อย่างเสมอ

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

Part 1​ :: ความรู้พื้นฐานเกี่ยวกับ Reactive Programming

$
0
0

จากทางกลุ่ม RxJS Thailand ทำการ share บทความ
เกี่ยวกับ The introduction to Reactive Programming you've been missing
อ่านแล้วน่าสนใจดี สำหรับคนเริ่มต้นใหม่ ๆ แบบผม
เลยทำการสรุปไว้นิดหน่อย

Reactive Programming คืออะไร ?

ในบทความอธิบายไว้ว่า ความหมายของ Reactive Programming ในแต่ละที่
มักจะอธิบายไม่ค่อยเข้าใจเท่าไร
ทั้งที่ Wikipedia จะออกแนวทฤษฎีมากไป
ทั้งที่ Stackoverflow นี่ยิ่งไม่เหมาะกับผู้เริ่มต้นใหม่
ทั้งที่ Reactive Manifesto นี่พูดภาษา business และ management มาก ๆ
ทั้งที่ทาง Microsoft นี่ก็ผูกติดกับเครื่องมือและ framework ของตนเองเกินไป

ดังนั้นในบทความจึงทำการอธิบายไว้ว่า
Reactive programming is programming with asynchronous data streams.

นั่นคือการ programming กับ stream ของข้อมูลที่เป็นแบบ asynchronous
ดังนั้นเราสามารถ observe
หรือคอยเฝ้าสังเกตหรือจับตามองข้อมูลหรือ event เหล่านั้น
จากนั้นจึงทำงานตามข้อมูลเหล่านั้น (side effect)
การทำงานนั้น ๆ ก็ก่อให้เกิดเหตุการณ์อื่น ๆ ขึ้นมา
วนไปเรื่อย ๆ

เป็นแนวคิดเดิม ๆ ไม่มีอะไรใหม่เลย
เนื่องจากทุกครั้งที่เกิดเหตุการณ์ใด ๆ (Event)
มักจะก่อให้เกิดการเปลี่ยนแปลงเสมอ ไม่มากก็น้อย (Site effect)

โดยที่ใน data stream เป็นข้อมูลอะไรก็ได้

ยกตัวอย่างเช่น

  • User input
  • Variable
  • Property
  • Cache
  • Data structure ต่าง ๆ

Stream นั้นมี function ทำการงานพื้นฐานเช่น 

  • การสร้าง stream
  • การกรองหรือ filter ข้อมูลใน stream
  • การรวมหรือ combine ข้อมูลใน stream

Stream ก็เหมือนท่อน้ำที่เราสามารถตัดต่อ รวม หรือกรองได้เลย
เพื่อให้ทำงานตามที่เราต้องการ

โดยที่ Stream คือส่วนการทำงานหลักของ Reactive เลย

แสดงดังรูป

จากรูปนั้น เป็นข้อมูลของเหตุการณ์ต่าง ๆ ที่เกิดขึ้น
ถูกเรียงตามเวลาที่เกิดขึ้นของแต่ละเหตุการณ์ 
โดยเหตุการณ์จะมีอยู่ 3 กลุ่มคือ

  1. Value หรือ Type เรียกง่าย ๆ คือ เหตุการณ์อะไรนั่นเอง เช่น Clicked, Created user เป็นต้น
  2. Error คือเมื่อเกิด error หรือข้อผิดพลาดจากเหตุการณ์ต่าง ๆ
  3. Completed คือเมื่อทำงานสำเสร็จจากเหตุการณ์ต่าง ๆ

เหตุการณ์สามารถเกิดขึ้นได้ตลอดเวลา

ส่วน Error หรือ Completed ของแต่ละเหตุการณ์
จะเกิดตอนไหนก็ได้หลังจากเหตุการณ์นั้น ๆ เกิดขึ้น
นั่นคือ เราไม่สามารถเดาได้เลยว่าจะเกิดขึ้นตอนไหน (ทำงานแบบ Asynchronous)

ดังนั้นเราจะเฝ้ามองหรือดักฟังเหตุการณ์ต่าง ๆ เหล่านี้ได้อย่างไร ?
ส่วนใหญ่เรามักจะได้ยินว่า
เราจะดักฟังเหตุการณ์ที่เกิดขึ้นใน stream ได้จะต้องทำการ subscribe ก่อนเสมอ
มันคือการทำงานตาม Observer Design Pattern

ในบทความนั้นทำการยกตัวอย่างที่น่าสนใจคือ

เพื่อทำให้เข้าใจ function การทำงานพื้นฐานของ Reactive library
เช่น map, filter และ scan เป็นต้น
ทำการเก็บข้อมูลของการ click ใน data stream
จากนั้นจะทำการตรวจหา multiple-click กัน โดยแนวทางการคิดเป็นดังนี้

  • ทำการตรวจสอบในแต่ละเหตุการณ์ว่าเกิดขึ้นใกล้เคียงในช่วงเวลาที่กำหนดหรือไม่ เพื่อรวมกลุ่มกัน
  • ทำการนับจำนวนในแต่ละกลุ่ม
  • ทำการกรองเฉพาะกลุ่มที่มีจำนวนมากกว่า 1 ขึ้นไปเท่านั้น

แสดงการใช้งาน function จาก Reactive Library ดังรูป
จะเห็นได้ว่าเป็นแนวคิดที่เรียบง่ายมาก ๆ

ใน Part ต่อไปเรามาคิดเชิง Reactive Programming
และตัวอย่าง code กัน
ขอให้สนุกกับการ coding ครับ

ว่าด้วยเรื่อง Domain Event และ Event Sourcing

$
0
0

จากการพูดคุยเรื่องของ Event-based architecture นั้น มักจะเจอ 2 คำคือ

  1. Domain Event
  2. Event Sourcing

คำถามที่น่าสนใจคือมันคืออะไร ?
ทำหน้าที่อะไรกันแน่
ก็เลยทำการอธิบายแบบสั้น ๆ ไว้หน่อย

Domain Event คืออะไร ?

ใช้อธิบายเหตุการณ์ที่เกิดขึ้นภายใน domain หรือกลุ่มงานในขอบเขตนั้น ๆ
เป็นภาษาที่ใช้คุยกันใน domain นั้น ๆ
ทั้ง Domain expert, Business, Development
ต้องตกลงและเข้าใจร่วมกัน
จึงเป็นหัวใจหลักของการทำงานร่วมกัน

ชื่อของ Domain Event นั้น ต้องไม่ผู้กับเทคโนโลยีใด ๆ
ยกตัวอย่างเช่น

  • ผู้ใช้งานทำงานลงทะเบียนแล้ว
  • ผู้ซื้อได้รับสินค้าเรียบร้อยแล้ว
  • การชำระเงินไม่สำเร็จ เพราะว่าหมดระยะเวลาการชำระเงิน

Domain Event นั้นสามารถเกิดได้ทั้ง
ภายในขอบเขตงานของตัวเอง หรือข้ามขอบเขตงานอื่น ๆ ได้เช่นกัน
เพื่อใช้ในการทำงานร่วมกันเท่านั้น
ยกตัวอย่างเช่น การทำงานในรูปแบบ CQRS เป็นต้น

แต่หน้าที่หลักของ Domain Event คือ
ใช้สำหรับการติดต่อสื่อสารและทำงานร่วมกันข้ามขอบเขตการทำงานต่าง ๆ ยกตัวอย่างเช่นมี 3 ส่วนงานคือ

  • Order
  • Invoice
  • Delivery

เมื่อในส่วนงาน Order มีการสร้าง Order หรือคำสั่งซื้อสำเร็จแล้ว
ทางส่วนงาน Invoice และ Delivery ก็จะต้องรู้หรือทำงานตามด้วย
ดังนั้นเหตุการณ์คำสั่งซื้อสำเร็จ จึงเป็นหนึ่งใน Domain Event นั่นเอง

จากแนวคิดนี้ทำให้แต่ละส่วนงานเป็นอิสระแก่กัน
ทำข้อตกลงหรือ contract กันผ่าน Domain Event

แต่ปัญหาที่ตามมาคือ เราจะทำการจัดเก็บ event นี้อย่างไร ?
ข้อมูลใน Event จะเป็นอย่างไร ?
ตำตอบที่ได้มาคือ Event Sourcing

Event Sourcing คืออะไร ?

Event Sourcing ensures that all changes to application state are stored as a sequence of events.

ทำการเก็บข้อมูลของทุก ๆ การเปลี่ยนแปลงไว้
ในรูปแบบของ Event stream นั่นเอง
โดยข้อมูลจะเรียงลำดับตามเวลาที่ Event เกิดขึ้น
และแต่ละ Event จะไม่สามารถแก้ไขได้ (Immutability)

ดังนั้น Event ที่จัดเก็บใน Event sourcing นั้น
เหมือนกับ local storage ของแต่ละขอบเขตงานนั้น ๆ 
ดังนั้นมักจะไม่ expose หรือใช้แบบ global หรือใช้งานข้ามขอบเขตงาน
มิเช่นนั้นจะทำการแต่ละส่วนงานผูกมัดกันเกินไป (Tight coupling)

แต่ถ้าต้องทำการ expose Event (Domain Event) 

เพื่อให้ขอบเขตงานอื่น ๆ ใช้งานด้วย
อาจะ expose ออกไปในรูปแบบต่าง ๆ ดังนี้

  • Public API
  • Customer/Supplier
  • Open Host with Publish/Subscribe

แสดงตัวอย่างของ Open Host with Publish/Subscribe ดังรูป

Reference Websites

Viewing all 1997 articles
Browse latest View live