Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Connect middleware that creates mocks for REST APIs

License

NotificationsYou must be signed in to change notification settings

muratcorlu/connect-api-mocker

Repository files navigation

Build Statusnpm versioncodecovsemantic-release

connect-api-mocker is aconnect.js middleware that fakes REST API server with filesystem. It will be helpful when you try to test your application without the actual REST API server.

It works with a wide range of servers:connect,express,browser-sync,lite-server,webpack-dev-server. Also it can be used as a command line tool with the help ofcli-api-mocker.

Detailed article:https://medium.com/@muratcorlu/mocking-rest-endpoints-in-web-apps-easy-way-d4cd0e9db000

A presentation at AmsterdamJS'18 conference:https://www.youtube.com/watch?v=yF_8O4l-Ybc

Türkçe sunum için:https://www.youtube.com/watch?v=cVL8sesauCU

Installation

npm install connect-api-mocker --save-dev

Usage

Using withConnect

varhttp=require('http');varconnect=require('connect');varapiMocker=require('connect-api-mocker');varapp=connect();app.use('/api',apiMocker('mocks/api'));http.createServer(app).listen(8080);

Using withExpress

varexpress=require('express');varapiMocker=require('connect-api-mocker');varapp=express();app.use('/api',apiMocker('mocks/api'));app.listen(8080);

Using withBrowserSync

varbrowserSync=require('browser-sync').create();varapiMocker=require('connect-api-mocker');varrestMock=apiMocker('/api','mocks/api');browserSync.init({server:{baseDir:'./',middleware:[restMock,],},port:8080,});

Using withlite-server

bs-config.js file:

