跳到内容
Sutando
Esc
↑↓导航↵打开⌘J预览
本页内容

序列化

将模型与关联转换为数组或 JSON,并通过 hidden、visible 等属性控制序列化时包含哪些字段,便于构建干净、稳定的 API 响应。

构建 JSON API 时,经常需要把模型和关联转化为对象或 JSON。针对这些操作,Sutando 提供了一些便捷方法,以及对序列化中的属性控制。

序列化模型 & 集合

序列化为对象

要转化模型及其加载的关联为对象,可以使用 toData 方法。这是一个递归的方法,因此所有的属性和关联(包括关联的关联)都将转化成数组:

const user = await User.query().with('roles').first();

return user.toData();

attributesToData 方法可用于将模型的属性转换为对象,但不会转换其关联:

const user = await User.query().first();
 
return user.attributesToData();

你还可以通过调用集合实例上的 toData 方法,将模型的全部集合转换为对象:

const users = await User.query().all();
 
return users.toData();

序列化为 JSON

方法 toJson 可以把模型转化成 JSON。和方法 toData 一样, toJson 方法也是递归的,因此所有属性和关联都会转化成 JSON, 你还可以指定由 Javascript 支持的 JSON 选项:

const user = await User.query().find(1);
 
return user.toJson();
 
return user.toJson(null, 2);

或者,你也可以将模型或集合转换为字符串,模型或集合上的 toJson 方法会自动调用:

const user = await User.query().find(1);

return String(user);

return JSON.stringify(user);

由于模型和集合在转化为字符串的时候会转成 JSON, 因此可以把 Sutando 对象直接从路由返回。Sutando 会把模型和集合序列化为 JSON,c.json() 原样输出即可:

import { Hono } from 'hono';

const app = new Hono();

app.get('/', async (c) => {
  const user = await User.query().find(1);

  return c.json(user);
});

关联关系

当一个模型被转化为 JSON 的时候,它加载的关联关系也将自动转化为 JSON 对象被包含进来。同时,通过「小驼峰」定义的关联方法,关联的 JSON 属性将会是「蛇形」命名。

隐藏 JSON 属性

有时要将模型对象或 JSON 中的某些属性进行隐藏,比如密码。则可以在模型中添加 hidden 属性。模型序列化后,hidden 数组中列出的属性将不会被显示:

import { Model } from 'sutando';

class User extends Model {
  hidden = ['password'];
}

此外,也可以使用属性 visible 定义一个模型数组和 JSON 可见的「白名单」。转化后的数组或 JSON 不会出现其他的属性:

import { Model } from 'sutando';

class User extends Model {
  visible = ['first_name', 'last_name'];
}

临时修改可见属性

如果你想要在一个模型实例中显示隐藏的属性,你可以使用 makeVisible 方法。makeVisible 方法返回模型实例:

user.makeVisible('attribute').toData();

user.makeVisible(['attribute', 'another_attribute']).toData();

相应地,如果你想要在一个模型实例中隐藏可见的属性,你可以使用 makeHidden 方法。

user.makeHidden('attribute').toData();

user.makeHidden(['attribute', 'another_attribute']).toData();

如果你想临时覆盖所有可见或隐藏的属性,你可以分别使用 setVisible 和 setHidden 方法:

user.setVisible(['id', 'name']).toData();

user.setHidden(['email', 'password', 'remember_token']).toData();

追加 JSON 值

有时,需要在模型转换为对象或 JSON 时添加一些数据库中不存在字段的对应属性。要实现这个功能,首先要定义一个访问器:

import { Model, Attribute } from 'sutando';

class User extends Model {
  attributeIsAdmin() {
    return Attribute.make({
      get: (value, attributes) => (attributes.admin === 'yes')
    });
  }
}

然后,在模型属性 appends 中添加该属性名。注意,尽管访问器使用「驼峰命名法」方式定义,但是属性名通常以「蛇形命名法」的方式来引用:

import { Model } from 'sutando';

class User extends Model {
  appends = ['is_admin'];
}

使用 appends 方法追加属性后,它将包含在模型的对象和 JSON 中。appends 数组中的属性也将遵循模型上配置的 visible 和 hidden 设置。

运行时追加

你可以在单个模型实例上使用 append 方法来追加属性。或者,使用 setAppends 方法来重写整个追加属性的数组:

user.append('is_admin').toData();
 
user.setAppends(['is_admin']).toData();

这个页面有帮助吗?