前言

身为一名前端开发工程师,在实际开发过程中,我们很有可能会碰上页面搭建完毕等待后端提供接口的情况,一般最简单的情况下,我们会在页面中写一些死数据作为占位,用以确保页面展示效果。不过这一方法存在弊端,我们无法测试是否可以真实调用数据。那怎么办呢?有什么方法能够解决呢?

这不, json-server 闪亮登场!!!我们可以利用 json-server 起一个本地服务用来测试,当接口提供时只需要替换 API 即可。往往我们只需要提供一个 json 文件,填充一些数据即可实时模拟出 RESTful API 接口。

json-server 介绍

json-server 是一个非常实用的工具,它可以快速为前端应用创建一个全功能的 REST API,只需提供一个 JSON 文件即可。它是基于 Node.js 开发的,并能在任何平台上运行,为开发者提供了一个简单且高效的方式来模拟后端API,从而支持前端开发和测试。

JSON 在线格式化验证JSON在线解析及格式化验证

json-server 主要特性

  • 零编码: 直接使用 JSON 文件来定义整个 API 的数据结构。

  • 快速搭建: 几秒内即可搭建并运行一个具有 CRUD 功能的 REST API。

  • 灵活性: 支持自定义路由、中间件、静态文件服务等。

  • 低学习曲线: 简单易懂的命令行界面。

json-server 基本使用

1. 安装 json-server

你可以通过 npm (Node Package Manager) 来安装 json-server。推荐全局安装,以便在任何项目中都能轻松使用:

npm install -g json-server
# 验证
json-server --version	

2. 创建 json 文件

json-server 通过读取一个 JSON 文件来提供数据。你可以创建一个文件,例如 db.json,并在其中定义一些初始数据:

{
  "posts": [
    { "id": 1, "title": "json-server", "author": "typicode" }
  ],
  "comments": [
    { "id": 1, "post_id": 1, "body": "Some comment" }
  ],
  "profile": {
    "name": "typicode"
  }
}

3. 启动 json-server

可以通过以下命令启动 json-server

json-server --watch db.json

这个命令将启动服务器,默认监听在 3000 端口。你现在可以通过 HTTP 请求访问你定义的资源。例如:

  • GET /posts 获取帖子列表。

  • POST /posts 创建一个新帖子。

  • GET /posts/1 获取特定 ID 的帖子。

  • PUT /posts/1 更新特定 ID 的帖子。

  • DELETE /posts/1 删除特定 ID 的帖子。

json-server 进阶用法

1. 基本命令

启动服务器

json-server --watch db.json

这是最基本的命令,用于启动服务器并监视 db.json 文件的变化,自动更新数据。

2. 常用参数

