Request model, Domain model and Response model have appeared in the previous paper. In this paper, DO model and Repository layer will be added, and the project structure has been in embryonic form.

Alibaba Java Development Manual Hierarchical Domain model specification:

Query: Data Query object. Each layer receives Query requests from the upper layer. Note that query encapsulation with more than two parameters is prohibited by using the Map class for transmission. Data Transfer Object (DTO) : a Data Transfer Object that is transmitted by the Service or Manager. Business Object (BO) : a Business Object that encapsulates Business logic and can be output by the Service layer. Data Object (DO) : This Object corresponds to the database table structure one by one and transmits Data source objects up through the DAO layer. VO (View Object) : Display layer objects, usually transmitted by the Web to the template rendering engine layer. (Ignored in this article)Copy the code

Corresponding model:

request => Query 
response => DTO 
domain => BO 
do => DO 
Copy the code

Here are a few examples of how each model can navigate and map across code layers

Case 1: Getting order details (single object)
package controller

func (ctr *Order) Get(c *gin.Context) {

   var request request.OrderGet
   iferr := c.ShouldB(&request); err ! =nil {
      c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
      return
   }

   order := ctr.repo.Get(c.Request.Context(), request.ID)

   response := new(response.Order)
   mapper.Map(&response, order)
   c.JSON(http.StatusOK, gin.H{"data": response})
}
--------------------------------------------------------------------------------
package repository

func (repo *Order) Get(ctx context.Context, id int) *domain.Order {
   order := &do.Order{ID: 1, UserID: 1, SN: "123456", CreateTime: time.Now()}

   domain := new(domain.Order)
   mapper.Map(&domain, order)
   return domain
}
Copy the code
Case 2: Get order list (object array)
package controller

func (ctr *Order) My(c *gin.Context) {

   orders := ctr.repo.My(c.Request.Context())

   response := []*response.Order{}
   mapper.Map(&response, orders)
   c.JSON(http.StatusOK, gin.H{"data": response})
}
--------------------------------------------------------------------------------
package repository

func (repo *Order) My(ctx context.Context) []*domain.Order {
   orders := []*do.Order{
      {ID: 1, UserID: 1, SN: "123456", CreateTime: time.Now()},
      {ID: 2, UserID: 1, SN: "987654", CreateTime: time.Now()},
   }

   domains := []*domain.Order{}
   mapper.Map(&domains, orders)
   return domains
}

Copy the code

Case 3: Get order list (query parameter + object array)
package controller

func (ctr *Order) List(c *gin.Context) {

   request := new(request.OrderList)
   iferr := c.ShouldB(&request); err ! =nil {
      c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
      return
   }

   orders := ctr.repo.List(c.Request.Context(), request)

   response := []*response.Order{}
   mapper.Map(&response, orders)
   c.JSON(http.StatusOK, gin.H{"data": response})
}

--------------------------------------------------------------------------------
package repository

func (repo *Order) List(ctx context.Context, request *request.OrderList)[] *domain.Order {
   fmt.Println(request)

   orders := []*do.Order{
      {ID: 1, UserID: 1, SN: "123456", CreateTime: time.Now()},
      {ID: 2, UserID: 1, SN: "987654", CreateTime: time.Now()},
   }

   domains := []*domain.Order{}
   mapper.Map(&domains, orders)
   return domains
}
Copy the code

Case 4: User registration
package controller

func (ctr *User) Register(c *gin.Context) {
   var request request.UserRegister
   iferr := c.ShouldB(&request); err ! =nil {
      c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
      return
   }

   user := new(domain.User)
   user.Register(request.Mobile, request.Password)

   data := ctr.repo.Register(c.Request.Context(), user)

   response := new(response.User)
   mapper.Map(&response, data)
   c.JSON(http.StatusOK, gin.H{"data": response})
}

--------------------------------------------------------------------------------
package domain

type NicknameS struct {}

func (dom *NicknameS) generate(str string) string {
   return str[0:4] + "* * * *" + str[8:11]}type PasswordS struct {}

func (dom *PasswordS) generate(str string) string {
   str += dom.salt()
   h := md5.New()
   h.Write([]byte(str))
   return hex.EncodeToString(h.Sum(nil))}func (dom *PasswordS) salt(a) string {
   return "~! @#abc123"
}

type User struct {
   ID          int
   Mobile      string
   Nickname    string
   NicknameS    *NicknameS
   Password    string
   PasswordS    *PasswordS
   HeaderImage string
   Money       int
   CreateTime time.Time
}

func (dom *User) Register(mobile string, password string) {
   dom.Mobile = mobile
   dom.Nickname = dom.NicknameS.generate(mobile)
   dom.Password = dom.PasswordS.generate(password)
   dom.CreateTime = time.Now()
   dom.HeaderImage = dom.DefaultHeaderImage()
}

func (dom *User) DefaultHeaderImage(a) string {
   return "header.jpg"} -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --package repository

func (repo *User) Register(ctx context.Context, user *domain.User) *domain.User {

   do := new(do.User)
   do.ID = 1
   do.Mobile = user.Mobile
   do.Password = user.Password
   do.HeaderImage = user.HeaderImage
   do.CreateTime = user.CreateTime
   // do objects into the library

   domain := new(domain.User)
   mapper.Map(&domain, do)
   return domain
}
Copy the code