博客地址:有實時的目錄閱讀體驗更好javascript
#Linxu/Mac os
sudo npm install json-server -g
#window
npm install json-server -g
複製代碼
新建db.json用於測試json-server db.json -p 3003
,-p 指定端口號爲3003html
{
"news":[
{
"id": 1,
"title": "曹縣宣佈昨日晚間登日成功",
"date": "2016-08-12",
"likes": 55,
"views": 100086
},
{
"id": 2,
"title": "長江流域首次發現海豚",
"date": "2016-08-12",
"likes": 505,
"views": 9800
}
],
"comments":[
{
"id": 1,
"news_id": 1,
"data": [
{
"id": 1,
"content": "支持黨中央決定"
},
{
"id": 2,
"content": "抄寫黨章勢在必行!"
}
]
}
]
}
複製代碼
/usr/bin/env: node: No such file or directory
解決java
ln -s /usr/bin/nodejs /usr/bin/node
複製代碼
json-server requires at least version 6 of Node, please upgrade
解決node
sudo npm cache clean -f
sudo npm install -g n
sudo n stable
複製代碼
db.json 目錄下新建package.json
, 運行npm run mock
git
{
"scripts": {
"mock": "json-server db.json --port 3003"
}
}
複製代碼
Content-Type: application/json
不然返回的雖然是200 OK,可是不會修改數據http://localhost:3003/db ==> db.json
http://localhost:3003/news ==> news節點github
Postman向http://localhost:3003/news
傳參數web
"id": 3,
"title": "我是新加入的新聞",
"date": "2016-08-12",
"likes": 0,
"views": 0
複製代碼
json-server 後臺反應chrome
POST /news?id=3&title=%E6%88%91%E6%98%AF%E6%96%B0%E5%8A%A0%E5%85%A5%E7%9A%84%E6%96%B0%E9%97%BB&date=2016-08-12&likes=0&views=0 201 2.622 ms - 13
複製代碼
使用url encode 解碼點擊UrlDecode解碼npm
POST /news?id=3&title=我是新加入的新聞&date=2016-08-12&likes=0&views=0 201 2.622 ms - 13
複製代碼
json-server 後臺打印json
PUT /news?title=我是新加入的新聞&date=2016-08-12&likes=55&views=100086 404 2.430 ms - 2
複製代碼
/mock/db.js
module.exports = function() {
var data = { users: [] }
// Create 1000 users
for (var i = 0; i < 1000; i++) {
data.users.push({ id: i, name: 'user' + i })
}
return data
}
複製代碼
運行
json-server db.js -p 3003
複製代碼
訪問
http://localhost:3003/users
複製代碼
返回
[
{
"id": 0,
"name": "user0"
},
{
"id": 1,
"name": "user1"
}
......
]
複製代碼
安裝mockjs 在 /mock
目錄下安裝
npm install mockjs --save
複製代碼
示例:返回100條新聞數據
// # /mock/db.js
let Mock = require('mockjs');
let Random = Mock.Random;
module.exports = function() {
var data = {
news: []
};
var images = [1,2,3].map(x=>Random.image('200x100', Random.color(), Random.word(2,6)));
for (var i = 0; i < 100; i++) {
var content = 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))
})
}
return data
}
複製代碼
運行
json-server db.js -p 3000
複製代碼
訪問http://localhost:3000/news
返回
[
{
"id": 0,
"title": "元小總小把清保住影辦歷戰資和總由",
"desc": "共先定製向向圓適者定書她規置鬥平相。要廣確但教金更前三響角面等以白。眼查何參提適",
"tag": "值集空",
"views": 3810,
"images": [
"http://dummyimage.com/200x100/79f2a5&text=別角置",
"http://dummyimage.com/200x100/f28279&text=收面幾容受取",
"http://dummyimage.com/200x100/7993f2&text=作件"
]
},
......
]
複製代碼
Mock.mock
repeat 方法(部分)
Mock.mock({
"string|5": "★" => "string": "★★★★★"
"string|1-10": "★" => "string": "★★"
"number|1-100": 100 => "number": 85
"number|1-100.2": 100 => "number": 25.69
})
複製代碼
Mock.Random
Random.boolean() => true false 各50%
Random.integer(60, 100) => 78
Random.float(60, 100) => 89.565475
Random.range(60, 100) => [60,61,62,...,99]
Random.date() => "2018-12-28"
Random.image('200x100','#396') => "http://dummyimage.com/200x100/396"
Random.color() => "#79d8f2" (默認使用hex顏色)
Random.county(true) => "浙江省 舟山市 岱山縣"
複製代碼
Random.image()
// => "http://dummyimage.com/125x125"
Random.image('200x100')
// => "http://dummyimage.com/200x100"
Random.image('200x100', '#fb0a2a')
// => "http://dummyimage.com/200x100/fb0a2a"
Random.image('200x100', '#02adea', 'Hello')
// => "http://dummyimage.com/200x100/02adea&text=Hello"
Random.image('200x100', '#00405d', '#FFF', 'Mock.js')
// => "http://dummyimage.com/200x100/00405d/FFF&text=Mock.js"
Random.image('200x100', '#ffcc33', '#FFF', 'png', '!')
// => "http://dummyimage.com/200x100/ffcc33/FFF.png&text=!"
複製代碼
paragraph-> centence -> word -> title
#中文
Random.cparagraph()
Random.cparagraph( len )
Random.cparagraph( min, max )
#隨機生成一段中文文本
Random.csentence()
Random.csentence( len )
Random.csentence( min, max )
# 隨機生成一個漢字
Random.cword()
Random.cword( pool )
Random.cword( length )
Random.cword( pool, length )
Random.cword( min, max )
Random.cword( pool, min, max )
複製代碼
對應的數據九宮格
comments:[
{
"id": 1,
"news_id": 1,
"author":{
"name":"a1",
"age":32
},
"data": [
{
"id": 1,
"content": "支持黨中央決定"
},
{
"id": 2,
"content": "抄寫黨章勢在必行!"
}
]
}
]
複製代碼
查詢語句:
GET /comments?id=1r&new_id=2
GET /comments?author.name=a1
複製代碼
GET /posts?_page=7
GET /posts?_page=7&_limit=20
複製代碼
access-control-expose-headers →X-Total-Count, Link
link →<http://localhost:3000/news?_page=1>; rel="first", <http://localhost:3000/news?_page=2>; rel="next", <http://localhost:3000/news?_page=2>; rel="last"
x-total-count →20
複製代碼
posts id 和comments id 是關聯的
{
"posts": [
{ "id": 1, "title": "post的第一個title", "author": "typicode" },
{ "id": 2, "title": "post的第二個title", "author": "tangcaiye" }
],
"comments": [
{ "id": 1, "body": "some comment1111", "postId": 2 },
{ "id": 2, "body": "some comment2222", "postId": 1 }
],
"profile": { "name": "typicode" }
}
複製代碼
http://localhost:3000/posts/2?_embed=comments
返回posts/2
下級關聯數據comments
{
"id": 2,
"title": "post的第二個title",
"author": "tangcaiye",
"comments": [
{
"id": 1,
"body": "some comment1111",
"postId": 2
}
]
}
複製代碼
http://localhost:3000/comments/2?_expand=post
返回comments上級關聯數據post
{
"id": 2,
"body": "some comment2222",
"postId": 1,
"post": {
"id": 1,
"title": "post的第一個title",
"author": "typicode"
}
}
複製代碼
排序
默認升序
GET /posts?_sort=views&_order=asc
GET /posts/1/comments?_sort=votes&_order=asc
複製代碼
切片 Slice
包括_star,不包括_end
GET /posts/1/comments?_start=20&_end=30
GET /posts/1/comments?_start=20&_limit=10
複製代碼
彙總
# _gte > || _lte <
GET /posts?views_gte=10&views_lte=20
# _ne !=
GET /posts?id_ne=1
# _like 注意title的字段名稱
GET /posts?title_like=server
# 全局搜索
GET /posts?q=internet
# 直接獲取數據
GET /db
複製代碼
注意:沒有設置路由(主要是: "host": "0.0.0.0" 屬性)以前
json-server --watch db.json
只有本機能訪問,也就是局域網外網都不能訪問
json-server --watch db.json -H 0.0.0.0
複製代碼
127.0.0.1
或者本地局域網IP地址 如192.168.1.168
無效 ,(服務器指定127.0.0.1/ 192.168.1.168是本地調試模式)IPV4中,0.0.0.0地址被用於表示一個無效的,未知的或者不可用的目標。* 在服務器中,0.0.0.0指的是本機上的全部IPV4地址,若是一個主機有兩個IP地址,192.168.1.1 和 10.1.2.1,而且該主機上的一個服務監聽的地址是0.0.0.0,那麼經過兩個ip地址都可以訪問該服務。 * 在路由中,0.0.0.0表示的是默認路由,即當路由表中沒有找到徹底匹配的路由的時候所對應的路由。
json-server db.js -p 3003 -d 500 -q -r ./routes.json
複製代碼
json-server.json
文件進行配置後,直接json-server db.json
# /mock/json-server.json
{
"host": "0.0.0.0",
"port": "3003",
"watch": false,
"delay": 500,
"quiet": true,
"routes": "./routes.json"
}
複製代碼
自定義路由,能夠指定訪問連接返回指定的數據,並且能夠動態修改
routes.json
{
"/api/*": "/$1",
"/:resource/:id/show": "/:resource/:id",
"/posts/:category": "/posts?category=:category",
"/articles\\?id=:id": "/posts/:id"
}
複製代碼
對應的效果
/api/posts # → /posts
/api/posts/1 # → /posts/1
/posts/1/show # → /posts/1
/posts/javascript # → /posts?category=javascript
/articles?id=1 # → /posts/1
複製代碼
"/api/*": "/$1"
至關於把api路徑給忽略掉/:resource
取值是變更的/
開頭// hello.js
module.exports = (req, res, next) => {
res.header('X-Hello', 'World')
next()
}
json-server db.json --middlewares ./hello.js
json-server db.json --middlewares ./first.js ./second.js
複製代碼
爲何學了上面還要學nodejs的案例呢? 由於上面的技能還不能很好的知足開發中REST API的需求
node 安裝 json-server模塊
$ npm install json-server --save-dev
複製代碼
// server.js
const jsonServer = require('json-server')
const server = jsonServer.create()
const router = jsonServer.router('db.json') //默認爲當前目錄
//const path = require('path') 指定其餘目錄
//const router = jsonServer.router(path.join(__dirname, 'db.json'))
const middlewares = jsonServer.defaults()
server.use(middlewares)
server.use(router)
server.listen(3000, () => {
console.log('JSON Server is running')
})
// 運行
$ node server.js
複製代碼
const jsonServer = require('json-server')
const server = jsonServer.create()
const router = jsonServer.router('db.json')
const middlewares = jsonServer.defaults()
// Set default middlewares (logger, static, cors and no-cache)
server.use(middlewares)
// Add custom routes before JSON Server router
server.get('/echo', (req, res) => {
res.jsonp(req.query)
})
// 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()
})
// Use default router
server.use(router)
server.listen(3000, () => {
console.log('JSON Server is running')
})
複製代碼
對上面的幾點進行說明
res.jsonp res ==> respose
res.status(500).jsonp({
error: "error message here"
"id": 21,
"title": "長江",
"date": "2016-09-12",
"likes": 509,
"views": 9900
})
複製代碼
請求的返回Json格式
{
"error": "error message here"
"id": 21,
"title": "長江",
"date": "2016-09-12",
"likes": 509,
"views": 9900
}
複製代碼
req.body.createdAt = Date.now() 往返回的jons中插入createAt字段,如本應返回
{
"id": 21,
"title": "長江",
"date": "2016-09-12",
"likes": 509,
"views": 9900
}
複製代碼
加入req.body.createdAt = Date.now()後返回
{
"id": 21,
"title": "長江",
"date": "2016-09-12",
"likes": 509,
"views": 9900,
"createdAt": 1536476508883,
}
複製代碼
// Add this before server.use(router)
server.use(jsonServer.rewriter({
'/api/*': '/$1',
'/blog/:resource/:id/show': '/:resource/:id'
}))
複製代碼
const jsonServer = require('json-server')
const server = jsonServer.create()
const router = jsonServer.router('db.json')
const middlewares = jsonServer.defaults()
server.use(middlewares)
server.use((req, res, next) => {
if (isAuthorized(req)) { // add your authorization logic here
next() // continue to JSON Server router
} else {
res.sendStatus(401)
}
})
server.use(router)
server.listen(3000, () => {
console.log('JSON Server is running')
})
複製代碼
// In this example, returned resources will be wrapped in a body property
router.render = (req, res) => {
res.jsonp({
body: res.locals.data
})
//res.jsonp => 包裹數據成json格式
//res.send => 直接發送字符串
}
複製代碼
訪問本應返回
{
"id": 21,
"title": "長江",
"date": "2016-09-12"
}
複製代碼
增長 body: res.locals.data後返回
{
body: {
id: 1,
title: "曹縣宣佈昨日晚間登日成功",
date: "2016-08-12",
likes: 55,
views: 100086
}
}
複製代碼
訪問http://localhost:3000/echo
返回模擬數據
const jsonServer = require('json-server')
const server = jsonServer.create()
const router = jsonServer.router('db.json')
const middlewares = jsonServer.defaults()
let Mock = require('mockjs');
server.use(middlewares)
var template = {
'titles': 'Syntax Demo',
'string1|1-10': '★',
'string2|3': 'value',
'number1|+1': 100,
'number2|1-100': 100,
'number3|1-100.1-10': 1,
'number4|123.1-10': 1,
'number5|123.3': 1,
'number6|123.10': 1.123,
'boolean1|1': true,
'boolean2|1-2': true,
'object1|2-4': {
'110000': '北京市',
'120000': '天津市',
'130000': '河北省',
'140000': '山西省'
},
'object2|2': {
'310000': '上海市',
'320000': '江蘇省',
'330000': '浙江省',
'340000': '安徽省'
},
'array1|1': ['AMD', 'CMD', 'KMD', 'UMD'],
'array2|1-10': ['Mock.js'],
'array3|3': ['Mock.js'],
'function': function() {
return this.titles
}
}
server.get('/echo', (req, res) => {
var data = Mock.mock(template)
var json = JSON.stringify(data, null, 4)
console.log('-----------------\n' + json)
res.send(json)
})
// 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) => {
console.log('--------------'+req.method)
if (req.method === 'POST') {
req.body.createdAt = Date.now()
req.body.test = 1
}
// Continue to JSON Server router
next()
})
// 返回錯誤碼,和指定json格式的數據
//router.render = (req, res) => {
// res.status(500).jsonp({
// error: "error message here"
// "id": 21,
// "title": "長江",
// "date": "2016-09-12",
// "likes": 509,
// "views": 9900
// })
//}
// Add this before server.use(router)
server.use(jsonServer.rewriter({
'/api/*': '/$1',
'/blog/:resource/:id/show': '/:resource/:id'
}))
router.render = (req, res) => {
res.jsonp({
body: res.locals.data
})
}
server.use(router)
server.listen(3000, () => {
console.log('JSON Server is running')
})
複製代碼
json-server
index.js [options] <source>
選項:
--config, -c Path to config file [默認值: "json-server.json"]
--port, -p Set port [默認值: 3000]
--host, -H Set host [默認值: "localhost"]
--watch, -w Watch file(s) [布爾]
--routes, -r Path to routes file
--middlewares, -m Paths to middleware files [數組]
--static, -s Set static files directory
--read-only, --ro Allow only GET requests [布爾]
--no-cors, --nc Disable Cross-Origin Resource Sharing [布爾]
--no-gzip, --ng Disable GZIP Content-Encoding [布爾]
--snapshots, -S Set snapshots directory [默認值: "."]
--delay, -d Add delay to responses (ms)
--id, -i Set database id property (e.g. _id) [默認值: "id"]
--foreignKeySuffix, --fks Set foreign key suffix (e.g. _id as in post_id)
[默認值: "Id"]
--quiet, -q Suppress log messages from output [布爾]
--help, -h 顯示幫助信息 [布爾]
--version, -v 顯示版本號 [布爾]
示例:
index.js db.json
index.js file.js
index.js http://example.com/db.json
https://github.com/typicode/json-server
Missing <source> argument
複製代碼
上面有更詳細的使用說明
使用Chrome 的同窗推薦使用