คำสั่ง "use workflow" ของ Vercel กระตุ้นการต่อต้านจากนักพัฒนา เรื่องการใช้ Magic Strings และความกังวลเรื่องการถูกผูกมัดกับผู้ให้บริการ

ทีมชุมชน BigGo
คำสั่ง "use workflow" ของ Vercel กระตุ้นการต่อต้านจากนักพัฒนา เรื่องการใช้ Magic Strings และความกังวลเรื่องการถูกผูกมัดกับผู้ให้บริการ

การเปิดตัว Workflow Devkit ล่าสุดของ Vercel ซึ่งเป็นชุดเครื่องมือใหม่ที่ออกแบบมาเพื่อเพิ่มความทนทานและความน่าเชื่อถือให้กับฟังก์ชัน TypeScript ได้จุดประเด็นการถกเถียงอย่างหนักทั่วทั้งชุมชนนักพัฒนา หัวใจของข้อโต้แย้งนี้คือคำสั่ง use workflow ซึ่งเป็น magic string ที่เปลี่ยนฟังก์ชันธรรมดาให้กลายเป็นเวิร์กโฟลว์ที่ทนทาน พร้อมระบบลองทำใหม่อัตโนมัติและการคงสถานะไว้ แม้จะสัญญาว่าจะทำให้การดำเนินการแบบอะซิงโครนัสที่ซับซ้อนง่ายขึ้น แต่วิธีการนี้ก็ถูกวิพากษ์วิจารณ์เนื่องจากการพึ่งพาการเขียนโค้ดใหม่และความเสี่ยงที่จะถูกผูกมัดกับผู้ให้บริการเฉพาะ

ความขัดแย้งเรื่อง Magic String

ไวยากรณ์ use workflow เป็นการก้าวล่าสุดของ Vercel สู่การเขียนโปรแกรมแบบใช้คำสั่ง (directive-based) ต่อเนื่องจากรูปแบบที่คล้ายกัน เช่น use server และ use client ใน Next.js วิธีการนี้ใช้การประกาศสตริงง่ายๆ ที่ส่วนบนของฟังก์ชันเพื่อเปิดใช้งานคุณสมบัติอันทรงพลัง เช่น การลองทำใหม่อัตโนมัติ การคงสถานะ และการสังเกตการณ์ (observability) อย่างไรก็ตาม นักพัฒนามืออาชีพจำนวนมากกำลังต่อต้านสิ่งที่พวกเขาเห็นว่าคือการพึ่งพา magic string มากเกินไป ซึ่งบดบังวิธีการทำงานที่แท้จริงของโค้ด

จากตัวเลือกไวยากรณ์ทั้งหมดที่พวกเขาเลือกได้ พวกเขาตัดสินใจเลือกสิ่งที่ฉันบอกได้ว่าแย่ที่สุด ถ้าคุณต้องการโค้ดบรรทัดเดียว ดีคอเรเตอร์ (decorators) ถูกใช้อย่างแพร่หลายในภาษาต่างๆ และ TypeScript ก็รองรับมันเช่นกัน

ชุมชนได้เสนอทางเลือกอื่นๆ หลายแบบ รวมถึงดีคอเรเตอร์ (decorators), ฟังก์ชันระดับสูง (higher-order functions) และฟังก์ชันเจเนอเรเตอร์ (generator functions) บางคนแย้งว่าดีคอเรเตอร์น่าจะให้วิธีการที่เป็นมาตรฐานมากกว่า ในขณะที่บางคนแนะนำให้ใช้ตัวห่อหุ้ม (wrappers) ที่ระบุชัดเจนสำหรับการลองเรียกใช้ฟังก์ชันแต่ละครั้งอีกที ความกังวลพื้นฐานคือ magic string ทำให้พฤติกรรมของโค้ดคาดเดาได้น้อยลงและดีบักได้ยากขึ้น โดยเฉพาะสำหรับนักพัฒนาที่จำเป็นต้องเข้าใจอย่างแท้จริงว่าโค้ดของพวกเขาทำงานอย่างไร

ทางเลือกไวยากรณ์ที่เสนอโดยชุมชน:

  • Decorators (@workflow) - มีมาตรฐานมากขึ้นในหลายภาษา
  • Higher-order functions - workflow(myFunction)
  • Generator functions - แนวทางดั้งเดิมของ JavaScript
  • Explicit retry wrappers - retry(() => myFunction())

การนำไปใช้ทางเทคนิคและความกังวลเกี่ยวกับระบบนิเวศ

