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)