Skip to content

Instantly share code, notes, and snippets.

@trinhvanminh
Last active December 27, 2024 11:09
Show Gist options
  • Save trinhvanminh/1c1c0d3d22dab63f3f3f38610ffdbe4d to your computer and use it in GitHub Desktop.
Save trinhvanminh/1c1c0d3d22dab63f3f3f38610ffdbe4d to your computer and use it in GitHub Desktop.
Mocks Server
  1. Install npm i -D @mocks-server/main

  2. Add script

"scripts": {
    "mocks": "mocks-server",
},
  1. Run (if this command have not create mocks.config.js => manual create one) npm run mocks

  2. Folder structure

project-root/
├── mocks/
│   ├── documents/ <- place your openapi.json
│   │   └── openapi.json
│   ├── openapi/ <- openapi definitions
│   │   └── definitions.js
│   ├── routes/ <- DEFINE YOUR ROUTES HERE
│   │   ├── common.js
│   │   └── users.js
│   └── collections.js <- DEFINE YOUR COLLECTIONS HERE
└── mocks.config.js <- DEFINE YOUR CONFIGURATION HERE
  1. Main concepts
  • Routes: A route defines the url and method of an API resource. Wildcards can be used in urls and methods, so one route can simulate one real API resource, or many.
  • Variants: Each route can contain many different variants. Each variant can define a response to send, or a middleware to execute, or a url to proxy the request, etc.
  • Collections: A collection of route variants defines all current routes and variants in the API mock. They can be created extending other collections. So, you can store many collections and change the whole API behavior by simply changing the current one.

Main concepts schema

<!-- ./mocks/collection.js -->
/**
* Mock collections for the application.
*
* Each collection contains a set of routes that will handle requests based on the route method and URL.
* The order of the routes in a collection is important as it determines the order in which middlewares are applied.
*
* @module collections
*
* @type {Array<Object>}
* @property {string} id - The unique identifier for the collection.
* @property {string} [from] - The base collection that this collection extends from. [Extending collections](https://www.mocks-server.org/docs/usage/collections/#extending-collections)
* @property {Array<string>} routes - The routes included in the collection. The first route in the array matching the route method and route URL will handle the request. So, you can use the order of the routes in a collection to apply middlewares (next()) in the order that you want.
*
* @example
* // Base collection with headers and user routes
* {
* id: 'base',
* routes: ['add-headers:enabled', 'get-users:success', 'get-user:success'],
* }
*
* @example
* // Collection extending from base without headers
* {
* id: 'no-headers',
* from: 'base',
* routes: ['add-headers:disabled'],
* }
*
* @example
* // Collection with all users
* {
* id: 'all-users',
* from: 'base',
* routes: ['get-users:all', 'get-user:id-3'],
* }
*
* @example
* // Collection with user 2
* {
* id: 'user-2',
* from: 'all-users',
* routes: ['get-user:id-2'],
* }
*
* @example
* // Collection with real user data
* {
* id: 'user-real',
* from: 'no-headers',
* routes: ['get-user:real'],
* }
*/
module.exports = [
{
id: 'base',
routes: ['add-headers:enabled', 'get-users:success', 'get-user:success'],
},
{
id: 'no-headers',
from: 'base',
routes: ['add-headers:disabled'],
},
{
id: 'all-users',
from: 'base',
routes: ['get-users:all', 'get-user:id-3'],
},
{
id: 'user-2',
from: 'all-users', // extends "all-users" collection
// "get-user" route uses "id-2" variant instead of "id-3"
// "get-user" route is still in the second place of the collection
routes: ['get-user:id-2'],
},
{
id: 'user-real',
from: 'no-headers',
routes: ['get-user:real'],
},
{
id: 'proxy-fallback',
routes: ['get-user:id-2', 'get-users:add-prefix', 'proxy-all:real-api'],
},
];
<!-- mocks/routes/common.js -->
// https://www.mocks-server.org/docs/usage/routes/#format
// Use this file only as a guide for first steps using middleware variants. You can delete it when you have understood the concepts.
// For a detailed explanation about using middlewares, visit:
// https://mocks-server.org/docs/usage/variants/middlewares
module.exports = [
{
id: 'add-headers', //route id
url: '*', // url in express format
method: ['GET', 'POST', 'PUT', 'PATCH'], // HTTP methods
variants: [
{
id: 'enabled', // variant id
type: 'middleware', // variant handler id
options: {
// Express middleware to execute
middleware: (_req, res, next, core) => {
res.set('x-mocks-server-example', 'some-value');
core.logger.info('Custom header added by route variant middleware');
next();
},
},
},
{
id: 'disabled', // variant id
disabled: true,
},
],
},
{
id: 'collection', //route id
url: '*', // url in express format
method: ['GET', 'POST', 'PUT', 'PATCH'], // HTTP methods
variants: [
{
id: 'content', // variant id
type: 'file', // variant handler id,
options: {
status: 200, // status to send
path: 'mocks/collections.js', // path to file
},
},
],
},
];
<!-- mocks/openapi/definitions.js -->
// http://localhost:3100/testing-api/items
module.exports = [
{
basePath: '/testing-api', // basePath to add to the url of every created route
collection: {
id: 'testing-api', // Id for the collection generated with all routes created from the OpenAPI document
},
document: {
$ref: '../documents/openapi.json',
},
},
];
<!-- mocks/documents/openapi.json -->
{
"openapi": "3.0.0",
"info": {
"title": "Sample API",
"description": "This is a sample API.",
"version": "1.0.0"
},
"paths": {
"/items": {
"get": {
"summary": "List all items",
"responses": {
"200": {
"description": "A list of items.",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
}
},
"example": [
{
"id": 1,
"name": "Item 1"
},
{
"id": 2,
"name": "Item 2"
}
]
}
}
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment