Requirement scenarios:

Article list interface: /articles interface required fields: article ID, article title, article image

/articles/id interface required fields: id, title, image, article

Technical selection: Model transformation function uses COPier

package model

type Article struct {
   ID int
   Title string
   ImageUrl string
   Content string
}

package response

type Article struct {
   ID int `json:"id"`
   Title string `json:"title"`
   ImageUrl string `json:"imageUrl"`
   Content string `json:"content"`
}

type Article struct {}

func (ctr *Article) List(c *gin.Context) {
   articles := []*model.Article {
      {ID:1, Title: "Heading 1", Content: Content of "1", ImageUrl: "1.jpg"},
      {ID:2, Title: "Heading 2", Content: "Content 2", ImageUrl: "2.jpg"}},var response []*response.Article
   copier.Copy(&response, articles)
   c.JSON(http.StatusOK, gin.H{"data": response})

}

func (ctr *Article) Detail(c *gin.Context) {
   article := &model.Article{ID:1, Title: "Heading 1", Content: Content of "1", ImageUrl: "1.jpg"}

   var response response.Article
   copier.Copy(&response, article)
   c.JSON(http.StatusOK, gin.H{"data": response})
}

Copy the code

The code implementation above causes the article details of the article list interface to be displayed as well.

In the project development, you must encounter such scenarios, the same model this interface needs all the data fields, another interface only needs part of the data fields, and some scenarios some data fields are sensitive, can only be shown to some interfaces; The more violent way is to establish a corresponding response model for each interface, which is very common in Java development, so is there a better solution in Go language development?

There are many articles on the web that explain how to hide fields in various ways, as follows:

A:type ArticleList struct {
   Article
   Content string `json:"-"`} return the following result, content field is empty, not hidden {"data": [{"id": 1."title": "Heading 1"."imageUrl": "1.jpg"."content": ""
    },
    {
      "id": 2."title": "Heading 2"."imageUrl": "2.jpg"."content": ""}} Mode 2:type Omit *struct{}

type ArticleList struct {
   Article
   Content Omit `json:"content,omitempty"`} return the following result: the content field becomes a JSON object, not hidden, omitEmpty zero value hidden {"data": [{"id": 1."title": "Heading 1"."imageUrl": "1.jpg"."content": {}}, {"id": 2."title": "Heading 2"."imageUrl": "2.jpg"."content": {}}]}Copy the code

It took a long time to solve this problem. At the beginning, it also imitated The Java way, establishing the corresponding response model for each interface. Later, I accidentally found a relatively simple method to hide fields elegantly, with the code as follows:

type ArticleList struct {
   Article
   Content string `json:"content,omitempty" copier:"-"`
}
Copy the code

Implementation principle: Copier model transformation will ignore the label “-” of the field, resulting in the target field is zero value, and then through omitEmpty zero value hidden, so as to realize the object field hiding.

How to implement compound structure field hiding, the code is as follows:

package model

type Article struct {
   ID int
   Title string
   ImageUrl string
   Content string

   Author *Author
}

package model

type Author struct {
   ID int
   Name string
   Desc string
}

package response

type Author struct {
   ID int `json:"id"`
   Name string `json:"name"`
   Desc string `json:"desc"`
}

type ArticleListAuthor struct {
   Author
   Desc string `json:"desc,omitempty" copier:"-"`
}

package response

type Article struct {
   ID int `json:"id"`
   Title string `json:"title"`
   ImageUrl string `json:"imageUrl"`
   Content string `json:"content"`

}

type ArticleList struct {
   Article
   Content string `json:"content,omitempty" copier:"-"`
   
   ArticleListAuthor `json:"author"`
}
Copy the code

Source link

In the process of project development, there is no need to be so rigid. If a model has many attributes, only two or three fields need to be displayed to the public. Most of the attributes need to be hidden in the above way.