自定义mock数据,实现restful风格api

2020-06-15 15:13:53 浏览数 (1)

介绍两种方式做mock的server: - Express for mock - json-server

express for mock

因为我们要实现restful风格的api, 所以我们需要构建服务器。这里我们用到了express。

express

高度包容,快速而极简的 Node.js Web框架

express 一种保持最低程度规模的灵活 Node.js Web应用框架,它提供精简基本Web应用程序功能,而不会隐藏你了解Node.js功能。

1. 安装
代码语言:javascript复制
    npm init //创建一个package.json
   npm install express --save
2. 原理
2.1 http模块

Express建立在 Node.js 内置的http模块上。

如果用http模块生成服务器如下:

代码语言:javascript复制
    var http = require('http');
   var app = http.createServer(function(request, response) {
       response.writeHead(200, {"Content-Type": "text/plain"});
       response.end("Hello world");
   });
   app.listen(3000, "localhost");

express封装(核心是对http模块的再包装)

代码语言:javascript复制
    var express = require('express');
   var app = express();
   app.get('/', function(req, res) {
       res.send("Hello world");
   });
   app.listen(3000):

Express 框架等价于在http模块之上,加了一个中间层.

2.2 中间件

middleware 就是处理HTTP请求的函数。其特点就是,一个中间件处理完,再传递给下一个中间件。

从本质上讲,一个express就是在调用各种中间件。 中间件的种类:

  • 应用级中间件
    1. app.use() use是express注册中间件的方法,返回一个函数。
    2. app.METHOD() METHOD是http请求方法,即HTTP动词都是Express的方法。
  • 路由级中间件
代码语言:javascript复制
var router = express.Router();
  • 错误处理中间件 使用四个参数
代码语言:javascript复制
app.use(function(err, req, res, next) {
    console.log(err.stack);
    res.status(500).send('Something broke!');
})
  • 定义处理错误中间件必须使用4个参数,即使不需要next对象,也必须在签名中声明它。
  • 内置中间件 从4.x版本开始,Express已经不再依赖Connect了,除了express.static, Express以前内置的中间件现在已经全部单独作为模块安装使用了。 express.static是Express唯一内置的中间件。
代码语言:javascript复制
var options = {
  dotfiles: 'ignore',
  etag: false,
  extensions: ['htm', 'html'],
  index: false,
  maxAge: '1d',
  redirect: false,
  setHeaders: function (res, path, stat) {
    res.set('x-timestamp', Date.now());
  }
};

app.use(express.static('public', options));

每个目录可有多个静态目录:

代码语言:javascript复制
    app.use(express.static('public'));
   app.use(express.static('uploads'));
   app.use(express.static('files'));
  • 第三方中间件 通过使用第三方中间件从而为express应用增加更多功能。
代码语言:javascript复制
npm install cookie-parser //先安装所需node模块var cookieParser = require('cookie-parser');
app.user(cookieParser());
Router
代码语言:javascript复制
路由是由一个 URI、HTTP 请求(GET、POST等)和若干个句柄组成,它的结构如下: app.METHOD(path, [callback...], callback), app 是 express 对象的一个实例, METHOD 是一个 HTTP 请求方法, path 是服务器上的路径, callback 是当路由匹配时要执行的函数。
  • 基本路由
代码语言:javascript复制
    var express = require('express');
   var app = express();   // respond with "hello world" when a GET request is made to the homepage   app.get('/', function(req, res) {
     res.send('hello world');
   });
  • 路由方法
代码语言:javascript复制
// GET method route
    app.get('/', function (req, res) {
      res.send('GET request to the homepage');
    });

    // POST method route
    app.post('/', function (req, res) {
      res.send('POST request to the homepage');
    });

    //....get, post, put, head, delete, options, trace, copy....

    app.all('/secret', function (req, res, next) {
      console.log('Accessing the secret section ...');
      next(); // pass control to the next handler
    });
  • app.all()是一个特殊的路由方法,没有任何http方法与其对应,它的作用是对于一个路径上的所有请求加载中间件。
  • 路由路径

他可以是字符串,字符串模式,正则表达式。

代码语言:javascript复制
    app.get('/', function(req, res) {...}); // 匹配根路径的请求
   app.get('/about', function(req, res) {...});// 匹配 /about 路径的请求
   app.get('/help.json', function(req, res) {...});// 匹配 /random.text 路径的请求   app.get('/ab?cd', function(req, res) {...});// 匹配 acd 和 abcd
   app.get('/ab cd', function(req, res) {...});// 匹配 abcd、abbcd、abbbcd等
   app.get('/ab * cd', function(req, res) {...});// 匹配 abcd、abxcd、abRABDOMcd、ab123cd等
   app.get('/ab(cd)?e', function(req, res) {...});// 匹配 /abe 和 /abcde   app.get('/a/', function(req, res) {...});// 匹配任何路径中含有 a 的路径:
   app.get('/.*fly$', function(req, res) {...});// 匹配 butterfly、dragonfly,不匹配 butterflyman、dragonfly man等

