3 คะแนน โดย GN⁺ 2024-11-04 | 2 ความคิดเห็น | แชร์ทาง WhatsApp
  • หลังพิจารณาหลายสแตกสำหรับแอปพลิเคชันจัดทำแบบฟอร์มสำแดงศุลกากร สุดท้าย Ruby on Rails ที่คุ้นเคยกลับช่วยสร้างฟีเจอร์เริ่มต้นได้เร็วกว่าแนวทางใหม่อย่างรู้สึกได้ จึงถูกนำมาใช้สำหรับการพัฒนาเวอร์ชันแรก
  • “version 2” ที่สร้างด้วยแบ็กเอนด์ Rust และฟรอนต์เอนด์ SvelteKit นั้นทั้งเร็วและดูดี แต่มีฟีเจอร์ที่จำเป็นเพียงราว 10% และมี งานเดินท่อระบบ มากกว่าโค้ดธุรกิจ
  • การย้ายแบบค่อยเป็นค่อยไปทำให้ต้องประกอบทุกอย่างเอง ตั้งแต่ routing, การเข้าถึงข้อมูล, สิทธิ์, การติดตามการเปลี่ยนแปลง, การค้นหา, งานเบื้องหลัง, pub/sub, อีเมล, OAuth 2.0, SMTP/POP, object storage ไปจนถึงการสร้าง PDF ซึ่งแทบไม่เพิ่มคุณค่าให้ผู้ใช้
  • จึงตัดสินใจย้อนเฉพาะส่วนที่ย้ายไปสแตกใหม่กลับมาเป็น Rails โดยมีปัจจัยจากการต้องดูแลแอป Rails คนเดียว ความเครียดจากการตอบโจทย์ผู้ใช้ไม่ได้ และความซับซ้อนที่ต้องแก้หลายจุดพร้อมกัน
  • หลังกลับมาใช้ Rails อีกครั้ง ความเร็วในการพัฒนาฟีเจอร์ ปรับปรุงของเดิม อัปเดต UI และแก้บั๊กก็กลับมา โดยเลือกจัดการข้อเสียของ Ruby/Rails ด้วยการทดสอบ การรีแฟกเตอร์ Turbo และ caching เพื่อ โฟกัสกับการพัฒนาผลิตภัณฑ์

จุดเริ่มต้นที่เลือก Rails เป็นทางเลือกชั่วคราว

  • ในปี 2022 ตอนเริ่มสร้างแอปพลิเคชันจัดทำแบบฟอร์มสำแดงศุลกากร ได้พิจารณาภาษาและเฟรมเวิร์กหลายแบบ เช่น .NET/F#, Go, Rust, React และลองเขียนโค้ดจริงด้วย
  • ตัวเลือกสุดท้ายคือ Ruby on Rails
    • เป็นเครื่องมือที่คุ้นเคยอยู่แล้ว และทำงานได้เร็วกว่าแนวทางที่ต้องเรียนรู้ใหม่ราว 10 เท่าตามความรู้สึก
  • ตอนนั้นการทำบน Rails ยังใกล้เคียงกับ proof of concept ชั่วคราว และวางแผนไว้ว่าในภายหลังจะเขียนใหม่ด้วยภาษาอื่นที่ไม่พลาดง่ายแบบ Ruby
  • แอป Rails เพิ่มฟีเจอร์ได้รวดเร็ว และเพื่อนร่วมงานก็ชอบผลลัพธ์
    • สามารถสร้างความสามารถที่ช่วยเพิ่มผลิตภาพได้อย่างรวดเร็ว
    • ในช่วงแรกสามารถป้องกันกรณีผิดพลาดที่เกิดบ่อยด้วยโค้ดได้

จุดที่ Rust และ SvelteKit “version 2” ไปต่อไม่ไหว

  • “version 2” เลือกใช้ Rust สำหรับแบ็กเอนด์ และ SvelteKit สำหรับฟรอนต์เอนด์
  • เวอร์ชันเริ่มต้นดูดีและทำงานเร็ว แต่มีฟีเจอร์ที่ต้องการเพียงประมาณ 10% เท่านั้น
  • ใน Rust ไม่มี integrated framework ที่เทียบกับ Rails ได้ จึงต้องเขียนโค้ดพื้นฐานและงานเชื่อมต่อมากกว่า logic ทางธุรกิจ
  • เริ่มชัดเจนว่าหากจะทำ version 2 ให้ครบถ้วน ต้องหยุดพัฒนา version 1 ไปเลย สุดท้าย version 2 จึงถูกยกเลิก
  • เรื่องนี้ยืนยันว่าการเขียนใหม่อาจใช้เวลาพอ ๆ กับตอนสร้างแอปเดิมตั้งแต่ต้น

