JSON Server在快速開發(fā)過程中的使用

在開發(fā)過程中,接口多半是滯后于頁面開發(fā)的。利用JSON Server快速搭建模擬返回REST風格的后臺數(shù)據(jù),保證前后端開發(fā)的分離。前后端開發(fā)只要設定好接口以及數(shù)據(jù)的定義,剩下的就可以各自開發(fā),最后集成測試。

JSON Server 作為工具,基于Express開發(fā),而且它足夠簡單,寫少量數(shù)據(jù),即可使用,支持CORS和JSONP跨域請求,支持GET, POST, PUT, PATCH 和 DELETE 方法,更提供了一系列的查詢方法,如limit,order等

安裝

npm install json-server -g

全局安裝,可以在命令行下獨立執(zhí)行。安裝完成后可以用 json-server -h 命令檢查是否安裝成功。

json-server [options] <source>

Options:
  --config, -c       指定 config 文件                  [默認: "json-server.json"]
  --port, -p         設置端口號                                   [default: 3000]
  --host, -H         設置主機                                   [默認: "0.0.0.0"]
  --watch, -w        監(jiān)控文件                                           [boolean]
  --routes, -r       指定路由文件
  --static, -s       設置靜態(tài)文件
  --read-only, --ro  只允許 GET 請求                                    [boolean]
  --no-cors, --nc    禁止跨域資源共享                                   [boolean]
  --no-gzip, --ng    禁止GZIP                                          [boolean]
  --snapshots, -S    設置快照目錄                                     [默認: "."]
  --delay, -d        設置反饋延時 (ms)
  --id, -i           設置數(shù)據(jù)的id屬性 (e.g. _id)                     [默認: "id"]
  --quiet, -q        不輸出日志信息                                     [boolean]
  --help, -h         顯示幫助信息                                       [boolean]
  --version, -v      顯示版本號                                         [boolean]

啟動

創(chuàng)建一個目錄server,在該目錄下創(chuàng)建一個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目錄下執(zhí)行

json-server db.json -p 3003

打開瀏覽器,http://localhost:3003,查看頁面。如果要監(jiān)控json文件的變化,啟動的時候加上參數(shù)--watch。

支持的方法

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

  • GET /list 獲取列表
  • GET /list/1 獲取id=1的數(shù)據(jù)
  • POST /list 創(chuàng)建一個項目
  • PUT /list/1 更新一個id為1的數(shù)據(jù)
  • PATCH /list/1 部分更新id為1的數(shù)據(jù)
  • DELETE /list/1 刪除id為1的數(shù)據(jù)

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

  • GET /user
  • POST /user
  • PUT /user
  • PATCH /user
  • 當你發(fā)送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來對返回數(shù)據(jù)定制(不設置默認返回10條)。
在返回的header中,有一個屬性Link,里面會有first, prev, next and last links。
header中還有一個屬性X-Total-Count,用來存儲滿足條件的數(shù)據(jù)的條數(shù)。

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里面),就像數(shù)據(jù)的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

關聯(lián)子資源, 添加_embed

GET /posts?_embed=comments
GET /posts/1?_embed=comments

包含父資源, 添加_expand

GET /comments?_expand=post
GET /comments/1?_expand=post

要獲得或創(chuàng)建nested resources(默認一層,多層的話,自定義routes)

GET  /posts/1/comments
POST /posts/1/comments

Database

GET /db

Homepage

返回默認的index文件,或者./public目錄

GET /

拓展功能

靜態(tài)文件服務器

你也可以用json server來托管你的靜態(tài)HTML,JS和CSS文件。僅僅需要簡單的創(chuàng)建一個./public目錄?;蛘哂?code>--static來指定一個不同的靜態(tài)文件路徑。

mkdir public
echo 'hello world' > public/index.html
json-server db.json
json-server db.json --static ./some-other-dir

改變端口號

你可以改變端口號使用--port

$ json-server --watch db.json --port 3004

從任何地方訪問

你可以使用CORS和JSONP從任何地方訪問你的API。

遠程文件

你可以加載遠程文件

$ json-server http://example.com/file.json
$ json-server http://jsonplaceholder.typicode.com/db

生成隨機數(shù)據(jù)

使用js文件替代json文件,可以動態(tài)生成數(shù)據(jù)。還可以借助其他模塊生成,比如Faker, Casual, Chance or JSON Schema Faker。

// index.js
module.exports = () => {
  const data = { users: [] }
  // Create 1000 users
  for (let i = 0; i < 1000; i++) {
    data.users.push({ id: i, name: `user${i}` })
  }
  return data
}
$ json-server index.js

HTTPS

有很多方式在開發(fā)中使用SSL。一個簡單的方式就是使用hotel.

自定義路由

創(chuàng)建routes.json文件。注意每個路由文件應該以/開頭。

{
  "/api/*": "/$1",
  "/:resource/:id/show": "/:resource/:id",
  "/posts/:category": "/posts?category=:category",
  "/articles\\?id=:id": "/posts/:id"
}

啟動json server時加上--routes選項。

json-server db.json --routes routes.json

現(xiàn)在你可以用附加路由訪問資源了。

/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-server db.json --middlewares ./hello.js
json-server db.json --middlewares ./first.js ./second.js

CLI usage

你可以將設置放在json-server.json配置文件里。

將json server作為一個模塊

在項目中,如何你需要增加認證,驗證或者其他功能,你可以將json server作為一個模塊,合并其他的Express中間件。

一個簡單的例子

// server.js
const jsonServer = require('json-server')
const server = jsonServer.create()
const router = jsonServer.router('db.json')
const middlewares = jsonServer.defaults()

server.use(middlewares)
server.use(router)
server.listen(3003, () => {
  console.log('JSON Server is running')
})
$ node server.js

你提供給jsonServer.router方法的路徑,是相對于你的node的。

如果你從另外一個路徑運行上面的代碼,最好用絕對路徑。

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

對于內(nèi)存數(shù)據(jù)庫,傳遞一個對象給jsonServer.router()。注意,jsonServer.router()可以被用在一個已經(jīng)存在的Express項目中。

自定義路由動態(tài)數(shù)據(jù)的例子

//db.js

let Mock  = require('mockjs');
let Random = Mock.Random;

module.exports = function() {
  var data = { 
      news: [],
      type:{
        "a":"a",
        "b":"b",
      }
  };
  
  var images = [1,2,3].map(x=>Random.image('200x100', Random.color(), Random.word(2,6)));
  
  for (var i = 0; i < 10; 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
}
//server.js
const path = require('path');
const config = require('./config');
const jsonServer = require('json-server');
const rules = require('./routes');
const dbfile = require(config.DB_FILE);

const ip = config.SERVER;
const port = config.PORT;
const db_file = config.DB_FILE;

const server = jsonServer.create();
const router = jsonServer.router(dbfile());
const middlewares = 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數(shù)據(jù)結構

需要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狀態(tài)碼

// 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'
}))
Mounting JSON Server on another endpoint example

更改掛載點

掛在/api

server.use('/api', router)

代碼下載

https://github.com/fujusong/JSON-Server-starter.git

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容