documentation/guides/mock-server/data-seeding.md
The x-seed extension allows you to automatically populate initial data when the mock server starts. This is perfect for having realistic test data available immediately without manual setup.
Use x-seed when you need:
The seed helper provides a Laravel-inspired API for creating data. It automatically uses the schema key as the collection name.
seed.count(n, factory) - Create Multiple ItemsCreate n items using a factory function:
components:
schemas:
Post:
type: object
properties:
id: { type: string }
title: { type: string }
content: { type: string }
author: { type: string }
publishedAt: { type: string, format: date-time }
x-seed: |
seed.count(5, () => ({
id: faker.string.uuid(),
title: faker.lorem.sentence(),
content: faker.lorem.paragraphs(3),
author: faker.person.fullName(),
publishedAt: faker.date.past().toISOString()
}))
seed(array) - Create from ArrayCreate items from an array of objects:
components:
schemas:
Post:
type: object
x-seed: |
seed([
{
id: '1',
title: 'Getting Started with Scalar',
content: 'Learn how to use Scalar...',
author: 'Jane Doe'
},
{
id: '2',
title: 'Advanced API Documentation',
content: 'Take your docs to the next level...',
author: 'John Smith'
}
])
seed(factory) - Create Single ItemCreate a single item using a factory function (shorthand for seed.count(1, factory)):
components:
schemas:
Post:
type: object
x-seed: |
seed(() => ({
id: faker.string.uuid(),
title: faker.lorem.sentence(),
content: faker.lorem.paragraphs(2),
author: faker.person.fullName(),
publishedAt: new Date().toISOString()
}))
When writing x-seed code, you have access to:
store: The same store helper as x-handler (for advanced use cases)faker: Faker.js for generating realistic dataseed: The seed helper function (described above)schema: The schema key name (useful for debugging)Here's a complete example that combines x-seed for initial data and x-handler for endpoints:
openapi: 3.1.0
info:
title: Blog API
version: 1.0.0
paths:
/posts:
get:
summary: List all posts
operationId: listPosts
x-handler: |
return store.list('Post')
responses:
'200':
description: List of posts
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Post'
post:
summary: Create a new post
operationId: createPost
x-handler: |
return store.create('Post', {
id: faker.string.uuid(),
...req.body,
createdAt: new Date().toISOString()
})
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/NewPost'
responses:
'201':
description: Post created
content:
application/json:
schema:
$ref: '#/components/schemas/Post'
components:
schemas:
Post:
type: object
properties:
id:
type: string
title:
type: string
content:
type: string
author:
type: string
publishedAt:
type: string
format: date-time
createdAt:
type: string
format: date-time
x-seed: |
seed.count(10, () => ({
id: faker.string.uuid(),
title: faker.lorem.sentence(),
content: faker.lorem.paragraphs(4),
author: faker.person.fullName(),
publishedAt: faker.date.past().toISOString(),
createdAt: faker.date.past().toISOString()
}))
NewPost:
type: object
required:
- title
- content
properties:
title:
type: string
content:
type: string
author:
type: string
When the server starts, it will automatically create 10 blog posts. You can immediately call GET /posts to see them.
You can seed multiple collections by adding x-seed to multiple schemas:
components:
schemas:
Post:
type: object
x-seed: |
seed.count(5, () => ({
id: faker.string.uuid(),
title: faker.lorem.sentence(),
content: faker.lorem.paragraphs(3)
}))
Author:
type: object
x-seed: |
seed.count(3, () => ({
id: faker.string.uuid(),
name: faker.person.fullName(),
email: faker.internet.email(),
bio: faker.person.bio()
}))
Category:
type: object
x-seed: |
seed([
{ id: '1', name: 'Technology' },
{ id: '2', name: 'Design' },
{ id: '3', name: 'Business' }
])
Each schema seeds independently, and all collections are populated when the server starts.
The seed code only runs if the collection is empty. This means:
This prevents duplicate data and ensures consistent behavior. If you need to reseed, you can clear the collection using store.clear('Post') in an x-handler endpoint, or restart the server after clearing.
x-seed for initial data and x-handler for CRUD operationsPost:
type: object
x-seed: |
// First create authors
const authors = seed.count(3, () => ({
id: faker.string.uuid(),
name: faker.person.fullName()
}))
// Then create posts with author references
seed.count(10, () => ({
id: faker.string.uuid(),
title: faker.lorem.sentence(),
authorId: faker.helpers.arrayElement(authors).id
}))
Post:
type: object
x-seed: |
seed.count(10, () => {
const isPublished = faker.datatype.boolean()
return {
id: faker.string.uuid(),
title: faker.lorem.sentence(),
content: faker.lorem.paragraphs(3),
published: isPublished,
publishedAt: isPublished ? faker.date.past().toISOString() : null
}
})