序列化

序列化程序提供干净的抽象来转换数据库结果。

AdonisJs 附带默认的 Vanilla Serializer ,但你可以自由创建和使用你的应用程序所需的任何序列化程序。

常见的序列化程序用法是根据 JSON:API 规范格式化数据。

介绍

通过 Lucid 模型进行的数据库查询返回可序列化的实例:

const User = use('App/Models/User')

const users = await User.all()

// users -> Vanilla Serializer instance

要将可序列化实例转换为普通数组/对象,请调用其 toJSON 方法:

const json = users.toJSON()

调用 toJSON 任何可序列化的实例都会返回准备好 JSON 输出的数据。

为何使用序列化器?

编写 API 服务器时,你不希望将未序列化的模型实例数据返回给用户。

Serializers 通过在需要时格式化模型数据来解决此问题。

假设一个 User 可以有很多 Post 关系:

const User = use('App/Models/User')

const users = await User
  .query()
  .with('posts')
  .fetch()

在上面的示例中, Lucid 加载所有 User 模型及其 Post 关系,但不会在此时格式化 JSON 的加载数据。

users 最后会调用 toJSON ,格式化数据的责任交给了 Vanilla 序列化:

// serialize the data
users.toJSON()
// 输出
[
  {
    id: 1,
    username: 'virk',
    posts: [
      {
        id: 1,
        user_id: 1,
        title: 'Adonis 101'
      }
    ]
  }
]

一个序列化执行所有 getters,setters 并 computed properties 返回格式化模型数据之前。

使用 Serializer

可以通过覆盖 Serializer 的 getter 方法来为每个模型定义序列化器:

class User extends Model {
  static get Serializer () {
    return // your own implementation
  }
}

Vanilla Serializer

Vanilla Serializer 执行以下操作:

  • 将每个模型记录旁边的所有关系附加为属性。

  • 将所有 sideloaded 数据附加到根 meta 键中,例如,给定用户的帖子计数表示如下:

{
  id: 1,
  username: 'virk',
  __meta__: {
    posts_count: 2
  }
}

格式分页结果:

{
  total: 10,
  perPage: 20,
  lastPage: 1,
  currentPage: 1,
  data: []
}

创建序列化程序

创建自己的序列化程序,以 AdonisJs 未提供的格式返回数据。

序列化程序 API 非常小,可以轻松添加新的序列化程序。

避免使用自定义序列化程序来修补 JSON 输出。相反,使用 getters 和 computed properties 。

API 概述

下面是自定义序列化程序的示例模板:

class CustomSerializer {
  constructor (rows, pages = null, isOne = false) {
    this.rows = rows
    this.pages = pages
    this.isOne = isOne
  }

  first () {
    return this.rows[0]
  }

  last () {
    return this.rows[this.rows.length - 1]
  }

  size () {
    return this.isOne ? 1 : this.rows.length
  }

  toJSON () {
    // return formatted data
  }
}

module.exports = CustomSerializer

创建自定义序列化程序后,将其绑定到 IoC 容器:

const { ioc } = require('@adonisjs/fold')

ioc.bind('MyApp/CustomSerializer', () => {
  return require('./app/Serializers/CustomSerializer')
})

绑定到容器后,为每个模型定义自定义序列化程序:

class User extends Model {
  static get Serializer () {
    return 'MyApp/CustomSerializer'
  }
}
最后一次更新: 7/3/2019, 11:00:54 PM