使用 json-server 快速创建一个完整的 REST API

json-server 使用教程

什么是 json-server

json-server 是一个基于 Node.js 的工具,可以快速创建一个完整的 REST API,使用 JSON 文件作为数据源。非常适合前端开发、原型设计和测试。

安装

全局安装

bash 复制代码
npm install -g json-server

本地安装

bash 复制代码
npm install json-server --save-dev

使用 npx(推荐)

bash 复制代码
npx json-server

快速开始

1. 创建数据文件

创建一个 db.json 文件:

json 复制代码
{
  "posts": [
    {
      "id": 1,
      "title": "第一篇文章",
      "author": "张三"
    },
    {
      "id": 2,
      "title": "第二篇文章",
      "author": "李四"
    }
  ],
  "comments": [
    {
      "id": 1,
      "body": "很好的文章",
      "postId": 1
    }
  ],
  "profile": {
    "name": "typicode"
  }
}

2. 启动服务器

bash 复制代码
# 默认端口 3000
json-server db.json

# 指定端口
json-server db.json --port 4000

# 指定主机
json-server db.json --host 0.0.0.0

# 静默模式
json-server db.json --quiet

# 监视文件变化
json-server db.json --watch

3. 访问 API

启动后,服务器会提供以下端点:

bash 复制代码
# 资源端点
GET    /posts
GET    /posts/1
POST   /posts
PUT    /posts/1
PATCH  /posts/1
DELETE /posts/1

# 其他资源
GET    /comments
GET    /profile

REST API 操作

GET - 获取数据

bash 复制代码
# 获取所有文章
curl http://localhost:3000/posts

# 获取指定 ID 的文章
curl http://localhost:3000/posts/1

# 获取个人资料
curl http://localhost:3000/profile

POST - 创建数据

bash 复制代码
# 创建新文章
curl -X POST http://localhost:3000/posts \
  -H "Content-Type: application/json" \
  -d '{
    "title": "新文章",
    "author": "王五"
  }'

# 使用 JavaScript fetch
fetch('http://localhost:3000/posts', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    title: '新文章',
    author: '王五'
  })
})

PUT - 完整更新

bash 复制代码
# 完整更新文章(必须包含所有字段)
curl -X PUT http://localhost:3000/posts/1 \
  -H "Content-Type: application/json" \
  -d '{
    "id": 1,
    "title": "更新后的标题",
    "author": "张三"
  }'

PATCH - 部分更新

bash 复制代码
# 部分更新文章(只更新指定字段)
curl -X PATCH http://localhost:3000/posts/1 \
  -H "Content-Type: application/json" \
  -d '{
    "title": "只更新标题"
  }'

DELETE - 删除数据

bash 复制代码
# 删除文章
curl -X DELETE http://localhost:3000/posts/1

高级查询

过滤

bash 复制代码
# 按字段过滤
GET /posts?author=张三

# 多条件过滤
GET /posts?author=张三&id=1

# 嵌套属性过滤
GET /comments?postId=1

分页

bash 复制代码
# 分页查询
GET /posts?_page=1&_limit=10

# 获取总数(在响应头 X-Total-Count 中)

排序

bash 复制代码
# 升序排序
GET /posts?_sort=id&_order=asc

# 降序排序
GET /posts?_sort=id&_order=desc

# 多字段排序
GET /posts?_sort=author,id&_order=asc,desc

切片

bash 复制代码
# 范围查询
GET /posts?_start=0&_end=10

# 限制数量
GET /posts?_limit=5

# 跳过数量
GET /posts?_start=5

操作符

bash 复制代码
# 大于
GET /posts?id_gte=1

# 小于
GET /posts?id_lte=10

# 不等于
GET /posts?id_ne=1

# 包含
GET /posts?q=关键词

# 正则表达式
GET /posts?id_like=1

全文搜索

bash 复制代码
# 搜索包含关键词的记录
GET /posts?q=文章

# 搜索会在所有字段中查找

关联查询

bash 复制代码
# 获取文章及其评论
GET /posts/1?_embed=comments

