Functional Mocks
You can write JSON mocks in JavaScript or TypeScript
Node 22.18+ or 23.6+ support TypeScript by default.
Option A: An Object, Array, or String is sent as JSON
api/foo.GET.200.js
export default { foo: 'bar' }
Option B: Function Mocks
Return a string | Buffer | Uint8Array,
but don’t call response.end().
export default (request, response) =>
JSON.stringify({ foo: 'bar' })
async functions are supported.
Custom HTTP Handlers
For example, you can intercept requests to write to a database. Or act based on
some query string value, etc. In summary, you get Node’s request,
response as arguments, so you can think of Mockaton as a
router, but in the handlers you return, instead of ending the response.
Examples
Imagine you have an initial list of colors, and you want to concatenate newly added colors.
api/colors.POST.201.js
import { parseJSON } from 'mockaton'
export default async function insertColor(request, response) {
const color = await parseJSON(request)
globalThis.newColorsDatabase ??= []
globalThis.newColorsDatabase.push(color)
// These two lines are not needed but you can change their values
// response.statusCode = 201 // default derived from filename
// response.setHeader('Content-Type', 'application/json') // unconditional default
return JSON.stringify({ msg: 'CREATED' })
}
api/colors.GET.200.js
import colorsFixture from './colors.json' with { type: 'json' }
export default function listColors() {
return JSON.stringify([
...colorsFixture,
...(globalThis.newColorsDatabase || [])
])
}
What if I need to serve a static .js or .ts?
Option A: Put it in your config.staticDir without the .GET.200.js extension.
Mocks in staticDir take precedence over mocksDir/*.
Option B: Read it and return it. For example:
import { readFileSync } from 'node:fs'
export default function (_, response) {
response.setHeader('Content-Type', 'application/javascript')
return readFileSync('./some-dir/foo.js', 'utf8')
}