As implement hexagonal pattern (Ports and adapters pattern), our code should separate to three sections
- API (Application Programming Interface) such your inbound (Gin, Echo, Fiber ...), Serialization or something else
- Domain, Entity or something else that make your app unique
- SPI (Service Programming Interface) such as external service, DB, DAO (Data Access Object) or something else
Example with below code, This will show relation with My Entity (Todo) and SPI(Database Insert)
- Entity -> Todo struct
- Port -> TodoHandler
- Adapters -> todoAdapter interface, MySQLDB and MongoDB struct
package main
import (
"log"
"go.mongodb.org/mongo-driver/mongo"
"gorm.io/gorm"
)
type Todo struct {
ID string
Title string
Description string
}
type todoAdapter interface {
Create(*Todo) error
}
type TodoHandler struct {
adapter todoAdapter
}
type MySQLDB struct {
db *gorm.DB
}
type MongoDB struct {
db *mongo.Collection
}
func NewTodoHandler(adapter todoAdapter) *TodoHandler {
return &TodoHandler{adapter: adapter}
}
func (db *MySQLDB) Create(todo *Todo) error {
log.Println("🐟 MySQL Create Interface")
// in real example, you can comment out below code
// err := db.db.Create(todo)
// return err
return nil
}
func NewMySQLDB(db *gorm.DB) *MySQLDB {
return &MySQLDB{db: db}
}
func (db *MongoDB) Create(todo *Todo) error {
log.Println("✅ MongoDB Create Interface")
// in real example, you can comment out below code
// _, err := db.db.InsertOne(context.TODO(), todo)
// return err
return nil
}
func NewMongoDB(db *mongo.Collection) *MongoDB {
return &MongoDB{db: db}
}
func main() {
var todoHandler *TodoHandler
// Todo insert with MySQL
mysqlAdapter := NewMySQLDB(&gorm.DB{})
todoHandler = NewTodoHandler(mysqlAdapter)
todoHandler.adapter.Create(&Todo{
ID: "1", Title: "New note", Description: "Save in mysql",
})
// Todo insert with MongoDB
mongoAdapter := NewMongoDB(&mongo.Collection{})
todoHandler = NewTodoHandler(mongoAdapter)
todoHandler.adapter.Create(&Todo{
ID: "1", Title: "New note", Description: "Save in mongo",
})
}
In the example, you will see two adapters should implement Create method to related with adapter interface
And result will be like this
2022/03/06 15:35:46 🐟 MySQL Create Interface
2022/03/06 15:35:46 ✅ MongoDB Create Interface
Top comments (0)