# 获取评论及其所属文章
GET /comments?_expand=post

# 嵌套多个关系
GET /posts/1?_embed=comments&_embed=likes

配置选项

命令行选项

bash 复制代码
# 完整命令示例
json-server db.json \
  --port 4000 \
  --host 0.0.0.0 \
  --watch \
  --routes routes.json \
  --middlewares middleware.js \
  --static ./public \
  --read-only \
  --no-cors

选项说明

选项 说明
--port 指定端口号(默认 3000)
--host 指定主机地址(默认 localhost)
--watch 监视文件变化
--routes 自定义路由文件
--middlewares 中间件文件
--static 静态文件目录
--read-only 只读模式(禁用 POST/PUT/DELETE)
--no-cors 禁用 CORS
--quiet 静默模式

自定义路由

创建路由文件

创建 routes.json

json 复制代码
{
  "/api/*": "/$1",
  "/:resource/:id/show": "/:resource/:id",
  "/posts/:category": "/posts?category=:category",
  "/articles\\?id=:id": "/posts/:id"
}

使用自定义路由

bash 复制代码
json-server db.json --routes routes.json

路由示例

bash 复制代码
# 原始路由
GET /posts/1

# 自定义路由
GET /api/posts/1        # 映射到 /posts/1
GET /posts/1/show       # 映射到 /posts/1
GET /posts/tech         # 映射到 /posts?category=tech

中间件

创建中间件

创建 middleware.js

javascript 复制代码
module.exports = (req, res, next) => {
  // 添加响应头
  res.header('X-Custom-Header', 'Custom Value')
  
  // 记录请求
  console.log(`${req.method} ${req.url}`)
  
  // 模拟延迟
  if (req.url.includes('delay')) {
    setTimeout(next, 2000)
  } else {
    next()
  }
}

使用中间件

bash 复制代码
json-server db.json --middlewares middleware.js

高级中间件示例

javascript 复制代码
module.exports = (req, res, next) => {
  // 身份验证模拟
  if (req.method === 'POST' && !req.headers.authorization) {
    return res.status(401).json({ error: 'Unauthorized' })
  }
  
  // 请求日志
  const timestamp = new Date().toISOString()
  console.log(`[${timestamp}] ${req.method} ${req.url}`)
  
  // 修改响应
  const originalSend = res.send
  res.send = function (data) {
    const modifiedData = JSON.parse(data)
    modifiedData.timestamp = timestamp
    originalSend.call(this, JSON.stringify(modifiedData))
  }
  
  next()
}

数据生成

使用 Faker.js 生成测试数据

javascript 复制代码
const faker = require('faker')
const fs = require('fs')

const generateData = () => {
  const users = []
  for (let i = 1; i <= 100; i++) {
    users.push({
      id: i,
      name: faker.name.findName(),
      email: faker.internet.email(),
      phone: faker.phone.phoneNumber(),
      address: {
        street: faker.address.streetAddress(),
        city: faker.address.city(),
        country: faker.address.country()
      },
      company: faker.company.companyName()
    })
  }
  
  const db = { users }
  fs.writeFileSync('db.json', JSON.stringify(db, null, 2))
}

generateData()

运行生成器

bash 复制代码
node generate-data.js
json-server db.json

与前端框架集成

React 示例

javascript 复制代码
import axios from 'axios'

const API_URL = 'http://localhost:3000'

// 获取所有文章
export const getPosts = async () => {
  const response = await axios.get(`${API_URL}/posts`)
  return response.data
}

// 创建文章
export const createPost = async (post) => {
  const response = await axios.post(`${API_URL}/posts`, post)
  return response.data
}

// 更新文章
export const updatePost = async (id, post) => {
  const response = await axios.put(`${API_URL}/posts/${id}`, post)
  return response.data
}

// 删除文章
export const deletePost = async (id) => {
  const response = await axios.delete(`${API_URL}/posts/${id}`)
  return response.data
}

Vue 示例

javascript 复制代码
import axios from 'axios'