2.1. 指定端口(--port

json-server --watch db.json --port 3001

默认情况下,json-server 在端口 3000 上运行。使用 --port 参数可以指定一个不同的端口。

2.2. 只读模式(--read-only

json-server --watch db.json --read-only

在这种模式下,所有写入操作(POST, PUT, PATCH, DELETE)都将被阻止,使 API 变为只读。

2.3. 延迟响应(--delay

json-server --watch db.json --delay 2000

这会使所有响应增加 2000 毫秒的延迟,用于模拟网络延时。

2.4. 静态文件服务(--static

如果你的项目中还包含静态文件(如 HTML、CSS、JavaScript 文件),你可以将它们放在一个文件夹中(比如叫做 public),然后启动服务器时指定这个文件夹:

json-server --static ./public

这允许 json-server 提供静态文件服务,你可以将静态资源(如 HTML, CSS, JavaScript 文件)放在指定目录下。

2.5. 启用 CORS(--cors

json-server --watch db.json --cors

启用 CORS 支持,允许跨域请求。

2.6. 自定义路由(--routes

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

使用 routes.json 文件来自定义 API 的路由。这可以用于创建更复杂的 API 结构。routes.json 示例:

{
  "/api/*": "/$1"
}

2.7. 无数据库模式(--no-db

json-server --no-db

这将启动一个不使用任何数据库文件的服务器。所有数据将在内存中处理,重启服务器后将丢失所有数据。

2.8. 中间件(--middlewares

你可以使用中间件来扩展 json-server 的功能。例如,创建一个日志记录中间件 logger.js

// logger.js
module.exports = (req, res, next) => {
  console.log(`${req.method} request to ${req.url}`);
  next();
};

然后使用这个中间件:

json-server --watch db.json --middlewares ./logger.js

加载自定义的中间件,这对于添加自定义逻辑或修改请求 / 响应非常有用。

2.9. 快照功能(--snapshots

json-server --watch db.json --snapshots ./path/to/snapshots

指定快照文件的保存目录。快照是对请求的临时响应,可以用于调试或测试。

3. 示例配置使用

这些命令和参数可以组合使用,以满足更具体的需求。例如,如果您想在开发过程中同时提供静态文件服务和 REST API,并允许跨域请求,可以使用如下命令:

json-server --watch db.json --static ./public --cors --port 3001

这将在端口 3001 上启动一个 json-server,同时监视 db.json 文件的变化,提供位于 ./public 目录下的静态文件服务,并允许跨域请求。

json-server 是一个极其灵活和强大的工具,非常适合快速开发和原型测试,帮助前端开发者在没有后端支持的情况下独立工作。

项目中执行 CRUD 操作

当我们基本了解 json-server 如何使用之后,是不是有个疑问,该如何利用 json-server 在真实的项目中执行真实的 CRUD 操作,要求数据返回格式模拟真实服务器返回的数据呢?

为了更加贴近真实的服务器响应,我们可以通过自定义中间件在 json-server 中修改响应格式,使其包含 statusmessagedata 字段

下面将详细介绍在一个 Vue 3 + TypeScript 项目中利用 json-server 执行真实的 CRUD 操作。其中,

  1. 使用 fetch API 处理增删改查操作

  2. 使用自定义中间件确保每个正确的响应格式

步骤 1:初始化项目和安装依赖

假设你已经有一个 Vue 3 + TypeScript 项目。如果没有,可以通过以下命令新建一个:

npm create vue@latest

然后,安装 json-server 相关依赖:

npm install json-server@v0.17.4 @types/json-server --save-dev

注意,务必确保 json-server 安装的版本是v0.17.4 ,否则其他如 alpha 版本 可能导致后续执行命令node server.js 依赖找不到【"json-server module not found"】。

步骤 2:创建 db.json 文件

在项目根目录中创建 db.json

{
  "posts": [
    { "id": 1, "title": "First post", "content": "This is the first post." },
    { "id": 2, "title": "Second post", "content": "This is the second post." }
  ]
}

步骤 3:配置 json-server 中间件

创建一个 server.js 文件在项目根目录:

我们将使用 JavaScript 来写这个服务器配置,因为 json-server 是一个 JavaScript 库,通常不需要 TypeScript 支持来运行它。

// server.js
// 调整 json-server 格式 =》 使用自定义中间件确保每个响应都返回一个包含 status message data 的对象
const jsonServer = require('json-server')
const server = jsonServer.create()
const router = jsonServer.router('db.json')  // 指向你的 db.json 文件路径
const middlewares = jsonServer.defaults()

server.use(middlewares);

// 添加自定义响应中间件
server.use((req, res, next) => {
  res.locals.data = {
    status: 200,
    message: 'success',
    data: res.locals.data
  }
  next()
});

// 将默认的json-server路由与中间件绑定
server.use(router)

// 设置端口并启动服务器
const PORT = 3000
server.listen(PORT, () => {
  console.log(`JSON Server is running on http://localhost:${PORT}`)
})

步骤 4:定义 TS 接口

在 Vue 项目中,创建或更新 src/types/index.ts 以定义你将使用的数据结构:

// src/types/index.ts
export interface Post {
  id?: number;
  title: string;
  content: string;
}

步骤 5:设置 package.json 脚本

package.json 添加脚本来运行 json-server,注意路径的正确配置,我这里是在根目录所以直接配置 node server.js

"scripts": {
  "dev": "vite",
  "json-server": "node server.js",
}

步骤 6:创建 API 服务

在 Vue 项目中的 src/service/PostService.ts,创建用于 CRUD 操作的 API 调用方法:

// src/service/PostService.ts
import type { Post } from '@/types'

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

class PostService {
  // 查询所有文章
  async fetchPosts(): Promise<Post[]> {
    const response = await fetch(API_URL)
    const result = await response.json()
    return result
  }

  // 新增文章
  async createPost(post: Post): Promise<Post> {
    const response = await fetch(API_URL, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(post)
    })
    const result = await response.json()
    return result.data
  }

  // 更新文章
  async updatePost(id: number, post: Post): Promise<Post> {
    const response = await fetch(`${API_URL}/${id}`, {
      method: 'PUT',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(post)
    })
    const result = await response.json()
    return result.data
  }

  // 删除文章
  async deletePost(id: number): Promise<void> {
    await fetch(`${API_URL}/${id}`, {
      method: 'DELETE'
    })
  }
}

export default new PostService()

步骤 7:Vue 组件中使用服务

接下来,我们将在 Vue3 项目中使用 Fetch API 进行 CRUD 操作

这里作为示例,直接在 App.vue 页面处理:

<script setup lang="ts">
import { RouterView } from 'vue-router'
import { onMounted, ref } from 'vue'
import PostService from '@/service/PostService'
import type { Post } from '@/types'

const posts = ref([] as Post[])

onMounted( () => {
  loadPosts()
})

const loadPosts = async () => {
  posts.value = await PostService.fetchPosts();
};

const addPost = async () => {
  await PostService.createPost({ title: 'New Post', content: 'Content of new post' });
  await loadPosts();
};

const deletePost = async (id: number) => {
  await PostService.deletePost(id);
  await loadPosts();
};
</script>

<template>
  <div v-for="post in posts" :key="post.id">
    <h2>{{ post.title }}</h2>
    <p>{{ post.content }}</p>
    <button @click="deletePost(post.id)">Delete</button>
  </div>
  <button @click="addPost">Add Post</button>
  <RouterView />
</template>

<style scoped>
</style>

步骤 8:运行项目

# 启动 json-server 服务 =》 因为我们前面在package.json文件内配置了脚本,所以可以直接npm run json-server,未配置的也可以直接通过 node server.js 启动服务
npm run json-server

# 启动项目
npm run dev

启动项目后可以在页面中尝试操作,实时查看 db.json 文件是否变动。

这样,我们就有了一个完整的Vue 3 应用,能够进行 CRUD 操作并从 json-server 接收模拟的真实服务器响应。这提供了一个非常好的开发环境,使前端开发人员可以在没有后端服务器的情况下工作,直到后端接口可用。


json-server VS Mock.js

json-serverMock.js(通常简称为mock)都是前端开发中常用的数据模拟工具,它们各有特点和适用场景。

以下是两者的区别以及各自的应用场景详细介绍:

json-server

特点

  • json-server 提供了一个完整的假 REST API,无需编写任何后端代码,只需要一个 JSON 文件即可启动一个服务。

  • 支持 CRUD 操作,可以处理 GET, POST, PUT, PATCH 和 DELETE 请求。

  • 支持自定义路由、中间件和静态文件服务。

  • 基于 Node.js,需要环境安装 Node.js。

应用场景

  • 快速原型开发:当需要快速搭建一个具有真实 API 行为的原型时,可以使用 json-server,它可以模拟真实的数据库交互。

  • 前端独立开发:在后端还未开发完成时,前端开发者可以使用 json-server 模拟后端API,不必等待后端接口就绪。

  • API 接口测试:可以作为测试 RESTful API 的工具,帮助开发者测试前端应用如何与后端数据交互。

Mock.js

特点

  • Mock.js 用于拦截 Ajax 请求并返回自定义的模拟响应数据。

  • 支持生成随机数据(如姓名、日期、邮箱等),并可根据需求定制响应模式。

  • 可以在客户端运行,不需要服务器环境,也可集成在任何前端框架中使用。

  • 提供丰富的数据生成语法,可以模拟复杂的数据结构。

应用场景

  • 开发环境数据模拟:在前端开发过程中,特别是单页应用(SPA)的开发,Mock.js 可以在不影响服务器端的情况下,快速模拟数据。

  • 单元测试和功能测试:Mock.js 能够轻松地为测试环境提供一致且可重复的数据模拟,帮助开发者进行严格的前端测试。

  • 学习和教学:由于 Mock.js 易于集成和使用,它非常适合用于教育和学习中,学习如何处理前端与API的交互。

总结

虽然 json-server 和 Mock.js 都可以用于模拟后端数据,但它们各自的特点和适用场景有所不同。选择哪一个工具,取决于你的具体需求:

  • 如果需要一个独立的、能够模拟完整后端服务的工具,json-server 是一个好的选择。

  • 如果你的需求是在客户端进行更细粒度的控制,特别是需要大量自定义的响应数据和行为,那么 Mock.js 更合适。

在实际开发中,这两个工具也可以根据项目需求结合使用,以发挥最大的效益。