JSON Server在快速开发过程中的使用

在开发过程中,接口多半是滞后于页面开发的。利用JSON Server快速搭建模拟返回REST风格的后台数据,保证前后端开发的分离。前后端开发只要设定好接口以及数据的定义,剩下的就可以各自开发,最后集成测试。

JSON Server 作为工具,基于Express开发,而且它足够简单,写少量数据,即可使用,支持CORS和JSONP跨域请求,支持GET, POST, PUT, PATCH 和 DELETE 方法,更提供了一系列的查询方法,如limit,order等

安装

npminstalljson-server-g

全局安装,可以在命令行下独立执行。安装完成后可以用 json-server -h 命令检查是否安装成功。

json-server[options]

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]

启动

创建一个目录server,在该目录下创建一个json文件,db.json.

{

"list": [

    {

"id":1,

"name":"张三",

"tel":"15223810923"

    },

    {

"id":2,

"name":"李四",

"tel":"15223810923"

    },

    {

"id":3,

"name":"王二",

"tel":"15223810923"

    },

    {

"id":4,

"name":"陈五",

"tel":"15223810923"

    },

    {

"name":"赵六",

"tel":"123454323",

"id":5

    },

    {

"name":"赵六",

"tel":"123454323",

"id":6

    },

    {

"name":"赵六",

"tel":"123454323",

"id":7

    }

  ],

"users": [

    {

"id":1,

"name":"陈五",

"sex":"male",

"tel":"12345678",

"auther":{

"name":"陈五",

"age":"25"

      }

    },

    {

"id":2,

"name":"王二",

"sex":"male",

"tel":"15223810923",

"auther":{

"name":"王二",

"age":"22"

      }

    }

  ],

"user": {

"id":1,

"name":"陈五",

"tel":"15223810923"

    }

    ,

"posts": [

{"id":1,"title":"json-server","author":"typicode"}

  ],

"comments": [

{"id":1,"body":"some comment","postId":1}

  ],

"profile": {"name":"typicode"}

}

在server目录下执行

json-serverdb.json-p3003

打开浏览器,http://localhost:3003,查看页面。如果要监控json文件的变化,启动的时候加上参数--watch。

支持的方法

以APIhttp://localhost:3003/list 为例

GET /list 获取列表

GET /list/1 获取id=1的数据

POST /list 创建一个项目

PUT /list/1 更新一个id为1的数据

PATCH /list/1 部分更新id为1的数据

DELETE /list/1 删除id为1的数据

对于对象,例如http://localhost:3003/user,地址是相同的。

GET /user

POST /user

PUT /user

PATCH /user

当你发送POST,PUT,PATCH 或者 DELETE请求时,变化会自动安全的保存到你的db.json文件中。

你的请求体body应该是封闭对象。比如{"name": "Foobar"}

id不是必须的,在PUT或者PATCH方法中,任何的id值将会被忽略。

在POST请求中,id是可以被添加的,如果该值没有没占用,会使用该值,否则自动生成。

POST,PUT或者PATCH请求应该包含一个Content-Type:application/json的header,来确保在请求body中使用json。

高级查找

Filter

用.来访问深层属性,比如

GET /users?set=male&tel=12345678

GET /list?id=1&id=2

GET /users?author.age=25

Paginate

使用 _page 和可选的 _limit来对返回数据定制(不设置默认返回10条)。

在返回的header中,有一个属性Link,里面会有first, prev, next and last links。

header中还有一个属性X-Total-Count,用来存储满足条件的数据的条数。

GET /list?_page=1

GET /list?_page=2&_limit=2

Sort

使用 _sort 和 _order (默认是ascending)

GET /list?_sort=id&_order=asc

对于多字段的排序,可以参考下面的格式:

GET /list?_sort=id,name&_order=desc,asc

Slice

使用_start和_end或_limit(一个 X-Total-Count 自定义Header在Response里面),就像数据的slice的方法一样。

GET /list?_start=2&_end=5

GET /list?_start=2&_limit=5

Operators

用 _gte或_lte来得到一个范围。

GET /list?id_gte=2&id_lte=5

用_ne来不包含(exclude)一个值

GET /posts?id_ne=1

GET /list?id_gte=2&id_lte=5&id_ne=4

用 _like 来 filter (RegExp 支持)

GET /list?name_like=王

search

使用q

GET /list?q=1

Relationships

关联子资源, 添加_embed

GET/posts?_embed=comments

GET/posts/1?_embed=comments

包含父资源, 添加_expand

GET/comments?_expand=post

GET/comments/1?_expand=post

要获得或创建nested resources(默认一层,多层的话,自定义routes)

GET/posts/1/comments

POST /posts/1/comments

Database

GET/db

Homepage

返回默认的index文件,或者./public目录

GET/

拓展功能

静态文件服务器

你也可以用json server来托管你的静态HTML,JS和CSS文件。仅仅需要简单的创建一个./public目录。或者用--static来指定一个不同的静态文件路径。

mkdirpublic

echo'hello world'>public/index.html

json-server db.json

json-server db.json --static./some-other-dir

改变端口号

你可以改变端口号使用--port

$ json-server --watch db.json --port3004

从任何地方访问

你可以使用CORS和JSONP从任何地方访问你的API。

远程文件

你可以加载远程文件

$ json-serverhttp://example.com/file.json

$ json-serverhttp://jsonplaceholder.typicode.com/db

生成随机数据

