@r35007/mock-server-lite
    TypeScript icon, indicating that this package has built-in type declarations

    1.0.1 • Public • Published

    Mock Server Lite

    Get a full REST API with zero coding in less than 30 seconds (seriously)

    Created with <3 for front-end developers who need a quick back-end for prototyping and mocking.

    Now also available as a VSCodeExtension thinker.mock-server-lite.

    This is the lite version of MocK Server.

    Table of contents

    Getting started

    Install Mock Server

    npm install -g @r35007/mock-server-lite

    Create a db.json file with some data.

    {
      "posts": [{ "id": 1, "title": "mock-server", "author": "r35007" }],
      "comments": [{ "id": 1, "body": "some comment", "postId": 1 }],
      "profile": { "name": "r35007" }
    }

    Start Mock Server

    mock-server --watch ./db.json

    Now if you go to http://localhost:3000/posts/1, you'll get

    { "id": 1, "title": "mock-server", "author": "r35007" }

    Using JS Module

    First install nodemon for watching changes

    npm install -g nodemon

    Create server.js File

    const { MockServer } = require("@r35007/mock-server-lite"); // use import if using ES6 module
    
    const mockServer = new MockServer("./config.json"); // Creates a Mock Server instance
    // or
    // const mockServer = MockServer.Create("./config.json"); // Creates a Mock Server single instance
    
    mockServer.launchServer(
      "./db.json",
      "./middleware.js",
      "./injectors.json",
      "./rewriters.json",
      "./store.json"
    ); // Starts the Mock Server.
    
    //or
    
    const app = mockServer.app;
    
    const rewriter = mockServer.rewriter("./rewriters.json");
    app.use(rewriter); // make sure to add this before defaults and resources
    
    const defaults = mockServer.defaults({ noGzip: true });
    app.use(defaults);
    
    const resources = mockServer.resources(
      "./db.json",
      "./middleware.js",
      "./injectors.json",
      "./store.json"
    );
    app.use(resources);
    
    const defaultRoutes = mockServer.defaultRoutes();
    app.use(defaultRoutes);
    
    // make sure to add this at last
    app.use(mockServer.pageNotFound);
    app.use(mockServer.errorHandler);
    
    mockServer.startServer(3000, "localhost");

    Now go to terminal and type the following command to start the Mock Server.

    nodemon server.js

    Route Config

    Create a db.json file. Pay attention to start every route with /. For Example:

    db.json

    {
      "/route/1, /route/2": {
        // /route/1 and /route/2 shares the same config and mock data
        "_config": true, // Make sure to set this to true to use this object as a route configuration.
        "id": "id-unique", // sets a unique id for each route
        "description": "", // Description about this Route.
        "delay": 2000, // in milliseconds
        "statusCode": 200, // in number between 100 to 600
        "middlewareNames": ["_IterateResponse"], // list of middleware names to be called
        "middlewares": "", // Can give a list of express Middlewares If using in .js file
        "mock": [{ "name": "foo" }, { "name": "bar" }],
        "store": {} // helps to store any values for later use
      },
      "/routeName3": {
        "name": "foo",
        "age": "bar",
        "description": "Note: Since _config attribute is not set to true this whole object will be sent as a response"
      }
    }

    Set Delay Response

    delay helps you to set a custom delay to your routes. Note : The delay yo set must be in milliseconds and of type number

    {
      "/customDelay": {
        "_config": true,
        "delay": 2000,
        "description": "Note: give delay in milliseconds",
        "mock": "This is response is received with a delay of 2000 milliseconds"
      }
    }

    Now if you go to http://localhost:3000/customDelay, you'll get the response in a delay of 2 seconds.

    Set Custom StatusCode

    statusCode helps you set a custom statusCode to your routes. It must be of type number and between 100 to 600.

    {
      "/customStatusCode": {
        "_config": true,
        "statusCode": 500,
        "mock": "This is response is received with a statusCode of 500"
      }
    }

    Now if you go to http://localhost:3000/customStatusCode, you'll get the response with a 500 statusCode

    Add Middleware

    You can add n number of middleware to a route which helps you to manipulate or log the data.

    middleware.js

    exports.DataWrapper = (req, res, next) => {
      res.locals.data = {
        status: "Success",
        message: "Retrived Successfully",
        result: res.locals.data,
      };
      next();
    };

    db.json

    {
      "/customMiddleware": {
        "_config": true,
        "description": "Note: This middleware must be available in the 'middleware.js' by the below given names. This 'DataWrapper' will be called on every hit of this route.",
        "mock": "This data will be wrapped by the middleware response object",
        "middlewareNames": ["DataWrapper"]
      }
    }

    Note: A middleware must be available at the name of the middlewareNames given in db.json http://localhost:3000/customMiddleware.

    Middleware Utils

    Use the predefined middleware to speedup your development and for ease of access.

    IterateResponse

    setting middleware to _IterateResponse helps to send you a iterate the response one after the other in the mock array for each url hit.

    example:

    {
      "/middleware/utils/example/_IterateResponse": {
        "_config": true,
        "description": "This route iterates through each data. Try to hit again to see the data change. Note: The data must be of type array",
        "mock": [
          {
            "userId": 1,
            "id": 1,
            "title": "Lorem ipsum dolor sit.",
            "body": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Est, dolorem."
          },
          {
            "userId": 1,
            "id": 2,
            "title": "Lorem ipsum dolor sit.",
            "body": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Est, dolorem."
          },
          {
            "userId": 1,
            "id": 3,
            "title": "Lorem ipsum dolor sit.",
            "body": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Est, dolorem."
          }
        ],
        "middlewareNames": ["_IterateResponse"]
      }
    }

    Now go and hit http://localhost:3000/middleware/utils/example/_IterateResponse. For each hit you will get the next object in an array from the photos data.

    IterateRoutes

    setting middleware to _IterateRoutes helps to send you a iterate the route one after the other in the mock array for each url hit.

    example:

    {
      "/middleware/utils/example/_IterateRoutes": {
        "_config": true,
        "description": "This route iterates through each route provide in the mock. Try to hit again to see the route change. Note: The data must be of type array",
        "mock": ["/injectors/1", "/injectors/2"],
        "middlewareNames": ["_IterateRoutes"]
      },
      "/injectors/1": "/injectors/1 data",
      "/injectors/2": "/injectors/2 data"
    }

    Now go and hit http://localhost:3000/middleware/utils/example/_IterateRoutes. For each hit the route is passed to next matching url provided in the mock list.

    AdvancedSearch

    _AdvancedSearch middleware helps to filter and do the advanced search from data.Following are the operations performed by this method.

    Filter

    Use . to access deep properties

    GET /posts?title=mock-server&author=typicode
    GET /posts?id=1&id=2
    GET /comments?author.name=typicode
    

    Paginate

    Use _page and optionally _limit to paginate returned data.

    In the Link header you'll get first, prev, next and last links.

    GET /posts?_page=7
    GET /posts?_page=7&_limit=20
    

    10 items are returned by default

    Sort

    Add _sort and _order (ascending order by default)

    GET /posts?_sort=views&_order=asc
    GET /posts/1/comments?_sort=votes&_order=asc
    

    For multiple fields, use the following format:

    GET /posts?_sort=user,views&_order=desc,asc
    

    Slice

    Add _start and _end or _limit (an X-Total-Count header is included in the response)

    GET /posts?_start=20&_end=30
    GET /posts/1/comments?_start=20&_end=30
    GET /posts/1/comments?_start=20&_limit=10
    

    Works exactly as Array.slice (i.e. _start is inclusive and _end exclusive)

    Operators

    Add _gte or _lte for getting a range

    GET /posts?views_gte=10&views_lte=20
    

    Add _ne to exclude a value

    GET /posts?id_ne=1
    

    Add _like to filter (RegExp supported)

    GET /posts?title_like=server
    

    Full text search

    Add q or _text

    GET /posts?q=internet&_text=success
    

    CrudOperations

    _CrudOperations middleware handles all the crud operations of the given data. By default it also handles the _AdvancedSearch operations. Note : the mock must of type Array of objects and must contain a unique value of attribute id. this id attribute can also be changes using config.id.

    For example: config.json

    {
      "id": "_id"
    }

    SetStoreDataToMock

    _SetStoreDataToMock sets every store data to Mock data. This overrides the existing mock with the store.

    ReadOnly

    _ReadOnly forbidden every Http method calls except GET call.

    Injectors

    Injectors helps to inject a Route Configs explicitly. This also helps to provide a common route configs. Injector uses path-to-regexp pattern recognition to set config for multiple routes.

    Inject Route Configs

    Here we are explicitly injecting delay, middlewareNames, statusCode to the /posts route. You can any route configs to a specific or to a group of routes using Injectors.

    • Injectors use path-to-regexp package for route pattern recognition.
    • Click path-to-regexp for more details.

    example : injectors.json

    [
      {
        "routeToMatch": "/injectors/:id",
        "description": "This description is injected using the injectors by matching the pattern '/injectors/:id'."
      }
    ]

    Override Existing Route Configs

    Setting override flag to true helps to override the existing config of that route.

    For example :

    injectors.json

    [
      {
        "routeToMatch": "/injectors/2",
        "override": true,
        "mock": "This data is injected using the injectors by matching the pattern '/injectors/2'."
      },
      {
        "routeToMatch": "/injectors/:id",
        "override": true,
        "exact": true,
        "statusCode": 200,
        "mock": "This data is injected using the injectors by exactly matching the route '/injectors/:id'."
      },
      {
        "routeToMatch": "/(.*)",
        "override": true,
        "middlewareNames": ["...", "CustomLog"]
      }
    ]

    Note: Use ["..."] If you want to add the existing middlewareNames.

    Common Route Configs

    Using wildcards you can set a common route configs to all the routes. /(.*) - matches all the routes.

    For example :

    injectors.json

    [
      {
        "routeToMatch": "/(.*)",
        "description": "This Description is injected using the injectors. Set 'Override' flag to true to override the existing config values."
      },
      {
        "routeToMatch": "/(.*)",
        "override": true,
        "middlewareNames": ["...", "CustomLog"]
      }
    ]

    Make sure you give /(.*) at the end of the injectors.json object to set route configs to all the routes.

    Store Data

    Store used to store any values which can be used later for any purpose like response manipulation or logging etc..

    Route Store

    Route store helps to store any values which can be accessed on by that particular route. This stores values cannot be able to accessed by the other routes. Route Store can be accessed using res.locals.routeConfig.store inside the middleware.

    The middlewareNames _CrudOperations, _IterateRoutes, _IterateResponse uses the Route store to manipulate response.

    Local Store

    Local Store helps to store and share data between routes. This can be accessed using res.locals.store inside the middleware.

    Route Rewriters

    Create a rewriters.json file. Pay attention to start every route with /.

    • Rewriters use express-urlrewrite package to rewrite the urls.
    • Click here for more information about url rewrite.
    {
      "/api/*": "/$1",
      "/:resource/:id/show": "/:resource/:id",
      "/posts/:category": "/posts?category=:category",
      "/articles?id=:id": "/posts/:id"
    }

    server.js

    const mockServer = MockServer.Create();
    mockServer.launchServer(
      "./db.json",
      "./middleware.js",
      "./injectors.json",
      "./rewriters.json"
    );

    Now you can access resources using additional routes.

    /api/posts # → /posts
    /api/posts/1  # → /posts/1
    /posts/1/show # → /posts/1
    /posts/javascript # → /posts?category=javascript
    /articles?id=1 # → /posts/1

    Locals

    res.locals helps to access the current route config, mock, statusCode etc.. Here are the available options in res.locals

    interface Locals {
      routePath: string;
      routeConfig: {
        _config?: boolean;
        id?: string;
        description?: string;
        statusCode?: number;
        delay?: number;
        mock?: any;
        store?: object;
        middlewareNames?: string[];
        middlewares?: Array<express.RequestHandler>;
      };
      data: any; // response will be sent using this attribute value.
      store: object;
      getDb: (ids?: string[], routePaths?: string[]) => Routes; // This method helps to get other route configs and values.
      config: Config; // gives you the current mock server configuration.
    }

    Dynamic Route Config

    RouteConfigs are mutable. Means we can able to modify the routeConfigs in runtime using middleware. For Example:

    middleware.js

    exports._Status500 = (_req, res, next) => {
      const locals = res.locals;
      const routeConfig = locals.routeConfig;
      routeConfig.statusCode = 500;
      routeConfig.mock = "Failed Response";
      next();
    };

    Config

    you can provide your own config by passing the config object in the MockServer constructor. For Example :

    server.js :

    // These are default config. You can provide your custom config as well.
    const config = {
      port: 3000, // by default mock will be launched at this port. http://localhost:3000/
      host: "localhost",
      root: process.cwd(), // all paths will be relative to this path. Please provide a absolute path here.
      base: "/", // all routes will be prefixed with the given baseUrl.
      staticDir: "public", // Please provide a folder path. This will be hosted locally and all files will be statically accessed
      reverse: false, // If true routes will be generated in reverse order
      bodyParser: true, // Sets the bodyParser
      id: "id", // Set the id attribute here. Helps to do Crud Operations. For example: 'id': "_id"
      logger: true, // If False no logger will be shown
      noCors: false, // If false cross origin will not be handled
      noGzip: false, // If False response will not be compressed
      readOnly: false, // If true only GET call is allowed
    };
    
    new MockServer(config).launchServer("./db.json");

    Default Routes

    Home Page

    Home Page

    CLI Usage

    $ mock-server --help
    Options:
      -c, --config           Path to config file                            [string]
      -P, --port             Set port                                [default: 3000]
      -H, --host             Set host                         [default: "localhost"]
      -m, --middleware       Paths to middleware file                      [string]
      -i, --injectors        Path to Injectors file                         [string]
      -s, --store            Path to Store file                             [string]
      -r, --rewriters        Path to Rewriter file                          [string]
          --staticDir, --sd  Set static files directory                     [string]
      -b, --base             Set base route path                            [string]
          --readOnly, --ro   Allow only GET requests                       [boolean]
          --noCors, --nc     Disable Cross-Origin Resource Sharing         [boolean]
          --noGzip, --ng     Disable GZIP Content-Encoding                 [boolean]
      -l, --logger           Enable logger                 [boolean] [default: true]
          --sample, --ex     Create Sample                [boolean] [default: false]
      -w, --watch            Watch file(s)                [boolean] [default: false]
      -S, --snapshots        Set snapshots directory                  [default: "."]
      -h, --help             Show help                                     [boolean]
      -v, --version          Show version number                           [boolean]
    
    Examples:
      index.js db.json
      index.js --watch db.json
      index.js --sample --watch
      index.js http://jsonplaceholder.typicode.com/db
    
    https://r35007.github.io/Mock-Server/

    API

    MockServer

    returns the instance of the mockServer.

    const { MockServer } = require("@r35007/mock-server-lite");
    const mockServer = new MockServer("./config.json");

    Params

    Name Type Required Description
    config string / object No This object sets the port, host etc..

    Create

    returns the single instance of the mockServer.

    const { MockServer } = require("@r35007/mock-server-lite");
    const mockServer = MockServer.Create("./config.json");

    Params

    Name Type Required Description
    config string / object No This object sets the port, host etc..

    Destroy

    stops the server and clears the instance of the mockServer. returns promise

    const { MockServer } = require("@r35007/mock-server-lite");
    await MockServer.Destroy();

    launchServer

    It validates all the params in the MockServer, loads the resources and starts the server.

    mockServer.launchServer(
      "./db.json",
      "./middleware.js", // middleware must be of type .js
      "./injectors.json",
      "./rewriters.json",
      "./store.json"
    );

    Params

    Name Type Required Description
    db string / object No This object generates the local rest api.
    middleware string / object No Here you initialize the needed custom middleware
    injectors string / object No Helps to inject a route configs for the existing routes
    rewriters string / object No Helps to set route rewriters
    store string / object No Helps to store values and share between routes

    rewriter

    Sets the route rewrites and return the router of the rewriters;

    const rewriters = mockServer.rewriter("./rewriters.json");
    app.use(rewriters);

    Params

    Name Type Required Description
    rewriters string / object No Give the Rewrites

    defaults

    returns the list of default middlewares. Also helps to host a static directory.

    const defaults = mockServer.defaults({ staticDir: "./public", readOnly: true });
    app.use(defaults);
    • options
      • staticDir path to static files
      • logger enable logger middleware (default: true)
      • bodyParser enable body-parser middleware (default: true)
      • noGzip disable Compression (default: false)
      • noCors disable CORS (default: false)
      • readOnly accept only GET requests (default: false)

    resources

    Sets the routes and returns the resources router.

    const resources = mockServer.resources(
      "./db.json",
      "./middleware.js",
      "./injectors.json",
      "./store.json"
    );
    app.use(resources);

    Params

    Name Type Required Description
    db string / object No This object generates the local rest api.
    middleware string / object No Here you initialize the needed custom middleware
    injectors string / object No Helps to inject a route configs for the existing routes
    store string / object No Helps to store values and share between routes

    defaultRoutes

    Returns router with some default routes.

    const defaultsRoutes = mockServer.defaultRoutes();
    app.use(defaultsRoutes);

    addDbData

    adds a new data to the existing db.

    mockServer.addDbData(db);

    Params

    Name Type Required Description
    db object No Give the new data to add to existing Db

    getDb

    Returns the routes

    const routes = mockServer.getDb(); // If param is not present return all the route values

    Params

    Name Type Required Description
    ids string[] No Give List of route ids
    routePaths string[] No Give List of routePaths

    startServer

    Returns a Promise of Server. - helps to start the app server externally

    const server = await mockServer.startServer(3000, "localhost");

    Params

    Name Type Required Description
    port number No Set custom Port
    host string No Set custom Host

    stopServer

    Returns a Promise of Boolean. - helps to stop the app server externally

    const isStopped = await mockServer.stopServer();

    resetServer

    Clears out all values and resets the server for a fresh start. By default this method will be called on mockServer.stopServer() method.

    mockServer.resetServer();

    pageNotFound

    It is a middleware to handle a page not found error. Please use it at the end of all routes.

    app.use(mockServer.pageNotFound);

    errorHandler

    It is a middleware to handle a any error occur in server. Please use it at the end of all routes.

    app.use(mockServer.errorHandler);

    Setters

    set the db, middleware, injectors, rewriters, config, store

    mockServer.setData(db, middleware, injectors, rewriters, store, config);
    
    //or
    
    mockServer.setConfig(config);
    mockServer.setMiddleware(middleware);
    mockServer.setInjectors(injectors);
    mockServer.setRewriters(rewriters);
    mockServer.setStore(store);
    mockServer.setDb(Db, Injectors, options, entryCallBack, finallCallback);

    Params

    The same as the MockServer

    Variables

    Other useful variables.

    // Please avoid directly modify or setting values to these variable.
    // Use Setter method to modify or set any values to these variables.
    const app = mockServer.app;
    const server = mockServer.server;
    const router = mockServer.router;
    const data = mockServer.data;
    
    const db = mockServer.db;
    const middleware = mockServer.middleware;
    const injectors = mockServer.injectors;
    const rewriters = mockServer.rewriters;
    const config = mockServer.config;
    const store = mockServer.store;
    const initialDb = mockServer.initialDb;
    const initialStore = mockServer.initialStore;

    Validators

    These helps to return a valid data from provided file path or object.

    // called only when the given data is in .Har format and called at each entry
    const entryCallback = (entry, routePath, routeConfig) => {
      return { [routePath]: routeConfig };
    };
    // called only when the given data is in .Har format and called at end of the entry loop
    const finalCallBack = (data, db) => {
      return db; // what ever you return here will be given back
    };
    
    const options = {
      reverse: true, // If true the db will be generated in reverse order
    };
    
    const db = mockServer.getValidDb(
      "db.json",
      "injectors.json",
      options,
      entryCallback,
      finalCallBack
    );
    const middleware = mockServer.getValidMiddleware(middleware);
    const injectors = mockServer.getValidInjectors(injectors);
    const rewriters = mockServer.getValidRewriters(rewriters);
    const config = mockServer.getValidConfig(config);
    const store = mockServer.getValidStore(store);

    Author

    Sivaraman - sendmsg2siva.siva@gmail.com

    License

    MIT

    Install

    npm i @r35007/mock-server-lite

    DownloadsWeekly Downloads

    9

    Version

    1.0.1

    License

    MIT

    Unpacked Size

    377 kB

    Total Files

    49

    Last publish

    Collaborators

    • r35007