const User = use('App/Models/User')
const users = await User.all()
// users -> Vanilla Serializer instance
You are viewing the legacy version of AdonisJS. Visit https://adonisjs.com for newer docs. This version will receive security patches until the end of 2021.
Serializers provides clean abstractions towards structuring the database results. AdonisJs by default ships with a Vanilla serializer, but you are free to create/use other serializers too.
For example: You can create a serializer to format data as per jsonapi specs.
Every time you make a database query using Lucid models, the return value is always a serializer instance and calling toJSON
to it returns a formatted output.
const User = use('App/Models/User')
const users = await User.all()
// users -> Vanilla Serializer instance
The users
object is an instance of Vanilla serializer and in order to get a plain array/object from it, you need to call toJSON()
method.
const json = users.toJSON()
When writing an API server, the data returned from models is not something that you want to return back and instead follow some conventions to structure the data.
The serializer solves that problem by giving the freedom to format the data as you want. For example
const User = use('App/Models/User')
const users = await User
.query()
.with('posts')
.fetch()
At this point Lucid loads all the users and their posts, but doesn’t care on how to present them in JSON format, but instead pass all the data to the serializer, which can be accessed from users
constant.
Now when you call toJSON
on users
. The vanilla serializer formats the data as follows.
users.toJSON()
// output
[
{
id: 1,
username: 'virk',
posts: [
{
id: 1,
user_id: 1,
title: 'Adonis 101'
}
]
}
]
Also, it executes all the getters
, setters
and computed properties
for you.
The serializers can be defined on each model by overriding the Serializer
getter.
class User extends Model {
static get Serializer () {
return // your own implementation
}
}
Here is the list of operations vanilla serializer performs for you.
Attach all relations next to the row as a property.
Attach all sideloaded
data to the __meta__
key. For example posts counts for a given user are represented as
{
id: 1,
username: 'virk',
__meta__: {
posts_count: 2
}
}
Format pagination results as.
{
total: 10,
perPage: 20,
lastPage: 1,
currentPage: 1,
data: []
}
You can create your serializer to get data back in your desired format. Intentionally the API of serializers is pretty small, to make it easier to add and use new serializers.
Serializers should not be created for small amendments to the output, use getters and computed properties for that.
|
Below is the list of methods, which are required on a serializer.
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
Once done, you can import this serializer manually using require
statement or bind it to the IoC container.
const { ioc } = require('@adonisjs/fold')
ioc.bind('MyApp/CustomSerializer', () => {
return require('./CustomSerializer')
})
Use it as
class User extends Model {
static get Serializer () {
return 'MyApp/CustomSerializer'
}
}