ความซับซ้อนในการปฏิบัติการจากการย้ายแบบค่อยเป็นค่อยไป

  • แม้จะเป็นเช่นนั้น ก็ยังอยากนำ Rust เข้ามาใช้ในแอปอยู่ เพราะมี type system ที่แข็งแรง ประสิทธิภาพสูง และความมั่นใจเมื่อคอมไพล์ผ่าน
  • แม้จะใช้ Ruby มานานกว่า 4 ปี ปัญหา runtime ก็ยังเกิดอยู่เรื่อย ๆ
    • หลัก ๆ คือค่า null และ exception ที่ไม่ได้จัดการ
    • หลัง deploy ก็มักดูเครื่องมือรายงานข้อผิดพลาดเพื่อแก้ปัญหา production อย่างรวดเร็ว
  • ในฝั่งฟรอนต์เอนด์ของ Rails มีความไม่พอใจที่ logic กับ markup กระจายอยู่หลายไฟล์ ขณะที่ Svelte ทำให้รวมสิ่งที่เกี่ยวข้องไว้ในไฟล์เดียวได้ง่ายกว่า
  • จึงวางแผนเขียนฟรอนต์เอนด์ใหม่ด้วย SvelteKit และแบ็กเอนด์ใหม่ด้วย Rust แบบค่อยเป็นค่อยไป แล้วแทนที่ส่วน Rails เดิมทีละส่วนจนสุดท้ายถอด Rails ออก
  • ช่วงแรกการย้ายหน้า “index” ที่มีรายการข้อมูลและตัวกรองไปยังสแตกใหม่ดำเนินไปอย่างรวดเร็ว
    • สแตกใหม่ทำงานเร็ว และส่วนที่เป็น Rust แทบไม่มีปัญหา runtime
    • แต่กฎการ deploy เพื่อกำหนดว่า route ไหนควรไปที่ Rails, Rust หรือ SvelteKit กลับซับซ้อนขึ้น
    • ความซับซ้อนนี้ถูกยอมรับว่าเป็นสภาพชั่วคราวจนกว่าจะย้ายได้ครบ

งานเทคนิคที่ใหญ่กว่าคุณค่าต่อผู้ใช้

  • เมื่อเวลาผ่านไป ฝั่ง Rails ก็ยังมีการเพิ่มฟีเจอร์ใหม่ที่มีประโยชน์อยู่ต่อเนื่อง และฟีเจอร์เดิมก็ลึกและละเอียดขึ้นเรื่อย ๆ
  • มีการรีแฟกเตอร์หลายครั้งเพื่อแก้สมมติฐานที่ผิดตั้งแต่แรก และมองว่า schema ฐานข้อมูลที่ออกแบบดีจะช่วยได้ไม่ว่าใช้เวอร์ชันไหน
  • UI ของ Rails ถูกมองว่าอีกไม่นานก็จะถูกแทนที่ จึงตั้งใจว่าจะไม่ทุ่มเวลาเพิ่มมากนัก
  • หลายเดือนต่อมา ธุรกิจประสบความสำเร็จมากพอที่จะจ้างนักพัฒนาเต็มเวลาได้ และคาดว่าการย้ายไป Rust จะเร็วขึ้น
  • แต่ในความเป็นจริง เวลาจำนวนมากในสแตกใหม่ถูกใช้ไปกับการเขียน abstraction และกลไก
    • การเข้าถึงฐานข้อมูล
    • การจัดการสิทธิ์เพื่อให้ผู้ใช้เห็นเฉพาะข้อมูลที่ได้รับอนุญาต
    • การติดตามการเปลี่ยนแปลงทั้งหมด
    • การค้นหาและตัวกรอง
    • การบังคับข้อจำกัดผ่าน type system
  • จากนั้นรายการฟีเจอร์ที่ต้องมีก็ยาวขึ้นเรื่อย ๆ
    • งานเบื้องหลัง
    • ระบบ pub/sub สำหรับอัปเดตฝั่งไคลเอนต์
    • ความสามารถด้านอีเมล
    • OAuth 2.0 สำหรับเชื่อมต่อบริการภายนอก
    • SMTP และ POP
    • object storage
    • การสร้าง PDF
  • แม้จะมีไลบรารี Rust มากพอ แต่การคัดเลือกไลบรารีที่เหมาะสมและเชื่อมทุกอย่างเข้าด้วยกันเป็นงานใหญ่
  • การสนทนาเริ่มวนอยู่กับรายละเอียดเชิงเทคนิคของการ implement เช่น การเลือก Rust ORM หรือจังหวะเปิดตัวและการปรับปรุงของ Svelte 5
  • หลังใช้เวลาราว 1 ปีเขียน Rust และ Svelte ก็ชัดเจนว่าผู้ใช้แทบไม่ได้ประโยชน์จากงานนี้
    • บางหน้าของสแตกใหม่ลื่นไหลและเร็ว แต่ไม่ใช่จุดที่เป็นปัญหามาแต่แรก
    • หน้าที่ถูกใช้งานมากที่สุดยังคงทำงานอยู่บน Rails และมีฟีเจอร์มากกว่า “beta version” ของสแตกใหม่ถึง 10 เท่า
    • มีหลายช่วงที่ต้องใช้เวลาหลายวันหรือหลายสัปดาห์กับงานที่ไม่ได้เพิ่มคุณค่าโดยตรง

