Data contract เป็นส่วนนึงของ data integration โดยตัวมันเองทำหน้าที่เป็นเหมือน  “contract” หรือสัญญา ว่าเราจะรับส่งข้อมูลกันระหว่างต้นทางและปลายทางยังไงบ้าง เพื่อสร้าง pipeline ได้อย่างถูกต้อง และโปร่งใสฮะ

ทีนี้ ตัว data contract เองจะต้องอธิบายได้ว่ามีอะไรบ้าง ตามนี้

  • Responsible persons (ใคร)
  • Data subjects (ส่งอะไร)
  • Methods and channels (ส่งทางไหน)
  • Frequency (ส่งตอนไหน)
  • Data schemas (ส่งด้วยรูปแบบอะไร)

เลยกลายมาเป็น blog เล่าเรื่อง basic data contract extraction ตอนนี้ฮะ


Data contract as an API

วาด flow คร่าวๆ เวลาเรา integrate data contracts เข้าไปใน ETL ของเรา แบบนี้ฮะ

สีส้มๆ ตรง "validation" นี่แหละ คือ หัวใจสำคัญของ data contract เลยฮะ เพราะ "สัญญา" ไว้แล้วว่าจะส่งอะไร แบบไหน เราเลยต้องมี validation เข้ามาตรวจสอบว่าอะไรที่ตรงตามสัญญาบ้าง อันไหนไม่ถูกต้องก็จะเก็บไว้อีกที่นึงเพื่อตรวจสอบหรืออะไรก็ว่าไป


ก่อนจะไปหัวข้อถัดไป

blog นี้ จะเล่าถึง real-time integration เป็น API ด้วย NodeJS และใช้ AJV เพื่อทำ validation

สำหรับ Python สามารถอ่านได้ตามลิงก์นี้ฮะ

สัญญา(ไม่)ปากเปล่า - data contracts in action (Python)
blog ที่แล้ว เราคุยกันถึง data contract กับ NodeJS รอบนี้ เรามาใช้ Python กันบ้างฮะ

API swagger

API swagger เป็นหัวข้อพื้นฐานของการทำ API ฮะ มันเป็นเหมือนห้องสมุด เพื่อแสดงว่า API ของเรามีหน้าตายังไง รับอะไร ส่งอะไร โดยใช้ configuration file ที่เราสามารถเขียนด้วย YAML หรือ JSON ก็ได้ ตรงนี้ เราจะใช้ YAML กันฮะ

และก็เขียนด้วย VSCode

1. VSCode plugin: OpenAPI Editor

ผมเลือกใช้ plugin ใน VSCode ตัวนี้ ช่วยเขียน API definition และสามารถ review swagger ได้ง่ายมากๆ ฮะ

OpenAPI (Swagger) Editor - Visual Studio Marketplace
Extension for Visual Studio Code - OpenAPI extension for Visual Studio Code

2. เขียน YAML file

เมื่อเราติดตั้งและเปิดใช้ plugin ใน VSCode แล้ว ให้เราเปิด palette แล้วเลือก “create”

กดปุ๊บ มันจะสร้าง OpenAPI YAML file หน้าตาแบบนี้มาให้

มันมีปุ่ม preview ก็จิ้มจึ้กไปทีนึง มันจะแสดงหน้า swagger มาแบบนี้

3. สร้าง path ใหม่

เอาล่ะ ลองสร้าง path ใหม่ ให้ชื่อว่า people

จากนั้นก็ save ด้วยชื่อ people.yml.

จริงๆ มันมีรายละเอียดการเขียน OpenAPI configuration file อยู่ เดี๋ยวค่อยเล่าวันหลังนะฮะ


เขียน app พร้อม validation

เรามี API configuration ที่ชื่อ people.yml แล้ว ซึ่งนั่นแหละ คือ contract ของเรา ทีนี้ เราต้องการจะรับข้อมูล people เข้ามา และให้มี "validation" ด้วย เราจะเริ่มจากสร้าง API ให้คนอื่นสามารถ POST ข้อมูลอะไรสักอย่างเข้ามาได้ แล้วค่อย "validate" ตอน extract ฮะ

