![require(esm) Backported to Node.js 20, Paving the Way for ESM-Only Packages](https://cdn.sanity.io/images/cgdhsj6q/production/be8ab80c8efa5907bc341c6fefe9aa20d239d890-1600x1097.png?w=400&fit=max&auto=format)
Security News
require(esm) Backported to Node.js 20, Paving the Way for ESM-Only Packages
require(esm) backported to Node.js 20, easing the transition to ESM-only packages and reducing complexity for developers as Node 18 nears end-of-life.
mock-config-server
Advanced tools
Tool that easily and quickly imitates server operation, create full fake api in few steps
tool that easily and quickly imitates server operation, create full fake api in few steps
$ npm i mock-config-server --save --dev
# or
$ yarn add mock-config-server --dev
π Mock Config Server it is a tool that, easily, quickly simulates the work of a server. The main difference from solutions such as json-server and mock-service-worker is the ease of filling in data and flexible emulation of any and usual cases. Our goal is to create a simple and flexible system for users, with the help of which they can create, test, and support their products.
Install π Mock Config Server with npm or yarn
$ npm i mock-config-server --save --dev
# or
$ yarn add mock-config-server --dev
Create a mock-server.config.js
file with server configuration
/** @type {import('mock-config-server').FlatMockServerConfig} */
const flatMockServerConfig = [
{
baseUrl: '/api'
},
{
configs: [
{
path: '/user',
method: 'get',
routes: [{ data: { emoji: 'π¦', name: 'Nursultan' } }]
}
]
}
];
export default flatMockServerConfig;
Start π Mock Config Server
$ npx mock-config-server
If the package is already installed you can use short command
mcs
staticPath?
{StaticPath} entity for working with static files, readinterceptors?
{Interceptors} functions to change request or response parameters, readcors?
{Cors} CORS settings object (default: CORS is turn off
), readport?
{number} server port (default: 31299
)baseUrl?
{string} part of the url that will be substituted at the beginning of the request url (default: '/'
)database?
Database config for mock requests read
data
{Object | string} initial data for databaseroutes?
{Object | string} map of custom routes for databasename
{string} name of componentbaseUrl?
{string} part of the url that will be substituted at the beginning of rest request url (default: '/'
)configs
{Array<RestRequestConfig | GraphQLRequestConfig>} configs for mock requests, read
interceptors?
{Interceptors} functions to change request or response parameters, readConfigs are the fundamental part of the mock server. These configs are easy to fill and maintain. Config entities is an object with which you can emulate various application behaviors. You can specify headers
| cookies
| query
| params
| body
for Rest request or headers
| cookies
| query
| variables
for GraphQL request to define what contract data you need to get. Using this mechanism, you can easily simulate the operation of the server and emulate various cases
Every route must be configured to handle response content in one of three ways: data or queue or file.
path
string | RegExp
request pathmethod
'get' | 'post' | 'delete' | 'put' | 'patch' | 'options'
rest api methodroutes
RestRouteConfig[]
request routes
data?
any
mock data of requestqueue?
Array<{ time?: number; data: any}>
queue for polling with opportunity to set time for each responsefile?
string
path to file for return in responsesettings?
Settings
settings for route (polling on/off, etc.)entities?
Object<headers | cookies | query | params | body>
object that helps in data retrievalinterceptors?
Interceptors
functions to change request or response parameters, readinterceptors?
Interceptors
functions to change request or response parameters, read/** @type {import('mock-config-server').FlatMockServerConfig} */
const flatMockServerConfig = [
{
baseUrl: '/api'
},
{
configs: [
{
path: '/user',
method: 'get',
routes: [
{
entities: {
headers: { 'name-header': 'Nursultan' }
},
data: { emoji: 'π¦', name: 'Nursultan' }
},
{
entities: {
headers: { 'name-header': 'Dmitriy' }
},
data: { emoji: 'β', name: 'Dmitriy' }
}
]
}
]
}
];
export default flatMockServerConfig;
Now you can make a request with an additional header and get the desired result
fetch('http://localhost:31299/api/user', {
headers: {
'name-header': 'Nursultan',
'Content-Type': 'application/json'
}
})
.then((response) => response.json())
.then((data) => console.log(data)); // { emoji: 'π¦', name: 'Nursultan' }
Every route must be configured to handle response content in one of two ways: data or queue.
operationType
query | mutation
graphql operation typeoperationName?
string | RegExp
graphql operation namequery?
: string
graphql query as stringroutes
GraphQLRouteConfig[]
request routes
data?
any
mock data of requestqueue?
Array<{ time?: number; data: any}>
queue for polling with opportunity to set time for each responsesettings?
Settings
settings for route (polling on/off, etc.)entities?
Object<headers | cookies | query | variables>
object that helps in data retrievalinterceptors?
Interceptors
functions to change request or response parameters, readinterceptors?
Interceptors
functions to change request or response parameters, readEvery graphql config should contain
operationName
orquery
or both of them
/** @type {import('mock-config-server').FlatMockServerConfig} */
const flatMockServerConfig = [
{
baseUrl: '/graphql'
},
{
configs: [
{
operationType: 'query',
operationName: 'GetUser',
routes: [
{
entities: {
headers: { 'name-header': 'Nursultan' }
},
data: { emoji: 'π¦', name: 'Nursultan' }
},
{
entities: {
headers: { 'name-header': 'Dmitriy' }
},
data: { emoji: 'β', name: 'Dmitriy' }
}
]
}
]
}
];
export default flatMockServerConfig;
Now you can make a request with an additional header and get the desired result
const body = JSON.stringify({
query: 'query GetUser { name }'
});
fetch('http://localhost:31299/graphql', {
method: 'POST',
headers: {
'name-header': 'Nursultan',
'Content-Type': 'application/json'
},
body
})
.then((response) => response.json())
.then((data) => console.log(data)); // { emoji: 'π¦', name: 'Nursultan' }
If you need more complex logic for matching entities, you can use entity descriptors.
Descriptor is an object with checkMode
and value
fields that describe how the correctness of the actual entity is calculated.
Allowed checkModes
/** @type {import('mock-config-server').FlatMockServerConfig} */
const flatMockServerConfig = [
{
baseUrl: '/api'
},
{
configs: [
{
path: '/user',
method: 'get',
routes: [
{
entities: {
headers: {
// 'name-header' is 'Dmitriy'
'name-header': {
checkMode: 'equals',
value: 'Dmitriy'
},
// check for 'equals' if descriptor not provided
// i.e. it is the same as `role: { checkMode: 'equals', value: 'developer' }`
role: 'developer'
},
cookies: {
// any 'token' cookie
token: {
checkMode: 'exists'
},
// 'someSecretToken' cookie can be '123-abc' or '456-abc' for example
someSecretToken: {
checkMode: 'regExp',
value: /^\d\d\d-abc$/
}
}
},
data: 'Some user data for Dmitriy'
}
]
}
]
}
];
export default flatMockServerConfig;
For checkMode
with the value
property (all checkMode
options except exists
and notExists
) you can use an array as value.
Mock server will find matches by iterating through the array until some match is found.
To be able to use this functionality you need to explicitly set oneOf: true
property in descriptor object.
/** @type {import('mock-config-server').FlatMockServerConfig} */
const flatMockServerConfig = [
{
baseUrl: '/api'
},
{
configs: [
{
path: '/user',
method: 'post',
routes: [
{
entities: {
// if body equals to { key1: 'value1' } OR { key2: 'value2' } then mock-config-server return 'Some user data 1'
body: {
checkMode: 'equals',
value: [{ key1: 'value1' }, { key2: 'value2' }],
oneOf: true
}
},
data: 'Some user data 1'
},
{
entities: {
// if body equals to [{ key1: 'value1' }, { key2: 'value2' }] then mock-config-server return 'Some user data 2'
// NO `oneOf` => array processed entirely
body: {
checkMode: 'equals',
value: [{ key1: 'value1' }, { key2: 'value2' }]
}
},
data: 'Some user data 2'
}
]
}
]
}
];
export default flatMockServerConfig;
function checkMode
is the most powerful way to describe your entities
logic, but in most cases you will be fine using other checkModes
.
Function value
has the following signature (actualValue, checkFunction) => boolean
.
Return true
if actualValue
matches your logic or false
otherwise.
You can use the checkFunction
from second argument if you want to describe your logic in a more declarative way.
checkFunction
has the following signature (checkMode, actualValue, descriptorValue?) => boolean
.
/** @type {import('mock-config-server').FlatMockServerConfig} */
const flatMockServerConfig = [
{
baseUrl: '/api'
},
{
configs: [
{
path: '/posts/:postId',
method: 'post',
routes: [
{
entities: {
params: {
postId: {
checkMode: 'function',
value: (actualValue) => +actualValue >= 0 && +actualValue <= 50
},
},
cookies: {
authToken: {
checkMode: 'function',
value: (actualValue, checkFunction) =>
checkFunction('equals', actualValue, 123) ||
checkFunction('startsWith', actualValue, 2)
}
}
},
data: 'Some user data'
}
]
}
]
}
];
module.exports = flatMockServerConfig;
If you want to check a deep nested property of your body or variables via descriptor you can use flatten object style. In this case server will check every field in entity with corresponding actual field. I.e. you can use descriptors only for properties of entity object (not for properties of nested objects).
/** @type {import('mock-config-server').FlatMockServerConfig} */
const flatMockServerConfig = [
{
baseUrl: '/api'
},
{
configs: [
{
path: '/users',
method: 'post',
routes: [
{
entities: {
body: {
// if body has properties like { user: { name: 'Sergey' } } OR { 'user.name': 'Sergey' } then mock-config-server return data
'user.name': {
checkMode: 'equals',
value: 'Sergey'
}
}
},
data: 'user.name in body is "Sergey"'
}
]
}
]
}
];
export default flatMockServerConfig;
You can also use descriptor for whole body or variables entity.
When you use 'equals'/'notEquals' check mode for whole body or variables mock-config-server is strictly compare entity and actual value. It means that you must specify ALL properties from actual body or variables.
/** @type {import('mock-config-server').FlatMockServerConfig} */
const flatMockServerConfig = [
{
baseUrl: '/api'
},
{
configs: [
{
path: '/users',
method: 'post',
routes: [
{
entities: {
body: {
// if actual body contains some extra property(-ies) then this entity won't match
checkMode: 'equals',
value: {
user: {
name: 'Sergey',
emoji: 'π',
roles: ['developer', 'moderator']
}
}
}
},
data: 'your body is strictly equals object from body entity value'
}
]
}
]
}
];
export default flatMockServerConfig;
Rest routes support paths to files. If a route is matched, the server will send data from the file. If the file is not found, the server will return 404.
/** @type {import('mock-config-server').FlatMockServerConfig} */
const flatMockServerConfig = [
{
baseUrl: '/api'
},
{
configs: [
{
path: '/files/settings',
method: 'get',
routes: [
{
file: './settings.json'
}
]
}
]
}
];
export default flatMockServerConfig;
If the file path is absolute, then this path will be used as is. If the file path is relative, it will be appended to the current working directory.
If the file exists, response interceptors will receive file descriptor
as the data
argument:
File descriptor
is an object with path
and file
fields that describe file location and file content.
path
string
path to the file. Same as file
passed in routefile
Buffer
file content as binary bufferNote to return file descriptor from interceptor. Server will send a buffer from
data.file
with correspondingContent-Type
andContent-Disposition
headers. If you return invalid file descriptor, server will send it as json data.
/** @type {import('mock-config-server').FlatMockServerConfig} */
const flatMockServerConfig = [
{
baseUrl: '/api'
},
{
configs: [
{
path: '/files/settings',
method: 'get',
routes: [
{
file: './settings.json',
interceptors: {
response: (data) => {
const { file, path } = data;
const buffer = file; // some logic with buffer
fs.writeFileSync(path, buffer); // rewrite ./settings.json file on disk with new content
return { path, file: buffer };
}
}
}
]
}
]
}
];
export default flatMockServerConfig;
Any changes to the data will not affect the file on disk unless you manually rewrite it.
If you return a new
path
from interceptor, server will send file corresponding to this path or 404 error otherwise.
Routes support polling for data. To add polling for data, you must specify the polling setting
and use queue
property instead of data
or file
.
queue
is an array containing data
or file
that should be returned in order.
After receiving the last value from polling, the queue is reset and the next request will return the first value from the queue.
/** @type {import('mock-config-server').FlatMockServerConfig} */
const flatMockServerConfig = [
{
baseUrl: '/api'
},
{
configs: [
{
path: '/user',
method: 'get',
routes: [
{
settings: { polling: true },
queue: [
{ data: { emoji: 'π¦', name: 'Nursultan' } },
{ data: { emoji: 'β', name: 'Dmitriy' } },
{ file: './users/Sergey.json' }
]
}
]
}
]
}
];
export default flatMockServerConfig;
Using the additional time
properties in milliseconds, you can specify how much time certain data should be returned
/** @type {import('mock-config-server').FlatMockServerConfig} */
const flatMockServerConfig = [
{
baseUrl: '/api'
},
{
configs: [
{
path: '/user',
method: 'get',
routes: [
{
settings: { polling: true },
queue: [
{ time: 5000, data: { emoji: 'π¦', name: 'Nursultan' } },
{ data: { emoji: 'β', name: 'Dmitriy' } }
]
}
]
}
]
}
];
export default flatMockServerConfig;
Entity for connecting statics to the server, like HTML, JSON, PNG, etc.
string
path to your static filesObject<{prefix, path}
prefix
string
path prefix for requestpath
string
path to your static filesArray<string | Object<{prefix, path}>>
Object with settings for CORS. You can flexibly configure the required origin, methods, headers, credentials, maxAge for the entire server. If you do not specify CORS
settings, then it will be disabled.
origin
string | RegExp | Array<string | RegExp> | Function | Promise
available origins from which requests can be mademethods?
Array<GET | POST | DELETE | PUT | PATCH>
available methods (default: GET,OPTIONS,PUT,PATCH,POST,DELETE
)allowedHeaders?
Array<string>
allowed headers (default: *
)exposedHeaders?
Array<string>
exposed headers (default: *
)credentials?
boolean
param tells browsers whether to expose the response to the frontend JavaScript code (default: true
)maxAge?
number
how long the results can be cached (default: 3600
)Functions to change request or response parameters
request?
(params) => void
response?
(data, params) => any
request interceptors (except interceptor for route) are called regardless of whether the server found a route match or not. So changes in request interceptors can affect whether the server finds the route or not
params
request
request objectsetDelay
(delay) => Promise<void>
delay
number
milliseconds of delay timegetHeader
(field) => string | number | string[] | undefined
field
string
name of response headergetHeaders
() => Record<string | number | string[] | undefined>
getCookie
(name) => string | undefined
name
string
name of cookielog
(logger) => Partial<LoggerTokens>
logger function read
logger
Logger | undefined
logger optionsdata
any
mock data of requestparams
request
request objectresponse
response objectsetDelay
(delay) => Promise<void>
delay
number
milliseconds of delay timesetStatusCode
(statusCode) => void
statusCode
number
status code for responsesetHeader
(field, value) => void
field
string
name of response headervalue
string | string[] | undefined
value of response headerappendHeader
(field, value) => void
field
string
name of response headervalue
string | string[] | undefined
value of response headergetHeader
(field) => string | number | string[] | undefined
field
string
name of response headergetHeaders
() => Record<string | number | string[] | undefined>
setCookie
(name, value, options) => void
name
string
name of cookievalue
string
value of cookieoptions
[CookieOptions](https://expressjs.com/en/resources/middleware/cookie-session.html) | undefined
cookie options (like path, expires, etc.)getCookie
(name) => string | undefined
name
string
name of cookieclearCookie
(name, options) => void
name
string
name of cookieoptions
[CookieOptions](https://expressjs.com/en/resources/middleware/cookie-session.html) | undefined
cookie options (like path, expires, etc.)attachment
(filename) => void
filename
string
name of file in 'Content-Disposition' headerlog
(logger) => Partial<LoggerTokens>
logger function read
logger
Logger | undefined
logger optionsYou can log requests and responses using log
function in any interceptor.
log
has the following signature (logger?: Logger) => Partial<LoggerTokens>
.
logger
parameter has the following optional properties
options?
LoggerOptions
object map containing tokens to log. Keys is token names, values is boolean. true
will add token into log, false
will remove. If options
property is not passed, following tokens will be logged
rewrite?
(tokens: Partial<LoggerTokens>) => void
function to replace default console.dir(tokens, { depth: null })
appearancelog
function returns object with logged token values
/** @type {import('mock-config-server').FlatMockServerConfig} */
const flatMockServerConfig = [
{
baseUrl: '/api'
},
{
configs: [
{
path: '/posts',
method: 'get',
routes: [
{
interceptors: {
request: ({ log }) => {
log({
// logs following object in terminal
options: {
// {
id: true, // id: 1,
type: true, // type: 'request',
timestamp: true, // timestamp: '31.12.2024, 23:59:59,999',
method: true, // method: 'GET',
url: true // url: 'http://localhost:31299/api/rest/posts/1'
} // }
});
},
response: (data, { log }) => {
log({
// logs following string in terminal
options: {
// response get: http://localhost:31299/api/rest/posts/1 => 200
type: true,
statusCode: true,
method: true,
url: true
},
rewrite: ({ type, statusCode, method, url }) => {
console.info(`${type} ${method}: ${url} => ${statusCode}`);
}
});
return data;
}
}
}
]
}
]
}
];
export default flatMockServerConfig;
By default,
timestamp
andmethod
tokens are prettified. Timestamp transforms from UNIX-timestamp number toDD.MM.YYYY, HH:mm:ss,sss
string. Method transforms from lower case to upper case. Ifrewrite
function is used, those tokens will remain unformatted. You can format them as you need.
type?
'request' | 'response'
type of logid?
number
unique id of request to reference request log with response logtimestamp?
number
UNIX-timestamp in millisecondsmethod?
'get' | 'post' | 'delete' | 'put' | 'patch' | 'options'
HTTP methodurl?
string
requested URLgraphQLOperationType?
'query' | 'mutation' | null
GraphQL operation type. null
if request is not GraphQLgraphQLOperationName?
string
GraphQL operation name. null
if request is not GraphQLgraphQLQuery?
string
GraphQL query. null
if request is not GraphQLvariables?
: Record<string, any>
GraphQL variables. null
if request is not GraphQL or variables is not passedheaders?
Record<string, any>
headers objectcookies?
Record<string, any>
cookies objectquery?
Record<string, any>
query objectparams?
Record<string, any>
params objectbody?
any
bodyResponse logger has additional tokens
statusCode?
number
response status codedata?
any
data returned to clientIf you need to log specific properties in mapped entities (headers, cookies, query, params), use Record<string, boolean>
object instead of boolean.
In that case logger will use following logic:
true
, entity will be filtered by whitelist
logic. Only enabled ones will be logged.false
, entity will be filtered by blacklist
logic. All entities will be logged except disabled ones.Whitelist logic have priority over blacklist if you pass
true
andfalse
in same entity.
/** @type {import('mock-config-server').FlatMockServerConfig} */
const flatMockServerConfig = [
{
baseUrl: '/api'
},
{
configs: [
{
path: '/posts',
method: 'get',
routes: [
{
interceptors: {
request: ({ log }) => {
log({
// whitelist. only query1 and query2 will be logged
options: {
query: {
query1: true,
query2: true
}
}
});
log({
// whitelist. only cookie1 and cookie2 will be logged
options: {
cookies: {
cookie1: true,
cookie2: true,
cookie3: false
}
}
});
log({
// blacklist. all headers will be logged except header1
options: {
headers: {
header1: false
}
}
});
}
},
data: {}
}
]
}
]
}
];
export default flatMockServerConfig;
With mock-config-server
you can create your own mock database with all CRUD operations
data
Object | string
initial data for databaseroutes?
Object | string
map of custom routes for databaseconst flatMockServerConfig = [
{
database: {
data: {
users: [{ id: 1, name: 'John' }],
settings: {
blocked: false
}
}
}
}
];
Now you have the following routes for requests
GET /users
POST /users
GET /users/1
PUT /users/1
PATCH /users/1
DELETE /users/1
GET /settings
POST /settings
PUT /settings
PATCH /settings
Collection routes created from arrays which all elements have unique(!) id. Other database parts become single routes.
Also, there are additional routes: /__db
and /__routes
__db -> return data from database config
__routes -> return routes from database config
const flatMockServerConfig = [
{
database: {
data: {
users: [{ id: 1, name: 'John' }],
settings: {
blocked: false
}
},
routes: {
'/api/users/:id': '/users/:id',
'/*/my-settings': '/settings'
}
}
}
];
Now following routes will work correctly
/api/users/1 -> return data for /users/1
/some/custom/url/my-settings -> return data for /settings
Note some things:
:id
templatewildcard
only for custom route, not for real routeUse . to access deep properties
GET /users?name=siberiacancode
GET /users?id=1&id=2
GET /users?author.name=siberiacancode
Use _page and optionally _limit to paginate returned data.
GET /users?_page=1
GET /users?_page=1&_limit=5
_limit is 10 by default
The returned data has the format:
{
_link: Link,
results: Data[]
}
In the Link header you'll get count, pages, next and prev links.
count
number
total count of elementspages
number
count of pagesnext
string | null
query string for next linkprev
string | null
query string for prev linkUse _sort and _order, use . to access deep properties
GET /users?_sort=name
GET /users/1/transfers?_sort=id&_order=asc
GET /users?_sort=address.city&_order=desc
_order is 'asc' by default
For multiple fields:
GET /users?_sort=id&_order=desc&_sort=name&_order=asc
X-Total-Count header is included in the response
GET /users?_begin=20
GET /users?_begin=20&_end=30
Works exactly as slice, _begin and _end are optional
Add _q parameter for search data, search can be done by strings and numbers
GET /users?_q=siberia
For multiple search
GET /users?_q=siberia&_q=24
const flatMockServerConfig = [
{
database: {
data: './data.json',
routes: './routes.json'
}
}
];
Instead of objects you can use paths to JSON files which contain needed data or routes
mcs [options]
Options:
--baseUrl, -b Set base url (default: '/')
--port, -p Set port (default: 31299)
--staticPath, -s Set static path
--config, -c Set path to config file (default: './mock-server.config.(?:ts|mts|cts|js|mjs|cjs)')
--watch, -w Enables server restart after config file changes (default: false)
--version, -v Show version number
--help, -h Show help
Examples:
mcs --baseurl /base/url --port 3000 --config ./path/to/config.ts -w
mcs --help
The init command is used to initialize a new project or set up the initial configuration for a tool. It helps users get started with a new project by providing a streamlined setup process.
mcs init
Examples:
mcs init
mcs init --baseurl /base/url --port 3000
βοΈ debabin |
πΉ MiaInturi |
π RiceWithMeat |
π±οΈ anv296 |
π΅ kvelian |
FAQs
Tool that easily and quickly imitates server operation, create full fake api in few steps
The npm package mock-config-server receives a total of 172 weekly downloads. As such, mock-config-server popularity was classified as not popular.
We found that mock-config-server demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Β It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
require(esm) backported to Node.js 20, easing the transition to ESM-only packages and reducing complexity for developers as Node 18 nears end-of-life.
Security News
PyPI now supports iOS and Android wheels, making it easier for Python developers to distribute mobile packages.
Security News
Create React App is officially deprecated due to React 19 issues and lack of maintenanceβdevelopers should switch to Vite or other modern alternatives.