เบื้องหลังแล้ว use workflow อาศัยปลั๊กอินคอมไพเลอร์ SWC ที่เขียนโค้ดใหม่ระหว่างกระบวนการ build การเปลี่ยนแปลงนี้ทำให้สามารถใช้คุณสมบัติต่างๆ เช่น การดำเนินการที่ทนทาน (durable execution) และการลองทำใหม่อัตโนมัติ โดยที่นักพัฒนาไม่จำเป็นต้องเขียนโค้ดจัดการสถานะที่ซับซ้อนด้วยตนเอง ระบบจะบันทึกสถานะของฟังก์ชันโดยอัตโนมัติ ทำให้เวิร์กโฟลว์สามารถรอดพ้นจากการรีสตาร์ทเซิร์ฟเวอร์และดำเนินการต่อจากจุดที่ค้างไว้ได้

อย่างไรก็ตาม วิธีการนี้ได้ก่อให้เกิดความกังวลเกี่ยวกับการถูกผูกมัดกับเฟรมเวิร์ก (framework lock-in) และความเข้ากันได้ของระบบนิเวศ ความคิดเห็นต่างๆ ชี้ให้เห็นว่าการนำไปใช้ในปัจจุบันดูเหมือนจะผูกติดกับ Next.js และโครงสร้างพื้นฐานของ Vercel อย่างแน่นหนา โดยมีสนับสนุนเฟรมเวิร์กอื่นๆ น้อย นักพัฒนาหลายคนแสดงความกังวลเกี่ยวกับการถูกขังอยู่ในระบบนิเวศของ Vercel โดยชี้ให้เห็นว่าโมเดลธุรกิจเดียวกันที่ทำให้การดีพลอยง่ายนั้น ก็สร้างการผูกมัดกับผู้ให้บริการที่แข็งแกร่งเช่นกัน แม้ธรรมชาติแบบโอเพนซอร์สของโปรเจกต์จะให้ความมั่นใจบ้าง แต่คำถามยังคงอยู่เกี่ยวกับว่าการจะให้เวิร์กโฟลว์เหล่านี้ทำงานนอกแพลตฟอร์มของ Vercel จะทำได้ง่ายเพียงใด

การรองรับเฟรมเวิร์กในปัจจุบัน:

  • ใช้งานได้: Next.js, NestJS
  • เร็วๆ นี้: Svelte, Remix, Astro, Qwik
  • ต้องการ: ปลั๊กอินคอมไพเลอร์ SWC สำหรับการแปลงโค้ด

การเปรียบเทียบกับโซลูชันที่มีอยู่

Workflow Devkit ของ Vercel เข้ามาในพื้นที่ที่ถูกครอบครองโดยโซลูชันที่ยืนหยัดมาแล้วหลายตัว ผู้แสดงความคิดเห็นได้เปรียบเทียบกับ Temporal.io, Cloudflare Workflows และ Azure's Durable Task Framework ทันที ระบบเหล่านี้แก้ปัญหาเดียวกันเกี่ยวกับการดำเนินการที่ทนทานและการจัดการเวิร์กโฟลว์ แต่ใช้วิธีการทางเทคนิคที่แตกต่างกัน

ตัวอย่างเช่น Cloudflare Workflows ใช้การเรียกฟังก์ชันที่ชัดเจน เช่น step.do และ step.sleep แทนที่จะเป็นการเขียนโค้ดใหม่ นักพัฒนาบางส่วนชอบวิธีการที่ชัดเจนแบบนี้มากกว่าเพราะมันทำให้บทบาทของเอ็นจินเวิร์กโฟลว์ปรากฏชัดในโค้ด Temporal.io นำเสนอโซลูชันที่成熟 (mature) พร้อมการสนับสนุนโครงสร้างพื้นฐานที่แข็งแกร่ง แม้ว่าผู้แสดงความคิดเห็นจะระบุว่ามันอาจซับซ้อนในการตั้งค่าและจัดการ การเกิดขึ้นของโซลูชันหลายตัวในพื้นที่นี้ชี้ให้เห็นถึงการยอมรับที่เพิ่มขึ้นว่าวิธีการดั้งเดิมในการจัดการกระบวนการที่ทำงานยาวนาน (long-running processes) จำเป็นต้องมีการปรับปรุง

โซลูชันเวิร์กโฟลว์ทางเลือกที่ชุมชนกล่าวถึง:

  • Temporal.io: แพลตฟอร์มออร์เคสเตรชันเวิร์กโฟลว์ที่มีความเป็นผู้ใหญ่
  • Cloudflare Workflows: ใช้ฟังก์ชันสเต็ปที่ชัดเจนแทนการเขียนโค้ดใหม่
  • Azure Durable Task Framework: โซลูชันของ Microsoft สำหรับฟังก์ชันที่ทนทาน
  • DBOS: แนวทางระบบปฏิบัติการที่มุ่งเน้นฐานข้อมูลสำหรับเวิร์กโฟลว์

