mock-rest-middleware
v2.3.1
Published
Simple middleware for mocking REST services
Downloads
57
Maintainers
Readme
Mock REST Middleware
Simple middleware for mocking REST services
- Simulates a RESTful JSON API. Uses a transient data store that can be interacted with through a typical REST API.
- Simple and fast to build the services.
- Middleware that plugs into any Connect, Express, or compatible server.
- Customizable to change or extend how the API works.
Usage
Node.js v6 or higher is required.
First install the module:
npm install mock-rest-middleware
Then use it in your Connect/Express app:
var connect = require('connect');
var http = require('http');
var createMocks = require('mock-rest-middleware');
var mocks = createMocks();
var bookCollection = [];
var movieCollection = [];
mocks.addResource('/books', bookCollection);
mocks.addResource('/movies', movieCollection);
var app = connect();
mocks.useWith(app);
http.createServer(app);
API
addResource(path, collection, options)
Adds a new resource at the given path. The path can include placeholders, e.g. /foo/:someId
.
Note: The path cannot contain an :id
placeholder; that is reserved for use by the module.
The collection argument should be the array of data that the endpoint begins with.
The optional options
object may contain:
idKey
-- The name of the ID field. If not specified, the library will use theid
field, or the first field that ends inId
, or the first field.collectionKey
-- The property name for the collection response (defaultitems
).countKey
-- The property name for the collection response (defaulttotal
).offsetParam
-- The name(s) to use for the "offset" query parameter when retrieving a collection subset (string or array of strings, defaultoffset
).limitParam
-- The name(s) to use for the "limit" query parameter when retrieving a collection subset (string or array of strings, defaultlimit
).queryParam
-- The name(s) to use for the query parameter when performing a collection text search (string or array of strings, default['q', 'query']
).sortByParam
-- The name(s) to use for the field parameter when sorting collection results (string or array of strings, default['sortBy']
).sortDirParam
-- The name(s) to use for the direction parameter when sorting collection results (string or array of strings, default['sortDir']
).
These options can also be changed in the rule object after it is created.
The following properties can only be changed on the rule object after it is created.
paramFilters
-- An array of filters used when filtering the collection duringGET /path
. Each item in the array should have the following pattern:{ param: 'pathOrQueryParamName', filter: function(item, paramValue) { /* return true if the item passes the test */ } }
These filters are added to the normal filtering for
GET /path?params
-- i.e., it is intersected with the other results.prefilter
-- A function that runs before every request. It receives the path+query parameters, the request body (parsed as JSON), and the raw http.ClientRequest. It should return the new input in the format{ params: paramsObject, data: bodyDataObject }
for the normal routine to use. Note you should clone any objects you change, rather than modifying them.postfilter
-- A function that runs after every request. It receives the original path+query parameters (unfiltered fromprefilter
), the response (in{ status: httpResponseCode, data: responseObject, headers: headersObject }
), and the raw http.ClientRequest. It should return the new response (in the same status+response format). If excluded,status
defaults to200
andheaders
defaults to{ 'Content-Type': 'application/json' }
.handler
-- A function to use for all requests. Overrides all of the default handling! You'll need to check the request method and run the prefilter/postfilter functions yourself. Receives the same arguments asprefilter
. It should return a response in the same format aspostfilter
.
Returns the new MiddlewareRule object. You can add new methods to it (or extend it) for extra/custom functionality.
getMiddleware()
Returns an array of middleware that can be used in a Connect-compatible server.
logger.enable()
logger.disable()
Turns logging on or off (begins disabled). Useful when debugging your rules.
useWith(app)
Injects the middleware into the given Connect-compatible app.
REST Endpoints
Given a base path of /example
, the middleware creates the mock endpoints:
/_reset
(any method) -- Special endpoint to return all collections to their original data.GET /example
-- Returns the full collection, in the format:{ items: [ // array of objects ], total: 20 // the number of items }
GET /example?params
-- Returns a filtered collection. Same as above, but:offset
(zero-based) andlimit
parameters will return only a subset of the collection. Note: the returnedtotal
will remain the size of full collection.query
orq
parameters will perform a partial text search. Note: All values are converted to strings for matching.sortBy
andsortDir
will sort the results by the top-level property specified insortBy
, in the direction specified bysortDir
-- either case-insensitiveasc
(the default), ordesc
for reversed sorting.- Any other parameter will filter the collection using that parameter as the field name, and performing an exact string match against the value.
GET /example/:id
-- Returns a single item from the collection. Returns a 404 if no match.HEAD (anything)
-- Same asGET
, but doesn't return the body.POST /example
-- Adds a new item with the passed JSON body. Returns the new item.PUT /example
-- Replaces the entire collection with the passed JSON body. Returns the new collection.PUT /example/:id
-- Replaces the matching resource with the passed JSON body. Returns the new item. Returns a 404 if no item with that ID exists.DELETE /example
-- Empties the collection. Returns the empty collection.DELETE /example/:id
-- Removes the matching resource from the collection. Returns the deleted resource. Returns a 404 if no item with that ID exists.PATCH /example
-- Extends the matching resources using the given array of objects. It looks for an ID in each element of the array to lookup the existing items in the collection.PATCH /example/:id
-- Extends the matching resource with the given object.
Don't forget to set Content-Type: application/json
in your requests. Form data (Content-Type: application/x-www-form-urlencoded
) are also supported.
Tips
Turn on logging (with
logging.enable()
) to debug your rules.Call the
/_reset
endpoint to reset your data.Remember that the collection passed to
addResource()
must be an array (or array-like object), not an object.The middleware uses the same path matching as Connect -- that is, the path only has to match the beginning of the URL path. The middleware uses the first resource that matches, so more specific paths must be defined first:
// In this example, /passwords/validate must come first. // Otherwise the /passwords endpoint will always be used instead. mockMiddleware.addResource('/passwords/validate', []); mockMiddleware.addResource('/passwords', []);
Start with the built-in behavior. If needed, tweak the
addResource()
options (idKey
,collectionKey
, etc). Minor changes to the default behavior can be achieved withparamFilters
,prefilter
, andpostfilter
. Individual endpoints can be overridden by redefining the MiddlewareRule methods (addItem()
,deleteCollection()
, etc). Finally, you can set ahandler()
method to override all of the endpoints.For testing, you can create a simple server (see Usage) to run your mocks. Then you can test the endpoints using any HTTP client (such as curl, http-console, or Postman).
Always modify a resource's collection. Don't replace it.
yourRule.handler = function() { // BAD. These create new arrays that replace the collection. this.collection = this.collection.map(function(item) { /* ... */ }); this.collection = this.collection.filter(function(item) { /* ... */ }); // GOOD. This modifies the array in place. this.collection.forEach(function(item, i) { this.collection[i].someProperty = true; }, this); };
Need to share a collection between multiple endpoints? You can point to another collection during a reset:
var animalRule = mockMiddleware.addResource('/animals', animalCollection); var petRule = mockMiddleware.addResource('/pets', []); petRule.reset = function() { this.collection = animalRule.collection; }; petRule.reset();
In your project, use the included
test-mock-server.js
script to start a test server using your mocks:./node_modules/.bin/test-mock-server ./mocks
Contributing
Please add tests and maintain the existing styling when adding and updating the code.
npm run lint # run linting
npm test # run tests
License
Copyright 2016 Jack Henry & Associates Inc.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.