การตัดสินใจกลับไปใช้ Rails

  • จึงตัดสินใจ เขียนใหม่บน Rails เฉพาะส่วนที่กำลังรันอยู่บนสแตกใหม่
  • ไม่ใช่การเขียนทั้งแอปใหม่ทั้งหมด แต่เป็นการย้อนส่วนที่ย้ายไป Rust/SvelteKit กลับมาเป็น Rails
  • การตัดสินใจนี้ยาก แต่สมเหตุสมผล
    • เพราะได้ลงทุนทั้งเวลาและโค้ดไปมากแล้ว
    • และอาจมีความเป็นไปได้ที่สมาชิกทีมจะไม่ชอบ Ruby หรือ Rails
    • โชคดีที่ทีมเข้าใจการตัดสินใจนี้ และเปิดรับการเรียนรู้สิ่งใหม่
  • จุดแข็งของ Rails คือมีความสามารถจำนวนมากมาให้ตั้งแต่ต้น มี ecosystem ไลบรารีที่สุกงอมและเสถียร และมีแนวทางกับ convention ที่ชัดเจนจนทำให้โค้ดกระชับ
  • Rails ช่วยให้โฟกัสกับการสร้างผลิตภัณฑ์ และลดภาระการเขียนโค้ดสนับสนุนระดับล่างด้วยตัวเอง

บทเรียนที่เหลือหลังกลับมาใช้ Rails

  • ความพยายามกับ Rust และ Svelte ไม่ได้สูญเปล่าไปทั้งหมด
    • การเรียนรู้ภาษาและเฟรมเวิร์กใหม่ทำให้ได้มุมมองและไอเดียที่นำไปใช้กับภาษาอื่นได้ด้วย
    • การสร้างเว็บแอปพลิเคชันคือชุดของการเลือกและการแลกเปลี่ยน
    • ต้องชั่งน้ำหนักระหว่างการยอมรับข้อจำกัดของเฟรมเวิร์ก หรือการลงทุนลงมือทำเอง ว่าจะให้ความได้เปรียบในการแข่งขันและผลตอบแทนระยะยาวหรือไม่
  • การย้อนกลับมาใช้ Rails ทำได้ค่อนข้างตรงไปตรงมา และช่วยลดความเครียดลง
  • ในช่วงไม่กี่สัปดาห์ที่ผ่านมา ก็กลับมารู้สึกถึงผลิตภาพอีกครั้ง ทั้งในการพัฒนาฟีเจอร์ใหม่ ปรับปรุงของเดิม อัปเดต UI และแก้บั๊ก
  • ข้อเสียของ Ruby และ Rails ถูกยอมรับว่าเป็นเงื่อนไขที่ต้องคำนึงถึงระหว่างเขียนโค้ด
    • ถ้ามีปัญหา runtime มาก ก็ต้องทดสอบให้มากขึ้น
    • spaghetti code ที่ดูแลยากนั้น นักพัฒนาสร้างได้ง่ายไม่ว่าใช้ภาษาหรือเฟรมเวิร์กใด
    • ต้องใช้เวลากับการรีแฟกเตอร์และจัดระเบียบโค้ดให้มากขึ้น
    • หากขยาย Rails ได้ยาก ก็อาจหมายความว่าสิ่งอื่นก็ขยายยากเช่นกัน
    • Rails เร็วเพียงพออยู่แล้ว และยังมีทางอ้อมด้วย Turbo และ caching
  • จากมุมผู้ใช้ สแตก Rust ไม่ได้เร็วขึ้นอย่างสังเกตได้
  • ใน Rails หน้าเว็บที่หนักที่สุดมี P95 duration อยู่ที่ 338ms ซึ่งยังมีพื้นที่ให้ปรับปรุง แต่ก็ถือว่าเร็วพอที่จะรู้สึกว่าลื่นแล้ว
  • ไม่มีภาษาและเฟรมเวิร์กใดสมบูรณ์แบบ ต้องรู้จักจุดแข็งและจุดอ่อนแล้วจัดการกับมัน
  • Rails เป็นหนึ่งในเฟรมเวิร์กที่ดีมากสำหรับคนที่อยากโฟกัสกับการสร้างผลิตภัณฑ์ และเฟรมเวิร์กอื่น ๆ ที่อยู่มายาวนานและมีผู้มีส่วนร่วมอย่างคึกคักก็อาจเป็นตัวเลือกที่ดีไม่แพ้กัน

2 ความคิดเห็น

 
lemonmint 2024-11-04