การประยุกต์ใช้จริงและประสบการณ์ของนักพัฒนา

แม้จะมีข้อโต้แย้ง Workflow Devkit ก็ได้แก้ไขจุดเจ็บปวดที่แท้จริงในการพัฒนาแอปพลิเคชันสมัยใหม่ ตัวอย่างที่แสดงในประกาศแสดงกรณีการใช้งานจริง เช่น ลำดับอีเมลหลายวัน, เวิร์กโฟลว์ของเอไอเอเจนต์ (AI agent workflows) และกระบวนการทางธุรกิจที่ซับซ้อนซึ่งต้องการความทนทานข้ามการรีสตาร์ทและความล้มเหลวของเซิร์ฟเวอร์ สำหรับนักพัฒนาที่สร้างแอปพลิเคชันที่มีการดำเนินการที่ทำงานยาวนาน กลไกการคงสถานะอัตโนมัติและการลองทำใหม่อาจลดโค้ดแบบโบลเลอร์เพลต (boilerplate code) ลงได้อย่างมีนัยสำคัญ

ประสบการณ์การพัฒนาดูเหมือนจะเป็นดาบสองคม แม้แนวทาง zero config และคุณสมบัติการสังเกตการณ์อัตโนมัติจะดึงดูดนักพัฒนาที่ต้องการโฟกัสที่ลอจิกทางธุรกิจ แต่แนวทาง magic string ก็ทำให้ผู้ที่ให้คุณค่ากับความโปร่งใสและความสามารถในการดีบักเป็นกังวล ดังที่ผู้แสดงความคิดเห็นหนึ่งระบุ ความสามารถในการ command คลิกและดูว่าทำไมสิ่งต่างๆ ถึงไม่ทำงานจะถูกทำลายเมื่อฟังก์ชันการทำงานหลักขึ้นอยู่กับการเปลี่ยนแปลงโค้ดในตอน build

อนาคตของการเขียนโปรแกรมแบบใช้คำสั่ง (Directive-Based Programming)

การอภิปรายรอบๆ use workflow สะท้อนให้เห็นถึงความตึงเครียดที่กว้างขึ้นในระบบนิเวศ JavaScript/TypeScript เกี่ยวกับวิธีการสร้างสมดุลระหว่างความสะดวกของนักพัฒนาและความโปร่งใสของโค้ด Vercel ดูเหมือนจะเดิมพันอย่างหนักกับการเขียนโปรแกรมแบบใช้คำสั่งในฐานะอนาคตของการพัฒนาเว็บ โดยต่อยอดจากประสบการณ์กับคำสั่งใน Next.js แนวทางนี้ให้ความสำคัญกับประสบการณ์ของนักพัฒนาและการสร้างต้นแบบอย่างรวดเร็ว มากกว่าการควบคุมและความเข้าใจที่ชัดเจน

ขณะที่เครื่องมือนี้เติบโตเต็มที่มากขึ้น หลายอย่างจะขึ้นอยู่กับว่า Vercel จัดการกับความกังวลของชุมชนเกี่ยวกับความโปร่งใส ความสามารถในการดีบัก และการพกพา (portability) อย่างไร การมีอิมพลีเมนเทชันอ้างอิงของ Postgres ชี้ให้เห็นว่าบริษัทตระหนักถึงความสำคัญของการหลีกเลี่ยงการถูกผูกมัดกับผู้ให้บริการโดยสมบูรณ์ อย่างไรก็ตาม ปฏิกิริยาที่แข็งกร้าวจากนักพัฒนาที่มีประสบการณ์บ่งชี้ว่าแนวทางในปัจจุบันอาจต้องมีการปรับปรุงเพื่อให้ได้รับการยอมรับในวงกว้างขึ้น นอกเหนือจากกลุ่มเป้าหมายหลักของ Vercel

การตอบสนองของชุมชนนักพัฒนาต่อ Workflow Devkit เน้นย้ำถึงการอภิปรายที่กำลังดำเนินอยู่เกี่ยวกับการลดทอน (abstraction) เทียบกับความโปร่งใสในการพัฒนาเว็บสมัยใหม่ แม้เครื่องมือจะนำเสนอโซลูชันที่น่าสนใจสำหรับปัญหาจริงเกี่ยวกับการดำเนินการที่ทนทาน แต่ทางเลือกในการอิมพลีเมนต์ของมันก็ได้จุดประกายการสนทนาที่สำคัญเกี่ยวกับทิศทางของเครื่องมือ JavaScript และความสมดุลระหว่างความมหัศจรรย์ (magic) และความชัดเจน (explicitness) ในการออกแบบเฟรมเวิร์ก

อ้างอิง: Make any TypeScript Function Durable