Response schemas and serialization
Serialization is turning a JavaScript object into a JSON string before sending it to the client. If you describe a response schema, Fastify builds the JSON from it: this is faster than the usual JSON.stringify and also protects against leaking fields that are not in the schema.
A response schema
Response schemas go in schema.response, separately for each status code. Suppose posts in src/routes/posts.js got an internal authorEmail field that clients should not see:
// src/routes/posts.js
const posts = [
{ id: 1, title: 'First post', body: 'Text', authorEmail: 'anna@example.com' },
];
const showSchema = {
params: {
type: 'object',
properties: { id: { type: 'integer' } },
},
response: {
200: {
type: 'object',
properties: {
id: { type: 'integer' },
title: { type: 'string' },
body: { type: 'string' },
},
},
},
};
app.get('/posts/:id', { schema: showSchema }, async (request) => {
return posts.find((post) => post.id === request.params.id);
});Open http://localhost:3000/posts/1 — the reply contains only id, title and body. The authorEmail field is dropped because it is not in the schema.
A list
For an array, set type: 'array' and the item schema in items:
// src/routes/posts.js
const listSchema = {
response: {
200: {
type: 'array',
items: {
type: 'object',
properties: {
id: { type: 'integer' },
title: { type: 'string' },
},
},
},
},
};
app.get('/posts', { schema: listSchema }, async () => posts);The /posts list now returns only id and title — post texts are needed only on the single-post page.
Shared schemas
To avoid repeating the post description in every route, register it once with addSchema and an $id. Add this to src/app.js before the routes are registered:
// src/app.js
app.addSchema({
$id: 'post',
type: 'object',
properties: {
id: { type: 'integer' },
title: { type: 'string' },
body: { type: 'string' },
},
});Now routes can refer to it with $ref:
// src/routes/posts.js
const showSchema = {
response: {
200: { $ref: 'post#' },
},
};The reply is the same, and the post description lives in one place.
Several codes
Key in response | When it is used |
|---|---|
200 | A successful reply |
201 | A reply after creating |
'4xx' | Any client error |
default | All other codes |
Common mistake
A new field that you added to the data but forgot in the response schema silently disappears from the JSON. If, for example, createdAt vanished from the reply without any error, check schema.response first.