Go语言高效率Web开发二:如何优雅的对外隐藏数据字段

需求场景:

文章列表接口: /articles
接口所需字段:文章id、文章标题、文章图片

文章详情接口: /articles/id
接口所需字段:文章id、文章标题、文章图片、文章详情
代码实现:

技术选型:模型转换函数使用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: "标题1", Content: "内容1", ImageUrl: "1.jpg"},
      {ID:2, Title: "标题2", 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: "标题1", Content: "内容1", ImageUrl: "1.jpg"}

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

复制代码

以上代码实现方式会导致文章列表接口的文章详情也会对外展示。

在项目开发中,你一定遇到这种场景,同样的模型这个接口需要全部数据字段,另外的接口只需要部分数据字段,还有的场景有些数据字段比较敏感,只能对某些接口展示;比较暴力的方式就是每一个接口建立对应的response模型,这种方式在Java开发中非常常见,那么在Go语言开发中有没有更好的解决方式呢?

网上有很多文章介绍有多种方式如何隐藏字段,如下:

方式一:
type ArticleList struct {
   Article
   Content string `json:"-"`
}
返回结果如下,content字段只是为空,不隐藏
{
  "data": [
    {
      "id": 1,
      "title": "标题1",
      "imageUrl": "1.jpg",
      "content": ""
    },
    {
      "id": 2,
      "title": "标题2",
      "imageUrl": "2.jpg",
      "content": ""
    }
  ]
}

方式二:
type Omit *struct{}

type ArticleList struct {
   Article
   Content Omit `json:"content,omitempty"`
}

返回结果如下,content字段变成了json对象,不隐藏,omitempty零值隐藏
{
  "data": [
    {
      "id": 1,
      "title": "标题1",
      "imageUrl": "1.jpg",
      "content": {}
    },
    {
      "id": 2,
      "title": "标题2",
      "imageUrl": "2.jpg",
      "content": {}
    }
  ]
}
复制代码

解决这个问题也经历了很长时间,刚开始也是模仿java的方式,每一个接口建立对应的response模型,后来无意间发现了比较简单的方法可以优雅的隐藏字段,代码如下:

type ArticleList struct {
   Article
   Content string `json:"content,omitempty" copier:"-"`
}
复制代码

实现原理:copier模型转换会忽略标签"-"的字段,导致目标字段为零值,再通过omitempty零值隐藏,从而实现对象字段隐藏.

如何实现复合结构体的字段隐藏,代码如下:

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"`
}
复制代码

源码链接

项目开发过程中,不需要这么死板,如果一个模型有很多属性,只需要对外展示两三个字段,用上述方式需要隐藏大多数属性,还不如直接建立一个新的模型,只包含所需要对外展示的少数字段,灵活度大家自己把握。

猜你喜欢

转载自juejin.im/post/7041544953394102285
今日推荐