rest - 如何在 JSON 响应中过滤数据库中的字段?

标签 rest go json-api

我正在 golang 中制作一个 REST API,我想添加对过滤字段的支持,但我不知道实现它的最佳方法,假设我有一个代表 Album 模型的结构

type Album struct {
  ID            uint64    `json:"id"`
  User          uint64    `json:"user"`
  Name          string    `json:"name"`
  CreatedDate   time.Time `json:"createdDate"`
  Privacy       string    `json:"privacy"`
  Stars         int       `json:"stars"`
  PicturesCount int       `json:"picturesCount"`
}

和一个返回Album

实例的函数
func GetOne(id uint64, user uint64) (Album, error) {

  var album Album

  sql := `SELECT * FROM "album" WHERE "id" = $1 AND "user" = $2;`

  err := models.DB.QueryRow(sql, id, user).Scan(
    &album.ID,
    &album.User,
    &album.Name,
    &album.CreatedDate,
    &album.Privacy,
    &album.Stars,
    &album.PicturesCount,
  )

  return album, err

}

而客户要发出这样的请求
https://api.localhost.com/albums/1/?fields=id,name,privacy

撇开明显的安全问题不谈,我的第一个想法是使用类似这样的方法过滤数据库中的字段

func GetOne(id uint64, user uint64, fields string) {

  var album Album

  sql := fmt.Sprintf(`SELECT %s FROM "album" WHERE "id" = $1 AND "user" = $2;`, fields)

  // i don't know what to do after this

}

然后我想到将 omitempty 标记添加到所有字段并将字段设置为零值,然后再将其编码为 JSON,

  • 这行得通吗?
  • 哪种方法更好?
  • 有没有最好的方法?
  • 我将如何实现第一种方法?

谢谢。

最佳答案

对于您的第一个提案(仅查询请求的字段),有两种方法(回答“这行得通吗?”和“我将如何实现第一种方法?”):

  1. 动态创建一个(可能是匿名的)struct 并使用 encoding/json 从那里生成 JSON。
  2. 实现一个包装器,将从查询返回的 *database/sql.Rows 转换为 JSON。

对于方法 (1.),您将需要以某种方式为原始 struct 中的任意属性组合创建 struct。作为reflect cannot create a new struct type at runtime , 你唯一的机会就是 generate them at compile time .组合爆炸会使你的二进制文件膨胀,所以不要那样做。

方法(2.)要谨慎处理,只能作为最后的手段。获取请求的字段列表并使用从数据库中获得的值写出 JSON 听起来很简单,并且不涉及反射。但是,您的解决方案(很可能)比 encoding/json 不稳定得多。

在阅读您的问题时,我也考虑过使用 json:"omitempty" 结构标记。我认为这是更好的解决方案。它既不涉及元编程,也不涉及编写您自己的 JSON 编码器,这是一件好事。请注意在某些字段丢失的情况下的影响(客户端可能必须考虑到这一点)。您可以查询所有属性总是并使用反射覆盖不需要的属性。

最终,上述所有解决方案都不是最优的,最好的解决方案是根本不实现该功能。我希望你有充分的理由让属性可变,我很乐意根据你的解释进一步澄清我的答案。但是,如果资源的其中一个属性太大,它可能应该是一个子资源。

关于rest - 如何在 JSON 响应中过滤数据库中的字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37075779/

相关文章:

java - 如何仅获取 JSON 对象的 ID 列表?

json - 从 Grails RestfulController 索引/搜索操作渲染分页元数据

go - 如何从 gorilla mux.Router过滤一些路径

go - 如何在运行测试之前自动清理 Visual Code 中的 go 缓存?

python - 如何找到 JSON 列表中的哪一项对于 Python 中的给定属性具有最大值?

ruby-on-rails - Ember : Relationship link related data not loading/disappearing

javascript - 用于 RESTful PUT/DELETE 链接的 DRY jQuery

c# - 导入 CMS Open Payment API

struct - 在 Go 中使用结构进行原子比较和交换

node.js - 使用 JSON API Serializer 创建更复杂的 JSON