varapiMocker=require('connect-api-mocker');varrestMock=apiMocker('/api','mocks/api');module.exports={server:{middleware:{// Start from key `10` in order to NOT overwrite the default 2 middleware provided// by `lite-server` or any future ones that might be added.10:restMock,},},port:8080,};

Using with Grunt

You can use it withGrunt. After you installgrunt-contrib-connect add api-mocker middleware to your grunt config. Themocks/api folder will be served as REST API at/api.

module.exports=function(grunt){varapiMocker=require('connect-api-mocker');grunt.loadNpmTasks('grunt-contrib-connect');// Connect - Development server// Project configuration.grunt.initConfig({// Development serverconnect:{server:{options:{base:'./build',port:9001,middleware:function(connect,options){varmiddlewares=[];// mock/rest directory will be mapped to your fake REST APImiddlewares.push(apiMocker('/api','mocks/api'));// Static filesmiddlewares.push(connect.static(options.base));middlewares.push(connect.static(__dirname));returnmiddlewares;}}}}});}

After you can run your server withgrunt connect command. You will see/api will be mapped tomocks/api.

Using with Webpack

To use api mocker on yourWebpack projects, simply add a setup options to yourwebpack-dev-server options:

devServer.setup , This option is deprecated in favor of before and will be removed in v3.0.0.

  ...before:function(app){app.use(apiMocker('/api','mocks/api'));},  ...

Using with CRA

To use api mocker on yourcra projects, please installcustomize-cra andreact-app-rewired using npm to modify webpack config file:

npm install customize-cra react-app-rewired --save-dev

Then, create a file named config-overrides.js, override webpack config using below codes:

constapiMocker=require("connect-api-mocker"),{ overrideDevServer}=require("customize-cra");constdevServerConfig=()=>config=>{return{        ...config,before:(app,server)=>{//call cra before function to not break codeconfig.before(app,server);//Then add our mocker url and folderapp.use(apiMocker('/api','mocks/api'));}}}module.exports={devServer:overrideDevServer(devServerConfig())};

Finally, change our run method to from "react-scripts start" to "react-app-rewired start" in package.json file:

..."scripts":{"start":"react-app-rewired start",    ...}  ...

Using with other languages other than JavaScript

If you have a Python/Ruby/.NET etc. project and want to use that mocking functionality, you can usecli-api-mocker as a wrapper of connect-api-mocker for command line. With the help of cli-api-mocker, if you runmockit command, you will have a seperate web server that will handle your mocks as a REST API. Please look forcli-api-mocker readme for details.

Directory Structure

You need to use service names as directory name and http method as filename. Middleware will match url to directory structure and respond with the corresponding http method file.

Example REST service:GET /api/messages

Directory Structure:

_ api  \_ messages     \_ GET.json

Example REST service:GET /api/messages/1

Directory Structure:

_ api  \_ messages     \_ 1        \_ GET.json

Example REST service:POST /api/messages/1

Directory Structure:

_ api  \_ messages     \_ 1        \_ POST.json

Example REST service:DELETE /api/messages/1

Directory Structure:

_ api  \_ messages     \_ 1        \_ DELETE.json

Custom responses

If you want define custom responses you can usejs files with a middleware function that handles requests.

Example REST service:POST /api/messages

Directory Structure:

_ api  \_ messages     \_ POST.js

POST.js file:

module.exports=function(request,response){if(!request.get('X-Auth-Key')){response.status(403).send({});}else{response.sendFile('POST.json',{root:__dirname});}}

POST.js file for non ExpressJS server:

constfs=require('fs');constpath=require('path');module.exports=(request,response)=>{if(!request.get('X-Auth-Key')){response.statusCode=403;response.end();}else{constfilePath=path.join(__dirname,'POST.json');conststat=fs.statSync(filePath);response.writeHead(200,{'Content-Type':'application/json','Content-Length':stat.size});constreadStream=fs.createReadStream(filePath);// We replaced all the event handlers with a simple call to readStream.pipe()readStream.pipe(response);}}

Another Example: Respond different json files based on a query parameter:

  • Request to/users?type=active will be responded bymocks/users/GET_active.json
  • Request to/users will be responded bymocks/users/GET.json

GET.js file:

constfs=require('fs');constpath=require('path');module.exports=function(request,response){lettargetFileName='GET.json';// Check is a type parameter existif(request.query.type){// Generate a new targetfilename with that type parametertargetFileName='GET_'+request.query.type+'.json';}constfilePath=path.join(__dirname,targetFileName);// If file does not exist then respond with 404 headertry{fs.accessSync(filePath);}catch(err){returnresponse.status(404);}// Respond with filePathresponse.sendFile(filePath);}

GET.js file for non ExpressJS server:

consturl=require('url');constfs=require('fs');constpath=require('path');module.exports=function(request,response){lettargetFileName='GET.json';consttypeQueryParam=url.parse(request.url,true).query.type;// Check is a type parameter existif(typeQueryParam){// Generate a new targetfilename with that type parametertargetFileName='GET_'+typeQueryParam+'.json';}varfilePath=path.join(__dirname,targetFileName);// If file does not exist then respond with 404 headertry{fs.accessSync(filePath);}catch(err){response.statusCode=404;response.end();return;}conststat=fs.statSync(filePath);response.writeHead(200,{'Content-Type':'application/json','Content-Length':stat.size});constreadStream=fs.createReadStream(filePath);// We replaced all the event handlers with a simple call to readStream.pipe()readStream.pipe(response);}

Helper functions for custom responses

Connect-Api-Mocker also presents a bunch of helper functions to speed up writing simple custom responses. There are:

  • status(statusCode): Set status code of response
  • notFound(message?): Set status code as 404 and optionally sends message
  • created(): Sets status code as 201
  • success(): Sets status code as 200
  • delay(duration): Delays the request by given duration(in ms).
  • json(data|callback(req,res)): Send given JSON object as response.
  • file(filePath): Responds with the content of file in given path(full path)
  • type(contentType): Sets content-type header.
  • end(body): Ends request and optionally sends the string output

You can use these functions in custom responses, like:

const{ notFound}=require('connect-api-mocker/helpers');module.exports=notFound('Page is not found');

Also you can combine multiple functions:

const{ delay, created, json}=require('connect-api-mocker/helpers');module.exports=[delay(500),created(),json({success:true})];

json middleware also accepts a callback that has request and response objects as parameters:

const{ json}=require('connect-api-mocker/helpers');module.exports=[json(req=>({id:req.params.userId,success:true}))];

Another example to return image as response:

const{ type, file}=require('connect-api-mocker/helpers');// Assuming a file named GET.png exists next to this fileconstfilePath=path.join(__dirname,'./GET.png');module.exports=[type('image/png'),file(filePath)];

Wildcards in requests

You can use wildcards for paths to handle multiple urls(like for IDs). If you create a folder structure likeapi/users/__user_id__/GET.js, all requests like/api/users/321 or/api/users/1 will be responded by custom middleware that defined in yourGET.js. Also id part of the path will be passed as a request parameter named asuser_id to your middleware. So you can write a middleware like that:

api/users/__user_id__/GET.js file:

module.exports=function(request,response){response.json({id:request.params.user_id});}

You can also defineANY.js orANY.json files that catch all methods.

api/users/__user_id__/ANY.js file:

module.exports=function(request,response){response.json({id:request.params.user_id,method:request.method});}

XML Support

Api Mocker also can handle XML responses. As you can see, for custom responses, it's not an issue. Because you are completely free about responses in custom responses. But for simple mocks, api mocker try to find a json file by default. You can set that behaviour astype in api mocker configuration:

app.use('/user-api',apiMocker({target:'other/target/path',type:'xml'}));

If you usexml as type, api mocker should look formocks/users/GET.xml file for a request to/users. Also you can useauto for type:

app.use('/user-api',apiMocker({target:'other/target/path',type:'auto'}));

In that case, api mocker will look forAccept header in the request to determine response format. So, if you make a request with aAccept: application/json header, it'll try to send a response with ajson file. If you make a request with aAccept: application/xml header, it'll try to send a response with anxml file.

Defining multiple mock configurations

You can use apiMocker multiple times with your connect middleware server. In example below, we are defining 3 mock server for 3 different root paths:

app.use('/api/v1',apiMocker('target/path'));app.use('/user-api',apiMocker({target:'other/target/path'}));app.use(apiMocker('/mobile/api',{target:'mocks/mobile'});

Next on not found option

If you have some other middlewares that handles same url(a real server proxy etc.) you can setnextOnNotFound option totrue. In that case, api mocker doesnt trigger a404 error and pass request to next middleware. (default isfalse)

apiMocker('/api',{target:'mocks/api',nextOnNotFound:true});

With that option, you can mock only specific urls simply.

Body parser

By default request body is pre-processed withbody-parser. Default body-parser configuration uses JSON parser. Example belows configures usage ofjson (default) parser. In order to disable default pre-processing setbodyParser option tofalse.

apiMocker('/text',{target:'test/mocks',bodyParser:false})

In order to modify default body-parser behaviour usebodyParser object.bodyParser object supports configuration of

  • parser type viatype setting.
  • parser options viaoptions setting.

Supported parsers and corresponding options can be foundhere

Example belows configures usage oftext parser for requests withcontent-type=application/vnd.custom-type

apiMocker('/text',{target:'test/mocks',bodyParser:{type:'text',options:{type:'application/vnd.custom-type'}}})

Logging

If you want to see which requests are being mocked, set theverbose option either totrue or provide your own function.

apiMocker('/api',{target:'mocks/api',verbose:({ req, filePath, fileType})=>console.log(`Mocking endpoint${req.originalUrl} using${filePath}.${fileType}.`)});

About

Connect middleware that creates mocks for REST APIs

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors17


[8]ページ先頭

©2009-2026 Movatter.jp