Validation หมายถึง การที่เราตรวจสอบว่าข้อมูล (request payload) ที่รับเข้ามาเนี่ย มันถูกต้องหรือเปล่า เช่น field นี้ต้องเป็น string ส่วน field นั้นต้องเป็น integer อะไรแบบนี้

เราจะใช้ตัวช่วย คือ AJV เพื่อทำ validation ให้เราฮะ

Ajv JSON schema validator
The fastest JSON schema Validator. Supports JSON Schema draft-04/06/07/2019-09/2020-12 and JSON Type Definition (RFC8927)

1. สร้าง javascript app

ตั้งต้น index.js ด้วย

และใช้ package.json แบบนี้

เมื่อ npm install แล้ว เราจะมี app ที่ listen port 4001 พร้อมมี endpoint /people

2. อ่าน contract

เราจะใช้ js-yaml library อ่าน people.yml

3. Setup AJV

เราได้ข้อมูล contract people.yml ก็เพิ่มเข้าใน AJV

  • strict: false เพื่อ disable restrictions ไม่ให้ throw error ถ้ามี keyword หรือ undefined format
  • addFormat() เพื่อ include formats ที่กำหนดด้วย JSON Schema specification.
  • AJV.addSchema(contract, key) เพื่อเพิ่ม contract ที่เราต้องการพร้อมกำหนด key

4. Validate

เราจะมี request payload ใน path /people เราก็ทำ validation ข้างใน path นั้น

  • AJV.compile() เพื่อ setup function สำหรับการทำ validation ของแต่ละ contract
  • $ref: ... เอาไว้เระบุว่า เนื้อหาของ contract ที่จะ validate นั้นมันอยู่ตรงไหน ของตัวอย่างนี้ คือ เรากำลัง validate ของ contract key people ตามด้วย # หมายถึง  internal reference และ definition ของ contract ซึ่งอยู่ที่ path /components/schemas/people
  • validator() อันนี้เป็น function ที่เราสร้างขึ้นเองจาก AJV.compile() และจะใช้อันนี้แหละเพื่อ validate
  • ถ้า validator() return "true" แปลว่า payload ถูกต้องตามที่ระบุใน contract
  • แต่ถ้า validator() return "false" แปลว่า payload มีอะไรสักอย่างผิดไปละ ตรงนี้ เราสามารถดูได้ว่าผิดตรงไหน จาก property .errors

5. Complete API

เอาทุกอย่างมารวมเข้าด้วยกัน

6. Test

จะใช้ curl แบบนี้

หรือ http tool ที่ถนัดก็ได้ฮะ

กรณี payload ถูกต้อง

กรณี payload มีบาง field ระบุ type ไม่ถูกต้อง

กรณี payload ไม่มี required field


ถ้ามีหลาย contract ?

จะ validate contract หลายๆ ตัวยังไงดี?

สมมติว่า เรามี endpoint 2 อัน คือ people กับ pets และก็จะมี contract file 2 file เหมือนกัน เราจะต้อง optimize validation กันหน่อยฮะ

people contract เรามีอยู่แล้ว ส่วนอันนี้คือ pets contract

สามารถเขียนได้แนวๆ นี้นะฮะ

  • List contract files แล้วทำ  AJV.addSchema() ทีละ file โดยกำหนด contract key ตามชื่อของ file
  • เขียน generic function ให้รับ contract key ( contract_key ) และ request payload ( body ) และสุดท้าย response object ( res )
  • ข้างใน generic function เขียนเหมือนเดิม คือ มี compile, validate, check แต่ปรับตัวแปรนิดหน่อยให้เป็น generic
  • ทีนี้ ในแต่ละ endpoint /people กับ /pets ให้ไปเรียก generic function โดยส่งค่า people กับ pets ไปเป็น contract key ตามลำดับ

complete code จะประมาณนี้ฮะ

ลอง test case ของ pets ให้มันเกิด error ซิ


Code repo

GitHub - bluebirz/sample-data-contracts-js: Sample data contracts for data integration
Sample data contracts for data integration. Contribute to bluebirz/sample-data-contracts-js development by creating an account on GitHub.

References