มาใช้ xState เป็น plugin ให้ Mongoose กันเถอะ

Kornkrit Supayanant
3 min readJul 15, 2022

ต้องขอเกริ่นก่อนว่าเมื่อไม่นานมานี้ได้รับ requirements ให้ implement state machine สำหรับ control status บน mongoose โดยในเวอร์ชั่นเก่านั้น ใช้ javascript-state-machine ต่อเข้ากับ plug-in ของ mongoose โดยตรง ซึ่งโจทย์ใหม่ของเราก็คือ เราอยากได้ state-machine ที่ต่อเข้ากับ nestjs (Typescript) ซึ่งหลังจากที่เราได้ใช้เวลาหลาย ชั่วโมงหมดไปกับการพยายามต่อของเก่านั้น บังเอิญผมไปเห็น lib อยู่หนึ่งตัวที่น่าสนใจ หรือก็คือ พระเอกของเราในบทความนี้คือ Tadaaaaa xState ซึ่งเพื่อนๆสามารถไปศึกษาเพิ่มเติ่มได้เลย

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

  1. npm
  2. vscode
  3. MongoDB compass
  4. docker โดยใช้ image mongodb ได้เลยคัรบ

หลังจากเตรียมของข้างบนเสร็จแล้วเรามาเริ่มกันเลย

เริ่มด้วย “nest new xstate-mongoose”

หลังจากสร้าง Project เสร็จแล้วเราก็เริ่ม install xstate กันต่อเลย “npm install xstate — save”

install xstate

หลังจากที่เราลง xstate เสร็จแล้วเราก็มาต่อกันที่ลง nest/mongoose กันต่อเลย

install mongoose

ต่อไปเราก็มาลงมือต่อ Mongoose และสร้าง Document กันเลยโดยในตัวอย่างนี้ผมจะสมมติสถานการณ์ต่างๆ เพื่อจะ update ค่า filed ที่ชื่อว่า status ครับ

create mongo db connection
create mongoose document

ต่อมาเราก็มา Implement state machine plugin กันต่อเลย โดยเริ่มต้นที่ state configurationโดยเพื่อนๆสามารถเข้าไปอ่าน definition ได้ที่ xstate แต่จากตัวอย่างที่เราทำจะมี state ตามกล่องสีส้มเลยคือมี created, validating, validated, publish แล้วก็จะมี action ของแต่ละ state ซึ่งในที่นี่มี NEXT กับ BRIBE โดยที่ event BRIBE จะเรียกใช้งานได้ก็ต่อเมื่อเราอยู่ใน state ของ validating ซึ่งเราใช้ invoke เพิ่มเติมเพื่อนเรียก service ในการเช็คค่าข้อมูลว่าจะ validate แบบปกติ หรือจะติดสินบนเพื่อความ state ไป publish (แค่ตัวอย่างนะเพื่อนๆ อย่าไปติดสินบนนนนนกันละ)

state flow

จาก flow ข้างบนเราสามารถ implement code ตามด้านล่างเลยซึ่ง invoke จะถูก hook ก่อนที่จะเข้า on next event

และเนื่องจากเรา implement TypeScript เราจึง defined type เพื่อให้ตรงวัตถุประสงค์ของมัน ซึ่งในส่วนนี้จะไปสอดคล้องกับ state ที่เรา defined เพราะฉะนั้นเพื่อนๆสามารถ customize ให้ตรงกับความตรงการของเพื่อนๆได้เลย

implement type for state config

หลังจากที่เรา defined state ของเราเรียบร้อยแล้วคราวนี้เราก็มีดูส่วนของ plug in กันซึ่งเพื่อนๆสามารถหา definition การ hook ได้ที่ mongoose document ส่วนของเราใช้จังหวะ pre validate schema เพื่อจะดูว่า status ควรเป็นค่าไหนแล้วเราค่อย call next function เพื่อให้ mongoose ของเรา save ข้อมูลลง document

state machine plugin

ในส่วนนี้เพื่อนๆต้อง defined logic ของตัวเองว่าต้องการทำอะไรหรือ requirement คืออะไร

หลังจากที่เรา defined state และ plugin เรียบร้อย คราวนี้เราก็มาเชื่อมตัวสองตัวนี้เข้ากับ mongoose กันซึ่งใน step นี้เราจะแก้ไขไฟล์ app.module.ts เล็กน้อยตามตัวอย่างเลย

Add plugin to mongoose

เป็นอันเสร็จพิธีเรียบร้อย ตอนนี้ xstate ของเราเชื่อมต่อกับ mongoose แล้วเพราะฉะนั้น เวลาเพื่อนๆ call TopicDocument เพื่อ save ข้อมูล filed status ของเราจะถูก control ด้วย flow ของ state machine เอง

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

--

--