Tech Blog

เหตุใดจึงแยก Admin Panel และ Customer App เป็น Repository ต่างกัน — สิ่งที่ได้และสิ่งที่เสีย

by Tech Writer
Architecture Git Design

บทนำ

เมื่อสร้างระบบ DVD rental สิ่งแรกที่เราลังเลคือจะใส่ admin panel และ customer app ไว้ใน repository เดียวกันหรือแยกกัน

เราเลือก repository แยกในที่สุด แต่การตัดสินใจนั้นไม่ได้ “ชัดเจนตั้งแต่แรก” มันคือการตัดสินใจที่เกิดจากการไตร่ตรอง เปรียบเทียบ และยอมรับการแลกเปลี่ยน


การคิดเริ่มต้น

แรงดึงดูดของ Monorepo

แรกๆ ผมคิดว่า “รวมทุกอย่างไว้ใน repository เดียวไม่ง่ายกว่าเหรอ?”

  • สามารถแชร์ DB definitions (Flyway migrations) ได้
  • สามารถนำ utility classes ทั่วไปมาใช้ซ้ำได้
  • สามารถรวม CI/CD ได้

สำหรับโปรเจกต์ขนาดเล็ก monorepo ก็เพียงพอ OSS หลายๆ โปรเจกต์ก็ทำแบบนั้น

อย่างไรก็ตาม เราพิจารณาสิ่งนี้

เมื่อคิดถึงวิสัยทัศน์ในอนาคตของระบบนี้ รู้สึกว่ามีบางอย่างที่ไม่ถูกต้อง

  • Admin panel: Spring Boot + Thymeleaf (server-side rendering)
  • Customer app: Spring Boot + Vue 3 (SPA + REST API)

Tech stack แตกต่างกันอย่างพื้นฐาน Frontend build pipelines, deployment strategies และ access control layers ต่างกัน การใส่ไว้ใน repository เดียวกันจะทำให้การจัดการ pom.xml และ package.json ซับซ้อน

นอกจากนี้ยังมีวิสัยทัศน์ในการขยายเป็น platform ครอบคลุมเหมือน DMM ในอนาคต ด้วยมุมมองที่กว้างขึ้น “แยกตั้งแต่แรก” รู้สึกเป็นธรรมชาติมากกว่า


สามคำถามที่ใช้เป็นเกณฑ์การตัดสิน

คำถามที่ 1: หน่วย deployment เหมือนกันไหม?

Admin panel และ customer app ไม่จำเป็นต้อง deploy พร้อมกันเสมอ เราต้องการหลีกเลี่ยงการเพิ่มฟีเจอร์ admin ที่ส่งผลต่อสภาพแวดล้อม production ฝั่งลูกค้า

ถ้าหน่วย deployment ต่างกัน repository แยกกันง่ายกว่า

คำถามที่ 2: จะแยกสิทธิ์การเข้าถึงอย่างไร?

เมื่อโปรเจกต์กลายเป็นทีม การจัดการสิทธิ์เมื่อ back-office staff และ frontend developer ฝั่งลูกค้าแตะต้อง codebase เดียวกันเป็นเรื่องยุ่งยาก

ด้วย repository แยก สิทธิ์การเข้าถึง GitHub สามารถควบคุมได้ต่อ repository

คำถามที่ 3: จะไม่จำกัดการเลือกเทคโนโลยีในอนาคตไหม?

Customer app ใช้ Vue 3 แต่วันหนึ่งอาจอยากเปลี่ยนเป็น React Admin panel ใช้ Thymeleaf แต่อาจย้ายไปใช้ Next.js ในอนาคต เมื่ออยู่ใน repository เดียวกัน dependencies ของฝั่งหนึ่งจะจำกัดอีกฝั่ง

การแยก repository สมเหตุสมผลสำหรับการรักษา loose coupling


โครงสร้างจริง

dvd-rental-admin/         ← Admin panel (Spring Boot + Thymeleaf + TypeScript)
dvd-rental-customer-app/  ← Customer app (Spring Boot + Vue 3)
dvd-rental-doc/           ← เอกสารออกแบบ (shared resource)

เอกสารถูกรวมไว้ใน dvd-rental-doc repository เฉพาะ DB definitions ที่แชร์ร่วมกัน (ER diagrams, table specs) ถูกวางไว้ที่นั่นและอ้างอิงโดย repository ทั้งสอง


Pain Points จริงๆ กับ Repository แยก

ขอพูดตรงๆ มีข้อเสีย

การจัดการ DB migrations สองที่

Flyway ฝั่ง admin และ Flyway ฝั่ง customer app ทั้งคู่ target DB เดียวกันแต่จัดการแยกกัน ตอนนี้เราจัดการแบบรวมศูนย์ฝั่ง admin และ customer app ทำแค่ reads และ API calls

กระบวนการที่ต้องเริ่มในเครื่องมากขึ้น

เพื่อรันทั้งคู่ใน local:

  • Admin panel: port 8081
  • Customer backend: port 8082
  • Frontend (Vite): port 5173
  • PostgreSQL: port 15433

ต้องเริ่ม 4 กระบวนการ เมื่อคุ้นเคยแล้วไม่มีปัญหา แต่แรกๆ ค่อนข้างยุ่ง

ไม่สามารถแชร์ code ได้

เมื่อต้องการนำ DTOs หรือค่าคงที่ทั่วไปมาใช้ซ้ำ กับ repository แยก ต้องจัดการผ่าน Maven repository เป็น shared library หรือคัดลอก ตอนนี้เราออกแบบให้ repository ทั้งสองเป็น loosely coupled โดยตั้งใจ ดังนั้นจึงมีนโยบาย “ไม่คัดลอก shared code”


สิ่งที่ได้

  • สามารถออกแบบ branch strategy และ CI/CD อย่างอิสระต่อ repository
  • การเปลี่ยนแปลงเทคโนโลยี (การย้าย framework ฯลฯ) ทำได้ง่ายขึ้น
  • รอบการ release ของ admin panel และ customer app สามารถเป็นอิสระได้
  • สิทธิ์การเข้าถึง GitHub สามารถควบคุมได้ต่อ repository

สรุป

“ควรใช้ repository แยกไหม” ขึ้นอยู่กับขนาดทีม, นโยบายการขยายในอนาคต และความแตกต่างใน tech stack ครั้งนี้ปัจจัยที่ตัดสินคือ: “หน่วย deployment ต่างกัน”, “tech stack แตกต่างกันอย่างพื้นฐาน” และ “ไม่ต้องการจำกัดการเลือกเทคโนโลยีในอนาคต”

มีหลายกรณีที่ monorepo เป็นคำตอบที่ถูกต้อง สิ่งสำคัญคือสามารถอธิบาย “ทำไมถึงเลือกโครงสร้างนั้น” ด้วยคำพูดของตัวเองได้


บทความที่เกี่ยวข้อง

การสร้างแอพ DVD Rental สำหรับผู้ใช้ควบคู่กับหน้าจัดการ — ภาพรวมโครงสร้าง Vue 3 + Spring Boot

ส่งข้อความได้ตามสบาย

กรุณาส่งข้อความ หากมีคำปรึกษาด้านเทคนิค ความคิดเห็น หรือคำถาม