Express路由路径用的是path-to-regexp

  • 路由句柄 路由句柄有多种形式,可以是一个函数、一个函数数组,或者是两者混合,
代码语言:javascript复制
    var cb0 = function (req, res, next) {
     console.log('CB0');
     next();
   }   var cb1 = function (req, res, next) {
     console.log('CB1');
     next();
   }   var cb2 = function (req, res) {
     res.send('Hello from C!');
   }   app.get('/example/c', [cb0, cb1, cb2]);
   app.get('/example/c', [cb0, cb1], function(req, res) {   });
  • app.route()

创建路由路径的链式句柄

代码语言:javascript复制
    app.route('/book')
       .get(function(req, res) {
           res.send('Get a random book');
       })
       .post(function(req, res) {
           res.send('Add a book');
       })
       .put(function(req, res) {
           res.send('Update the book');
       });
  • express.Router

中间件

代码语言:javascript复制
//birds.jsvar express = require('express');
var router = express.Router();// 该路由使用的中间件
router.use(function timeLog(req, res, next) {
 console.log('Time: ', Date.now());
 next();
});
// 定义网站主页的路由
router.get('/', function(req, res) {
 res.send('Birds home page');
});
// 定义 about 页面的路由
router.get('/about', function(req, res) {
 res.send('About birds');
});module.exports = router;
代码语言:javascript复制
var birds = require('./birds');
...
app.use('/birds', birds);

应用即可处理发自 /birds 和 /birds/about 的请求

faker.js

用来mock数据,有自己的API,而且非常丰富

install
代码语言:javascript复制
npm i faker --savevar faker = require('faker');var randomName = faker.name.findName();
var randomEmail = faker.internet.email();
var randomCard = faker.helpers.createCard();
API

Faker.fake()

代码语言:javascript复制
var json = faker.fake("{{name.lastName}}, {{name.firstName}}, {{name.suffix}}");
console.log(json) //"Marks, Dean Sr."
Localization

default value is set to English

代码语言:javascript复制
faker.locale = "zh_CN";

demo

代码语言:javascript复制
var Faker  = require('faker');
var _ = require('lodash');
Faker.locale="zh_CN";
console.log(Faker, 'faker');var data = [];
_.times(10, function() {
   var temp = {
       name: Faker.name.findName(),
       emial: Faker.internet.email(),
       website: Faker.internet.url(),
       image: Faker.image.avatar()
   };
   data.push(temp);
})module.exports = {
   errcode: 0,
   errmsg: 'success',
   data: {
       list: data
   }
}

json-server for mock

install

代码语言:javascript复制
 npm install json-server --save

创建数据文件

代码语言:javascript复制
//db.json
{
   "posts": [
       {
           id: 1,
           title: 'json-server'
       },
       {
           id: 2,
           title: "mock"
       }
   ],
   "comments": [
       {
           id: 1,
           content: "very good !",
           postId: 1
       }
   ],
   "profile": {
       "name": "yulong"
   }
}

运行

安装完后,在本目录下创建一个xx.json,然后执行

代码语言:javascript复制
json-server db.json -p 3003

默认端口是3000

代码语言:javascript复制
json-server [options] <source>
Options:
 --config, -c       指定 config 文件                  [默认: "json-server.json"]
 --port, -p         设置端口号                                   [default: 3000]
 --host, -H         设置主机                                   [默认: "0.0.0.0"]
 --watch, -w        监控文件                                           [boolean]
 --routes, -r       指定路由文件
 --static, -s       设置静态文件
 --read-only, --ro  只允许 GET 请求                                    [boolean]
 --no-cors, --nc    禁止跨域资源共享                                   [boolean]
 --no-gzip, --ng    禁止GZIP                                          [boolean]
 --snapshots, -S    设置快照目录                                     [默认: "."]
 --delay, -d        设置反馈延时 (ms)
 --id, -i           设置数据的id属性 (e.g. _id)                     [默认: "id"]
 --quiet, -q        不输出日志信息                                     [boolean]
 --help, -h         显示帮助信息                                       [boolean]
 --version, -v      显示版本号                                         [boolean]

然后访问: http://locahost:3000/posts

代码语言:javascript复制
[
   {
       id: 1,
       title: 'json-server'
   },
   {
       id: 2,
       title: "mock"
   }
]

0 人点赞