const api = axios.create({
  baseURL: 'http://localhost:3000'
})

export default {
  async getPosts() {
    const response = await api.get('/posts')
    return response.data
  },
  
  async createPost(post) {
    const response = await api.post('/posts', post)
    return response.data
  },
  
  async updatePost(id, post) {
    const response = await api.put(`/posts/${id}`, post)
    return response.data
  },
  
  async deletePost(id) {
    const response = await api.delete(`/posts/${id}`)
    return response.data
  }
}

package.json 配置

添加脚本

json 复制代码
{
  "name": "my-project",
  "version": "1.0.0",
  "scripts": {
    "json-server": "json-server --watch db.json --port 4000",
    "dev": "npm run json-server"
  },
  "devDependencies": {
    "json-server": "^0.17.3"
  }
}

运行脚本

bash 复制代码
npm run dev

常见问题

1. 端口被占用

bash 复制代码
# 使用其他端口
json-server db.json --port 4000

2. CORS 问题

json-server 默认启用 CORS,如果遇到问题:

bash 复制代码
# 确保没有禁用 CORS
json-server db.json

3. 数据持久化

json-server 会将修改保存到 db.json 文件中,确保文件有写入权限。

4. 重置数据

bash 复制代码
# 删除 db.json 或恢复备份
rm db.json
cp db.json.backup db.json

最佳实践

1. 版本控制

bash 复制代码
# 添加到 .gitignore
echo "db.json" >> .gitignore

# 创建示例数据文件
cp db.json db.example.json

2. 环境配置

javascript 复制代码
// config.js
module.exports = {
  port: process.env.JSON_SERVER_PORT || 3000,
  host: process.env.JSON_SERVER_HOST || 'localhost',
  watch: process.env.NODE_ENV !== 'production'
}

3. 数据验证

javascript 复制代码
// middleware.js
module.exports = (req, res, next) => {
  if (req.method === 'POST' || req.method === 'PUT') {
    const body = req.body
    
    // 验证必填字段
    if (!body.title) {
      return res.status(400).json({ error: 'Title is required' })
    }
  }
  next()
}

4. 性能优化

bash 复制代码
# 使用静态文件服务
json-server db.json --static ./public

# 禁用日志(生产环境)
json-server db.json --quiet

总结

json-server 是一个强大且易于使用的工具,适合:

  • ✅ 前端开发和原型设计
  • ✅ API 测试和调试
  • ✅ 快速搭建演示项目
  • ✅ 学习 REST API 概念

通过本教程,你应该能够:

  • 安装和启动 json-server
  • 执行 CRUD 操作
  • 使用高级查询功能
  • 自定义路由和中间件
  • 与前端框架集成

开始使用 json-server,快速构建你的 REST API 吧!

相关推荐
一位搞嵌入式的 genius6 小时前
深入理解 JavaScript 异步编程:从 Event Loop 到 Promise
开发语言·前端·javascript
m0_564914927 小时前
Altium Designer,AD如何修改原理图右下角图纸标题栏?如何自定义标题栏?自定义原理图模版的使用方法
java·服务器·前端
brevity_souls7 小时前
SQL Server 窗口函数简介
开发语言·javascript·数据库
方安乐7 小时前
react笔记之useCallback
前端·笔记·react.js
小二·7 小时前
Python Web 开发进阶实战:AI 伦理审计平台 —— 在 Flask + Vue 中构建算法偏见检测与公平性评估系统
前端·人工智能·python
走粥7 小时前
选项式API与组合式API的区别
开发语言·前端·javascript·vue.js·前端框架
We་ct7 小时前
LeetCode 12. 整数转罗马数字:从逐位实现到规则复用优化
前端·算法·leetcode·typescript
方安乐7 小时前
react笔记之useMemo
前端·笔记·react.js
晚霞的不甘7 小时前
解决 Flutter for OpenHarmony 构建失败:HVigor ERROR 00303168 (SDK component missing)
android·javascript·flutter
清风细雨_林木木8 小时前
react 中 form表单提示
前端·react.js·前端框架