使用js文件替代json文件,可以动态生成数据。还可以借助其他模块生成,比如Faker, Casual, Chance or JSON Schema Faker。

// index.js

module.exports =() =>{

constdata = {users: [] }

// Create 1000 users

for(leti =0; i <1000; i++) {

data.users.push({id: i,name:`user${i}`})

  }

returndata

}

$ json-server index.js

HTTPS

有很多方式在开发中使用SSL。一个简单的方式就是使用hotel.

自定义路由

创建routes.json文件。注意每个路由文件应该以/开头。

{

"/api/*":"/$1",

"/:resource/:id/show":"/:resource/:id",

"/posts/:category":"/posts?category=:category",

"/articles\\?id=:id":"/posts/:id"

}

启动json server时加上--routes选项。

json-serverdb.json--routesroutes.json

现在你可以用附加路由访问资源了。

/api/posts# → /posts

/api/posts/1# → /posts/1

/posts/1/show# → /posts/1

/posts/javascript# → /posts?category=javascript

/articles?id=1# → /posts/1

增加中间件

命令行中,你可以使用--middlewares选项。

// hello.js

module.exports =(req, res, next) =>{

res.header('X-Hello','World')

  next()

}

json-serverdb.json --middlewares ./hello.js

json-serverdb.json --middlewares ./first.js ./second.js

CLI usage

你可以将设置放在json-server.json配置文件里。

将json server作为一个模块

在项目中,如何你需要增加认证,验证或者其他功能,你可以将json server作为一个模块,合并其他的Express中间件。

一个简单的例子

// server.js

constjsonServer =require('json-server')

constserver = jsonServer.create()

constrouter = jsonServer.router('db.json')

constmiddlewares = jsonServer.defaults()

server.use(middlewares)

server.use(router)

server.listen(3003, () => {

console.log('JSON Server is running')

})

$ node server.js

你提供给jsonServer.router方法的路径,是相对于你的node的。

如果你从另外一个路径运行上面的代码,最好用绝对路径。

constpath =require('path')

constrouter = jsonServer.router(path.join(__dirname,'db.json'))

对于内存数据库,传递一个对象给jsonServer.router()。注意,jsonServer.router()可以被用在一个已经存在的Express项目中。

自定义路由动态数据的例子

//db.js

letMock  =require('mockjs');

letRandom = Mock.Random;

module.exports =function(){

vardata = {

news: [],

type:{

"a":"a",

"b":"b",

      }

  };


varimages = [1,2,3].map(x=>Random.image('200x100', Random.color(), Random.word(2,6)));


for(vari =0; i <10; i++) {


varcontent = Random.cparagraph(0,10);


    data.news.push({

id: i,

title: Random.cword(8,20),

desc: content.substr(0,40),

tag: Random.cword(2,6),

views: Random.integer(100,5000),

images: images.slice(0,Random.integer(1,3))

    })

  }

returndata

}

//server.js

constpath =require('path');

constconfig =require('./config');

constjsonServer =require('json-server');

construles =require('./routes');

constdbfile =require(config.DB_FILE);

constip = config.SERVER;

constport = config.PORT;

constdb_file = config.DB_FILE;

constserver = jsonServer.create();

constrouter = jsonServer.router(dbfile());

constmiddlewares = jsonServer.defaults();

server.use(jsonServer.bodyParser);

// Set default middlewares (logger, static, cors and no-cache)

server.use(middlewares);

server.use((req, res, next) =>{

res.header('X-Hello','World');

next();

})

router.render =(req, res) =>{

  res.jsonp({

body: res.locals.data,

code:0

  })

}

server.use("/api",router);

server.use(jsonServer.rewriter(rules));

server.use(router);

server.listen({

host: ip,

port: port,

},function(){

console.log(JSON.stringify(jsonServer));

console.log(`JSON Server is running in http://${ip}:${port}`);

});

//routes.js

module.exports= {

"/api/":"/",

"/:id":"/news/:id",

"/news/show/:id":"/news/:id",

"/topics/:id/show":"/news/:id"

}

添加一个路由输出query parameters

// Add custom routes before JSON Server router

server.get('/echo', (req, res) => {

  res.jsonp(req.query)

})

添加一个时间戳

支持post请求需要使用bodyParser

// To handle POST, PUT and PATCH you need to use a body-parser

// You can use the one used by JSON Server

server.use(jsonServer.bodyParser)

server.use((req, res, next) =>{

if(req.method ==='POST') {

req.body.createdAt =Date.now()

  }

// Continue to JSON Server router

  next()

})

添加控制

server.use((req, res, next) =>{

if(isAuthorized(req)) {// add your authorization logic here

next()// continue to JSON Server router

}else{

res.sendStatus(401)

}

})

修改response数据结构

需要override router.render方法。

// In this example, returned resources will be wrapped in a body property

router.render =(req, res) =>{

  res.jsonp({

body: res.locals.data

  })

}

自定义reponse状态码

// In this example we simulate a server side error response

router.render =(req, res) =>{

res.status(500).jsonp({

error:"error message here"

  })

}

Rewriter例子

添加rewrite rules,使用jsonServer.rewriter():

// Add this before server.use(router)

server.use(jsonServer.rewriter({

'/api/*':'/$1',

'/blog/:resource/:id/show':'/:resource/:id'

}))

MountingJSONServer on another endpoint example

更改挂载点

挂在/api上

server.use('/api', router)

你可能感兴趣的:(JSON Server在快速开发过程中的使用)