Hi guys, I’m a Front-End developer. Before there was a time 2 years working CMS Magento, I like CMS Magento because system clean, and architecture database EAV (Entity — Attribute — Value) but I don’t understand why present I’m dev front-end (I don’t know) in the 2-year current. And present I chance comeback working position Back-End that I like.
I’ve read some articles following:
If you have read through the article Uncle bob, he said that: > Each has at least one layer for business rules, and another for interfaces.
So, each of these architectures produce systems that are:
More at https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html
In architecture of Uncle Bob divide 4 layers:
In my project divide layers:
Models:
Models is same as entites. It set of data struct, interface and method, functions. Example model: Book
import (
"context"
)
// Book ...
type Book struct {
ID uint `json:"id" gorm:"primary_key"`
Title string `json:"title"`
Author string `json:"author"`
}
type BookUsecase interface {
Fetch(ctx context.Context) ([]Book, error)
GetByID(ctx context.Context, id string) (Book, error)
}
type BookRepository interface {
Fetch(ctx context.Context) (res []Book, err error)
GetByID(ctx context.Context, id string) (Book, error)
}
Usecase:
This a layer will handle problem logic business. This a layer decide repository will use. And have responsibility to provide data to layer delivery use.Layer Usecase a depends layer Repository
import (
"context"
"github.com/working/project/domain"
)
type bookUsecase struct {
bookRepo domain.BookRepository
}
// NewArticleUsecase will create new an articleUsecase object representation of domain.ArticleUsecase interface
func NewBookUsecase(a domain.BookRepository) domain.BookUsecase {
return &bookUsecase{
bookRepo: a,
}
}
func (a *bookUsecase) Fetch(c context.Context) (res []domain.Book, err error) {
res, err = a.bookRepo.Fetch(c)
if err != nil {
return nil, err
}
return
}
func (a *bookUsecase) GetByID(c context.Context, id string) (res domain.Book, err error) {
res, err = a.bookRepo.GetByID(c, id)
return
}
Repository:
This a layer will handle to database method: fetch, put, delete, get, etc.Layer responsibility will choose DB use in application. Could be Mysql, Postgresql, MongoDB, MariaDB, etc
import (
"context"
"github.com/jinzhu/gorm"
"github.com/working/project/domain"
)
type psqlBookRepository struct {
Conn *gorm.DB
}
// NewMysqlArticleRepository will create an object that represent the article.Repository interface
func NewPsqlBookRepository(Conn *gorm.DB) domain.BookRepository {
return &psqlBookRepository{Conn}
}
func (m *psqlBookRepository) Fetch(ctx context.Context) (res []domain.Book, err error) {
var books []domain.Book
m.Conn.Find(&books)
return books, nil
}
func (m *psqlBookRepository) GetByID(ctx context.Context, id string) (res domain.Book, err error) {
var book domain.Book
m.Conn.Where("id = ?", id).First(&book)
return book, nil
}
Deliver:
This a layer will decide how the data present. Could be REST API, HTML, or gRPC whatever the decide type.This a lay accept the input from user and send layer Usecase handle logic
import (
"github.com/gin-gonic/gin"
"github.com/working/project/domain"
)
type BookeHandler struct {
BookUsecase domain.BookUsecase
}
func NewBooksHandler(r *gin.RouterGroup, us domain.BookUsecase) {
handler := &BookeHandler{
BookUsecase: us,
}
r.GET("/books", handler.FindBooks)
// r.POST("/books", handler.CreateBook) // create
r.GET("/books/:id", handler.FindBook) // find by id
// r.PATCH("/books/:id", handler.UpdateBook) // update by id
// r.DELETE("/books/:id", handler.DeleteBook) // delete by id
}
func (a *BookeHandler) FindBooks(c *gin.Context) {
books, _ := a.BookUsecase.Fetch(c.Request.Context())
c.JSON(200, gin.H{"data": books})
}
func (a *BookeHandler) FindBook(c *gin.Context) {
books, _ := a.BookUsecase.GetByID(c.Request.Context(), c.Param("id"))
c.JSON(200, gin.H{"data": books})
}
Current my project building on based 4 layers: Model, Usecase, Repository, and Delivery which I present above. And my project interview, I think it not good. I will rebuild the architecture project in article next.
You should understand architecture someone and accept it in a project of you. That will give you look good and remember to start with it simple
Link Project: https://github.com/caohoangnam/go-clean-architecture
Tech stack using:
If you have a question , or need more explanation, or something, that I can not explain well here, you can ask me from my linkedin or email me. Thank you so much.