เขียนใหม่ด้วย Ruby
เขียนใหม่ด้วย Rails

 
GN⁺ 2024-11-04
ความคิดเห็นจาก Hacker News
  • ผมมองว่า Rails นำหน้าสต็กอื่น ๆ มากในการสร้างเว็บแอป รวมถึง Django หรือ Laravel ด้วย
    มันจัดการส่วนที่น่าเบื่อมาหมดแล้ว รู้ว่าความต้องการที่จำเป็นมีอะไรบ้าง และขัดขวางน้อยกว่าเวลาสร้างแอปจริง ตลอด 15 ปีที่พัฒนาเว็บแอป ผมเคยใช้ Meteor, Remix, Next.js, Node.js บน Express และอื่น ๆ แต่รู้สึกว่าการพัฒนาเว็บเป็นปัญหาที่ถูกแก้ไปมากแล้ว ฝั่ง JavaScript ค่อนข้างเหมือนนักพัฒนาถูกเงินทุนจากบริษัทใหญ่ผลักให้ไปเล่นของเล่นใหม่ ๆ ส่วน Rust หรือ Go เหมาะกับการพัฒนาระบบและโครงสร้างพื้นฐานการ deploy แต่การยัดมันเข้ามาใช้กับงานพัฒนาเว็บแบบฝืน ๆ นั้นดูไม่สมเหตุสมผล

    • แม้จะไม่ใช่สแต็กที่กำลังเป็นกระแส แต่รู้สึกว่า Spring Framework/Spring Boot เป็นสแต็กเว็บแอปพลิเคชันที่ดีที่สุดโดยรวม
      มันผสานกับไลบรารี Java จำนวนมากได้ง่าย และเป็นภาษาแบบ static type จึงช่วยได้ในหลายสถานการณ์ แค่การ bind ข้อมูลตาม convention ผ่าน Jackson ก็ยอดเยี่ยมมาตั้งนานแล้ว ส่วนในภาษาแบบ dynamic type สิ่งเหล่านี้มักให้ความรู้สึกเหมือนถูกเติมเข้ามาทีหลัง
    • เฟรมเวิร์กเหล่านี้เหมือน เลนด่วน สำหรับเริ่มโปรเจกต์ เพราะไม่ต้องตัดสินใจเรื่องใหญ่ ๆ มากนัก
      แต่หลังจากลงลึกกับ Rails, Django, Laravel แล้ว หากต้องทำสิ่งที่ออกนอก convention ก็อาจยุ่งยากได้ เพราะไม่ได้เขียนโค้ดเชื่อมต่อเอง จึงมักเกิดช่องว่างด้านความเข้าใจมากกว่าจะเป็นอุปสรรคทางเทคนิค ถึงอย่างนั้น หากเรียนรู้ภายในของมันอย่างถูกต้อง แค่อ่านโค้ดก็ประหยัดเวลาการเขียนโค้ดได้มหาศาล แน่นอนว่าในความเป็นจริงเรามักไม่ทำแบบนั้น และเพราะการเขียนใหม่ทั้งหมดมันสนุกเกินไป ต่อให้ไม่สมเหตุสมผลทางธุรกิจก็ยังอยากลองของใหม่
    • ไม่เห็นด้วย Rails ยอดเยี่ยมในแง่ฟีเจอร์และ productivity แต่ไม่ใช่ ทางออกครอบจักรวาล
      ไม่ต้องเชื่อแค่ความเห็นผม ดูข้อมูลได้เลย: https://www.youtube.com/watch?v=Qp9SOOtgmS4
      หากใช้ Rails กับบริการที่ยังไม่รู้แน่ชัดว่าจำนวนผู้ใช้หรือจำนวน request ต่อวินาทีจะเป็นเท่าไร อาจประหยัดต้นทุนตอนเปิดตัวได้ แต่ต้องจ่ายค่าเซิร์ฟเวอร์มากขึ้น
    • ในฐานะคนที่เคยใช้ AOLServer และเคยอยู่ในสตาร์ทอัพที่สร้างสิ่งคล้าย Rails ด้วย Tcl เมื่อปี 1999 ผมไม่ค่อยเห็นด้วยเท่าไร
      เดโมของ Rails ไม่ได้ดึงดูดมากนัก นอกจากแสดงให้เห็นว่าโชคเรื่องการถูกนำไปใช้และได้รับความสนใจนั้นสำคัญแค่ไหน ถึงตอนนี้ก็ยังไม่ค่อยเห็นคุณค่าของมัน และผมคงเลือก Spring หรือ ASP.NET ผู้ก่อตั้งสตาร์ทอัพที่ใช้ Tcl นั้นต่อมาสร้าง OutSystems ซึ่งเป็นหนึ่งในเครื่องมือ RAD ไม่กี่ตัวที่ประสบความสำเร็จในการพัฒนาเว็บระดับองค์กร และเป็นหนึ่งในกรณีความสำเร็จของวงการ IT โปรตุเกส
    • เรื่องนี้ส่วนใหญ่ใช้ได้กับ Django ด้วย
      เมื่อก่อนผมชอบ Rails มากกว่า แต่ในช่วงกว่า 10 ปีที่ผ่านมา Python เติบโตขึ้นมาก ทำให้ Django กลายเป็นตัวเลือกที่ใช้งานได้จริงกว่า นักพัฒนาด้าน machine learning และ data science คุ้นเคยกับ Python อยู่แล้ว และเอกสารของ Django ก็ดีมากจนถ้าจำเป็นก็สามารถ productive ได้ในเวลาอันสั้น ผมเห็นมากับตัวในหลายโปรเจกต์
      Django ยังช่วยลดการตัดสินใจและการถกเถียงเรื่องโครงสร้างแอปพลิเคชัน เมื่อเทียบกับไลบรารีหรือ microframework ที่ยึดแนวทางน้อยกว่า ชุมชน Django/FLOSS ก็คึกคักกว่าที่คิดมาก และการมีปฏิสัมพันธ์ด้วยก็น่าพอใจ อย่างไรก็ตาม อยากให้มี generator แบบ Rails และฟังก์ชัน seed ข้อมูลในตัว เช่น rake db:seed
  • ผมใช้ Rails มา 17 ปีแล้ว ยังชอบอยู่ และชอบใช้กับ front-end ด้วย
    มันให้ตัวเลือกทั้งหมดในการแยกโค้ด โดยที่หัวไฟล์ไม่กลายเป็นรายการ includes ยาวเกินจำเป็นอย่างที่เห็นในแอป Angular ผมไม่เห็นข้อเสียของการแยก logic กับ markup ใน front-end เพราะสามารถทดสอบ logic แยกต่างหากได้ และโดยปกติเมื่อหาบั๊ก เราจะรู้ได้ว่าเป็นปัญหาที่ markup หรือ logic ทำให้ตามรอยง่ายขึ้น ผมเองก็เคยเขียนเมธอด Ruby ยาวเกิน 200 บรรทัดอยู่ไม่น้อย แต่นั่นเป็นความผิดของผมจริง ๆ และถ้ามีระบบ unit test ที่ละเอียดขึ้นก็ป้องกันได้

    • อีกวิธีในการหลีกเลี่ยงรายการ includes ยาว ๆ คือทำให้ทุกอย่างเป็น global
      ผมไม่แน่ใจว่านั่นเป็นข้อดีหรือเปล่า import อาจกินพื้นที่มากก็จริง แต่มันแสดงอย่างชัดเจนว่าทุกอย่างเชื่อมกันอย่างไร ถ้ารบกวนสายตา ก็พับเก็บไว้ใน IDE ได้
  • ชอบที่เป็นบทความที่อยู่บนความจริง ประโยคสำคัญควรวางไว้ข้างเตียงให้อ่านเสมอ
    “น่าสนใจที่สิ่งต่าง ๆ ใน Ruby และ Rails ที่เคยทำให้หงุดหงิด ตอนนี้รบกวนน้อยลงมาก ผมยอมรับแล้วว่าไม่มีภาษา หรือเฟรมเวิร์กที่สมบูรณ์แบบ แค่ต้องรู้จุดแข็งจุดอ่อนและรับมือกับมัน”

    • ชอบที่บทความนี้ใช้งานได้จริง รู้สึกเหมือนเป็นบทนำที่ดีให้อ่านก่อน เขียนใหม่ อะไรสักอย่าง
    • หลายครั้งผมรู้สึกว่าคนที่บ่นเรื่องเฟรมเวิร์กมักมี โลกทัศน์อุดมคติ ที่ไม่อยากประนีประนอม
      ในหลายกรณี พวกเขาไม่ได้เข้าใจเฟรมเวิร์กมากพอ และไม่รู้ด้วยว่าทำไมมันถึงเป็นแบบนั้น แต่การรู้ข้อจำกัดและทำงานร่วมกับเฟรมเวิร์กนั้นมีประสิทธิภาพกว่ามาก ควรใช้เวลาเพื่อทำความเข้าใจเครื่องมือที่ตัวเองใช้อย่างถูกต้อง
    • ประโยคนั้นมีบริบทมาจากความพยายามแบบนี้
      “ระหว่างนั้น ผมเริ่มสร้าง ‘เวอร์ชัน 2’ ของแอปพลิเคชัน โดยเลือก Rust เป็นภาษาแบ็กเอนด์ และ SvelteKit เป็นฟรอนต์เอนด์”
      เพราะ v1 เริ่มด้วย Rails เลยอ่านได้ว่าเป็นบทความที่เตือนให้ระวังเมื่อจะทิ้งเฟรมเวิร์กที่ทำงานได้ดีอยู่แล้ว
    • สำหรับผม นี่ก็เป็นส่วนที่สำคัญที่สุดที่ได้ตระหนักเหมือนกัน ตอนนี้ไม่ต้องคิดวนอยู่กับเรื่องอย่าง “ถ้ามี enum ของ Rust ก็คงดี!” แล้ว เลยมีความสุขขึ้นมาก
  • Rust เป็นภาษาที่สร้างโดยคนฉลาดมาก ๆ แต่ดูเหมือนจุดเน้นจะไปอยู่ที่ทฤษฎี type และการประหยัดการจัดสรรหน่วยความจำไม่กี่ครั้ง มากกว่าการทำให้ developer หน้างานแบบผมสร้างสิ่งที่มีประโยชน์และสม่ำเสมอได้
    ถึงจะใช้ Rust มาตั้งแต่ปี 2020 แต่เวลาอ่านบทความในบล็อก Rust ผมก็ยังเข้าใจไม่ถึงครึ่งจริง ๆ

    • ช่วยยกตัวอย่างที่รู้สึกว่า Rust ไม่มีความสม่ำเสมอได้ไหม? ผมกลับรู้สึกว่ามันเป็น ภาษาที่สม่ำเสมอมาก ขนาดเล็กและออกแบบมาดี
      โดยเฉพาะเมื่อเทียบกับภาษากระแสหลักขนาดใหญ่ เช่น trait ครอบคลุม use case ของทั้ง abstract class และ concept ใน C++ รวมถึง abstract class และ protocol ใน Python ไม่มีความไม่สอดคล้องกันว่าจะใช้ exception หรือคืนค่าเพื่อจัดการ error ด้วย มี panic อยู่ก็จริง แต่ใช้เหมือน assertion ถ้า if-else เป็น expression ก็ไม่ต้องมี ternary operator แยกต่างหาก
    • Rust เป็น ภาษาเชิงระบบ และทำได้ยอดเยี่ยมในพื้นที่นั้น ถ้าเทียบกับภาษาในสายเดียวกัน บทความบล็อกของ C++ ให้ความรู้สึกไม่สม่ำเสมอมากกว่ามาก
      ช่วงหลังมีแนวโน้มพยายามใช้ Rust กับทุกอย่าง แต่ภาษานี้ไม่ได้ถูกสร้างมาเพื่อเขียนแอป CRUD บทความนี้สุดท้ายก็ใกล้เคียงกับ case study ที่ว่า “ใช้เครื่องมือให้เหมาะกับงาน ภาษาที่คุณชอบในเวลาว่างหรือภาษาตามกระแสล่าสุดไม่จำเป็นต้องเหมาะเสมอไป”
    • โดยแก่นแล้ว Rust คือ ตัวแทนของ C++
      ถ้ารับภาระของ garbage collector ได้ ก็ไม่มีเหตุผลต้องใช้ Rust หรือ C++ แล้วกังวลเรื่องการจัดการหน่วยความจำ มีคนโปรโมต Rust ว่าเป็นภาษาโปรแกรมมิงทั่วไป และในเชิงทฤษฎีก็ถูก แต่ยุค 90 C++ ก็ถูกโปรโมตแบบนั้นเหมือนกัน การลดการจัดสรรหน่วยความจำให้น้อยที่สุดมักเป็นคุณสมบัติที่ต้องการพอดีเวลาที่เลือก Rust หรือ C++
  • การเขียนเว็บแอปพลิเคชันขนาดใหญ่ด้วย Rust ให้เร็วทำได้ยาก
    แอปพลิเคชันขนาดใหญ่ที่เขียนด้วย Rails อาจรันไม่เร็ว อาจมีบั๊กมาก หรือดูแลและขยายยากก็ได้ ตัวเลือกอย่าง Java, C#, Go อาจไม่ดูเซ็กซี่หรือเท่ แต่สามารถทำงานให้เสร็จได้เร็วพอ ๆ กับ Rails และรันได้ใกล้เคียงความเร็วของ Rust โดยปกติแล้วโปรเจกต์ก็จะมีบั๊กน้อยลง ดูแลและขยายได้ง่ายขึ้นด้วย

    • คงพูดอย่างจริงจังไม่ได้ว่า ภาษาเชิงระบบระดับต่ำ อย่าง Go มี productivity เท่ากับ Rails ซึ่งเป็น framework ระดับสูงสำหรับแอป CRUD
      ไม่ว่าจะเกลียด Rails แค่ไหน นี่ก็คล้ายกับการบอกว่าสามารถสร้างบล็อกด้วย C++ ได้เร็วกว่า WordPress
    • ผมมองว่าคำว่า “แอปพลิเคชันขนาดใหญ่ที่เขียนด้วย Rails ไม่เร็ว มีบั๊กมาก และดูแลกับขยายยากได้” เป็น การเหมารวมเกินไป
      ถ้าทำอย่างใส่ใจ มันไม่จำเป็นต้องเป็นแบบนั้น ผมเคยเห็นแอป Rails ขนาดใหญ่ที่แทบไม่มีบั๊ก เสถียร และแก้ไขง่ายมามาก และก็เคยเห็นทั้งแอป Rails กับ Go ที่เละเทะมาแล้วเหมือนกัน บางภาษาและ framework อาจทำให้ตกไปอยู่ในสภาพนั้นได้ง่ายกว่า แต่ทุกอย่างเป็นไปได้ และก็มี trade-off ที่ทำให้ยากขึ้นด้วยเหตุผลอื่น หากมีวินัย ก็ทำให้อะไร ๆ ใช้งานได้ทั้งนั้น
    • Rails ก็สามารถสร้าง แอปพลิเคชันขนาดใหญ่ ที่เร็ว บั๊กน้อย และไม่ได้ดูแลกับขยายยากได้ มีตัวอย่างจริงอยู่มากมาย
      ถ้า developer มีฝีมือใกล้เคียงกัน Rails จะพัฒนา feature ของเว็บแอปพลิเคชันส่วนใหญ่ได้เร็วกว่า Java, C#, Go จากประสบการณ์ของผมเร็วได้ถึง 3 เท่า ผมเคยดูแลทั้ง monolith ขนาดใหญ่และสถาปัตยกรรมแบบ service-oriented และเคยทำงานร่วมกับทีม Java ด้วย ช่วงหนึ่งผมถึงขั้นนำ Go เข้ามาในองค์กร Rails ด้วยความเชื่อแบบเดียวกัน
      สุดท้ายปัญหาจริง ๆ คือ MVC ไม่ได้เหมาะกับทุกอย่าง และไม่ได้ใช้ namespace อย่างเข้มงวดพอ หากแก้ปัญหานั้นในพื้นที่เล็ก ๆ ที่เจาะจง Rails ก็ใช้ได้ดีพอ
    • ผมไม่เคยใช้ Basecamp แต่เชื่อว่าผลิตภัณฑ์นี้เขียนมาดีและใช้ได้ดี
      ดังนั้นถ้ามีการจัดการที่เพียงพอ สถาปัตยกรรมที่ดี และการบำรุงรักษาที่ดี ผมคิดว่า Rails ก็ทำได้
  • ช่วงหลังเริ่มทดสอบ AdonisJS ในฐานะทางเลือก TypeScript ของ Rails
    ถ้าสนใจ “Rails ที่เขียนด้วย TypeScript” แนะนำให้ลองใช้ดู มันให้ความรู้สึกใกล้ Rails หรือ Laravel มากกว่า stack TypeScript ยอดนิยมส่วนใหญ่อย่างชัดเจน และเป็นแนวทางแบบ batteries included แทนที่จะปล่อยให้ต้องเลือกทุกส่วนของ stack เองหรือเชื่อ template จาก third-party

    • ผมเคยสงสัยเกี่ยวกับ AdonisJS อยู่ พอเห็นคอมเมนต์นี้ก็อยากลองใช้ดู
      ช่วงหลังผมเริ่มถูกดึงดูดโดย backend framework แบบ batteries included อย่าง Rails, Laravel, Django แต่ตลอดอาชีพแทบจะใช้ TypeScript มาตลอด จึงง่ายกว่าที่จะไปต่อแบบเดิมมากกว่าการเปลี่ยนตอนนี้ อยากรู้ความรู้สึกหลังได้ทดสอบ และอยากรู้ด้วยว่าเทียบกับ framework อื่น ๆ ที่พูดถึงได้ไหม
    • ตั้งใจจะลองใช้ AdonisJS อยู่พอดี ถือเป็นข่าวดี
      ช่วงหลังในโปรเจกต์ส่วนตัวผมเลือก NestJS แต่ไม่นานก็ได้รู้จัก Adonis และกำลังคิดจริงจังว่าจะย้ายไปหรือไม่
  • เทคโนโลยีอย่าง Next.js และ SvelteKit ได้รับความนิยมในหมู่ JavaScript developer เพราะช่วยบรรเทาปัญหาที่ประสบการณ์พัฒนา backend ของ Node.js ไม่ดี
    การทำ backend ด้วย TypeScript คล้ายกับทำด้วย C# แต่รู้สึกว่าข้อดีของภาษาที่ออกแบบมาดีหายไป ประสบการณ์ต่างจากการทำ backend ด้วย Rails มาก developer Node.js ก็เริ่มตระหนักว่าไม่ใช่แค่ปัญหาของ ecosystem และเครื่องมือเท่านั้น แต่ framework ที่ให้คำตอบครบถ้วนในการสร้างแอปพลิเคชันก็สำคัญ จุดที่ Next.js และ SvelteKit ช่วยได้คือจุดนั้น และนั่นก็เป็นสิ่งที่ Rails สร้างนวัตกรรมไว้ในปี 2006

    • ผมชอบ TypeScript อยากรู้ว่าเมื่อเทียบกับ C# แล้ว มันไม่ใช่ ภาษาที่ออกแบบมาดี ตรงไหน
    • การเอา Next.js หรือ Remix ฯลฯ ไปเทียบกับ Rails, Django, Laravel นั้นฝืนเกินไป
      แค่รันโค้ดบน backend ได้แล้วจะเอาไปเทียบกับ Rails หรือ? การเข้าถึงฐานข้อมูล, migration, ORM, queue, scheduled job, validation, translation, authentication, authorization support อยู่ตรงไหน? สิ่งเดียวที่ Next.js ช่วยคือผลักคนเข้าไปใน แพลตฟอร์ม Vercel เท่านั้น
    • ถ้าให้เลือกระหว่าง C# กับ TypeScript สำหรับ backend ผมยินดีเลือก C#
      ถ้าเป็น frontend ผมชอบ TypeScript มากกว่า JavaScript
  • คอมเมนต์ที่บอกว่า Rust ไม่ค่อยเหมาะกับเว็บแบ็กเอนด์ทำให้สับสนนิดหน่อย
    จากประสบการณ์ที่ทำบริการเล็ก ๆ อย่าง beampaint.com หรือ probablyup.net เป็นหลัก กลับรู้สึกตรงกันข้าม ถ้าทำแอปที่ใหญ่ขึ้น ความซับซ้อนอาจเพิ่มขึ้นมาก และก็คงเป็นแบบนั้นแน่ ๆ แต่ในการให้ความมั่นใจที่จำเป็นสำหรับโค้ดเบสขนาดใหญ่ Rust ทำได้ยอดเยี่ยม

    • พอถึงจุดที่ต้องการฟีเจอร์ในระดับเฟรมเวิร์กมากขึ้น ความยากจะพุ่งขึ้นอย่างรวดเร็วไม่ใช่หรือ?
      เฟรมเวิร์กเก่า ๆ มีสิ่งเหล่านั้นมาให้เป็นพื้นฐานอยู่แล้ว แต่เฟรมเวิร์กของ Rust มีโอกาสน้อยกว่าที่จะมีครบเพราะอายุยังน้อย ลองจินตนาการว่าฟีเจอร์ที่ขาดไปเพิ่มจากสองอย่างเป็นหกอย่างก็พอ
  • บทความนี้แทบจะเหมือนเรื่องชีวิตของผมเลย
    เคยใช้ Rails แล้วในปี 2013 ก็เปิดตัวแอป SaaS ที่เขียนด้วย Go ซึ่งต้องหาทุกอย่างเองหมด ทั้งไมเกรชัน เลเยอร์ฐานข้อมูล แอสเซ็ตไปป์ไลน์ การ deploy การตรวจสอบความถูกต้อง logging การชำระเงิน และอีกหลายอย่างที่ Rails ให้มาอยู่แล้ว

    • แต่ประสบการณ์นั้นก็น่าจะทำให้กลายเป็นนักพัฒนาที่ชำนาญขึ้นมาก
    • กำลังเอาภาษาโปรแกรมระดับต่ำที่เป็นโครงร่างแบบเน้นระบบอย่างเดียว ไปเทียบกับเฟรมเวิร์กระดับสูงมากบนภาษาระดับสูงมาก
      ผมไม่ได้ชอบ Go แต่ในกรณีนี้ Go ไม่ใช่สิ่งที่ควรถูกตำหนิ การใช้ Go กับ แอปพลิเคชัน CRUD เป็นการตัดสินใจที่แย่มากตั้งแต่แรกแล้ว
  • Django ก็ให้ความรู้สึกคล้ายกัน
    ปัญหาด้านประสิทธิภาพมักเกิดจาก คิวรีฐานข้อมูล มากกว่าจากตัว Django เองมาก

    • แทบทุกครั้งคิวรีฐานข้อมูลจะใช้เวลานานที่สุดอยู่แล้ว แต่เห็นวิศวกรมากเกินไปที่ไม่ทำแม้แต่การปรับแต่งพื้นฐานอย่างการสร้างดัชนี
      การปรับแต่งง่าย ๆ ที่มักถูกลืม ได้แก่ การสร้างดัชนีฐานข้อมูล, มอบตรรกะให้ฐานข้อมูลทำมากกว่าโค้ด เช่น ใช้ MongoDB pipeline หรือ partial index ของ Postgres, เปิดใช้การบีบอัด Brotli/zstd สำหรับคำขอส่วนใหญ่, แคชอ็อบเจ็กต์หรือคำขอด้วยแคชในหน่วยความจำอย่าง Redis, และตั้งค่า header ควบคุมแคชให้เหมาะสม ส่วนฝั่งฟรอนต์เอนด์ก็ต้องมีการปรับแต่ง เช่น อย่าเรนเดอร์อ็อบเจ็กต์หลายพันรายการเป็นโหนด DOM แต่ให้ใช้ canvas แทน เพิ่งเห็นปัญหาแบบนี้ในแอปพลิเคชันแผนที่เมื่อไม่นานมานี้