มาลอง Code style Hexagonal กัน
มาลองเขียน go style Hexagonal กัน
เริ่มต้น setup project ก่อน ใน หัวข้อนี้เราจะใช้ Fiber และ Gorm ที่เคยร่ำเรียนมาจากก่อนหน้านี้
- Fiber เป็นตัวแทนของฝั่งการรับ HTTP Request ที่ส่งมาจาก Client ของ User
- Gorm เป็นตัวแทนของฝั่งการส่งข้อมูลเข้า Database ที่ทำต่อหลังจากได้รับข้อมูลจาก Business Logic
** เพื่อให้เกิดความเข้าใจที่ถ่องแท้มากขึ้น ขอให้รู้จัก 2 ตัวนี้มาก่อนที่จะเริ่ม code เรื่องนี้
เราจะลองทำ Diagram หน้าเมื่อกี้ (ส่วนของการ Create Order) ออกมาเป็น code กันบ้าง
โดยเราจะทำการวาง Structure กันตามนี้
.
├── adapters --> สำหรับเก็บ adapter
│ ├── gorm_adapter.go
│ └── http_adapter.go
├── core --> สำหรับเก็บ business logic, port
│ ├── order.go
│ ├── order_repository.go
│ └── order_service.go
├── main.go
1. Port
Structure ที่เกี่ยวข้องจะมี 3 file นี้
.
├── adapters --> สำหรับเก็บ adapter
│ ├── gorm_adapter.go
│ └── http_adapter.go
├── core --> สำหรับเก็บ business logic, port
│ ├── order.go
│ ├── order_repository.go
│ └── order_service.go
├── go.mod
├── go.sum
├── main.go
สิ่งแรกที่เรามีการประกาศออกมาก่อนคือ struct สำหรับการเก็บข้อมูล Order ไว้ภายใน core
โดย โครงสร้างนี้จะมีการเรียกใช้งานในทุกส่วนของ application เพื่อให้ทุกคนสามารถเข้าถึงโครงสร้างข้อมูลหน้าที่เหมือนกันออกมาได้
ที่ order.go
ก็จะมีหน้าประมาณนี้
package core
type Order struct {
ID uint˝
Total float64
}
โดย Port จะมีทั้งหมด 2 ตัวที่ต้อง implement คือ
- Primary Port (ส่วนที่ต้องรับจากภายนอก) = เก็บไว้ที่
order_service.go
โดย
- implement
OrderService
เป็น Port ระบุการเชื่อมต่อเอาไว้ว่า ถ้าจะส่งข้อมูลเข้ามาต้องส่งข้อมูล order หน้าตาแบบไหนมา - โดยเราจะสร้าง
order.go
สำหรับการเก็บ schema ของ data เอาไว้ เพื่อใช้สำหรับกำหนด spec ทั้ง Port, Adapter, Business Logic ว่า data ที่ใช้สื่อสารกันมีหน้าตาเป็นแบบไหน
ที่ไฟล์ order_service.go
สำหรับ Primary Port ก็จะมีหน้าตาประมาณนี้
package core
// Primary port
type OrderService interface {
CreateOrder(order Order) error
}
- Secondary Port (ส่วนที่จะต้องส่งต่อไปยังส่วนของ database) = เก็บไว้ที่
order_repository.go
โดย
- implement
OrderRepository
สำหรับ spec ข้อมูลสำหรับการรับข้อมูลเพื่อไป save ลง database (ซึ่งก็คือข้อมูล order)
ที่ไฟล์ order_repository.go
สำหรับ Secondary Port ก็จะมีหน้าตาประมาณนี้
package core
// Secondary port
type OrderRepository interface {
Save(order Order) error
}
2. Business Core logic
Structure ที่เกี่ยวข้องจะมี 1 file นี้
.
├── adapters --> สำหรับเก็บ adapter
│ ├── gorm_adapter.go
│ └── http_adapter.go
├── core --> สำหรับเก็บ business logic, port
│ ├── order.go
│ ├── order_repository.go
│ └── order_service.go
├── go.mod
├── go.sum
├── main.go