美文网首页
『前端必备』本地数据接口 —— json-server 从入门到

『前端必备』本地数据接口 —— json-server 从入门到

作者: 德育处主任 | 来源:发表于2021-12-20 09:17 被阅读0次

    前言

    Ajax 是前端必学的一个知识点,但刚接触 Ajax 的同学可能会因为没接口测试而烦恼。

    本文 入门篇 会花你10分钟解决 没接口测试 这个烦恼,而且不需要你具备后端知识。

    如果不想自己在本地搭环境,还可以使用 《前端需要的免费在线api接口》 里推荐的几个线上接口平台,里面包括常用的 json 结构数据和图片。

    虽然有线上的免费接口可以测试,但需要自定义接口和数据的时候,还是本地模拟数据比较适合前端开发者。

    本文分 入门篇进阶篇。再往下滑一点就能看到全文目录。

    入门篇: 5分钟内带你实现 本地环境搭建增删改查 操作,满足入门测试使用。

    进阶篇: 主要讲解常用的 查询操作,除此之外还包括 常规配置、静态资源配置 等知识点。这部分有点长,建议收藏

    本文约定

    1. 本文主要面向的读者是 前端小白,几乎不会涉及到后端知识,所以并不打算讲解 json-server 中间件 的内容。
    2. 本文讲到的所有知识点都会提供对应的代码展示(会比官方文档详细点)。
    3. 本文使用 postman 测试,希望能照顾到使用不同工具库做数据请求的读者(我知道还有只懂 jQuery 的开发者)。
    4. 特殊情况会使用 axios 配合演示。

    点赞 + 收藏 = 学会了

    目录

    思维导图.png

    入门

    json-server简介

    npm地址 | github地址

    Get a full fake REST API with zero coding in less than 30 seconds (seriously)

    引用了官方的一句话,大概意思是30秒就能获得一套完整的模拟 REST API 接口。

    使用 json-server 需要遵守一定的规范。

    • 数据查询要使用 GET
    • 新增数据要使用 POST
    • 删除数据要使用 DELETE
    • 修改数据使用 PUTPATCH

    其他啰嗦的介绍可以打开上面提供的网址看看。

    30秒起步

    30秒起步分 4 步完成:

    1. node 环境安装
    2. 安装 json-server
    3. 创建数据库(其实就是一个 json 文件)
    4. 启动服务

    1. node 环境安装

    json-server 需要通过 npm 下载,npm 依赖在 node 中。

    node 常见的安装方法有2种。第一种是官方下载,第二种是使用 nvm 下载。自己选一种就行。

    node 官网,点击进入主页下载,下载完狂按“下一步”和“完成”就行了。

    注意: node 版本一定要 12 以上。不然会报以下错误:

    json-server requires at least version 12 of Node, please upgrade
    

    2. 安装 json-server

    可以全局安装,也可以在某项目里安装。这里建议全局安装,因为以后你可能会对 json-server 产生依赖。

    全局安装方式:

    npm install -g json-server
    

    3. 创建数据库

    在你本机创建一个文件夹,然后新建一个 json 文件,再填入数据即可。

    建议文件名不要出现中文。

    例:

    创建 json-server-demo 文件夹,在 json-server-demo 里创建 db.json 文件(这些文件夹和文件名都可以自由命名)。

    db.json 文件录入以下数据(数据来自 json-server 官方文档,你也可以使用自己的数据)

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

    4. 启动服务

    进入 json-server-demo 目录,打开终端输入以下命令即可

    json-server --watch db.json
    
    01.png

    首页和三个接口都可以直接在浏览器访问,自己打开试试吧。

    搞掂!

    查(get)

    json-server 查询数据需要使用 GET 方法。

    入门篇 只写一种查询方法,其他查询操作请往下滑,看 进阶篇

    上一小节创建了3个接口,我们可以直接在浏览器、postman或者自己写JS代码获取数据。

    http://localhost:3000/posts
    
    02.png

    http://localhost:3000/commentshttp://localhost:3000/profile 两个接口可以自己尝试,这里不再啰嗦。

    增(post)

    json-server 新增数据需要使用 POST 方法。

    例:给 posts 添加一条新的数据。

    http://localhost:3000/posts
    
    03.png

    这里使用 POSt 方法向 /posts 接口传输数据,/posts 原本的数据结构是包含 id、title、author 三个字段,id 默认是自增主键,不传的话会默认增加。

    此时打开 db.json 文件看看,可以发现 posts 里多了一条数据。

    04.png

    需要注意的是:json-server 默认情况下并不会限制你上传的数据格式和类型,所以需要你严格遵循自己设计的数据格式来添加和修改。

    删(delete)

    json-server 删除数据需要使用 DELETE 方法。

    删除的公式是:

    http://localhost:3000/{接口名}/{id}
    

    比如现在要删除刚刚上传的那条数据

    {
      "title": "leihou",
      "author": "雷猴",
      "id": 2
    }
    

    可以看到刚刚上传的那条数据的 id 为 2

    http://localhost:3000/posts/2
    
    05.png

    此时打开 db.json 就会发现刚刚删除的那条数据已经没了。

    06.png

    需要注意的是: 删除成功 Status 会返回 200;如果删除的数据不存在会返回 404

    我用 axios 模拟了一下。

    删除成功返回的结果:

    07.png

    删除失败返回的结果:

    08.png

    改(put 和 patch)

    修改数据分为2个方法:

    • put :覆盖
    • patch :更新

    公式如下所示:

    http://localhost:3000/posts/{id}
    

    覆盖(put)

    例:把 id1 的数据改成 { "title": "leihou", "author": "雷猴" }

    09.png

    此时打开 db.json 就可以看到 id1 的数据已经发生变化。

    注意:原本的数据包含 titleauthor ,使用 put 时必须把这两个字段都写上,不然会删掉没传的字段。这就是 “覆盖” 的意思。

    例如:

    10.png

    此时查看 db.json 会发现数据被覆盖了

    11.png

    更新(patch)

    先还原一下数据,改成如下图所示:

    12.png

    此时有 titleauthor 字段。

    例:使用 patch 方法把 id1 的数据 title 字段的值更改成 hello

    13.png

    打开 db.json 文件查看一下,会发现只改了 id1title 值,并没有删掉 author 这个字段的数据。

    14.png

    进阶

    启动参数

    我们之前使用 json-server --watch db.json 这条命令启动了接口项目,其中 json-server 是服务启动的命令,--watch 是参数,db.json 是目标文件。

    使用下面这条命令可以 查看配置项:

    json-server --help
    
    # 或使用简写方式
    json-server -h
    
    参数 简写 说明
    --config -c 指定配置文件
    --port -p 端口号
    --host -H 主机地址
    --watch -w 监听文件
    --routes -r 指定路由文件
    --middlewares -m 指定中间件
    --static -s 设置静态文件
    --read-only --ro 只读
    --no-cors --nc 禁用跨源资源共享
    --no-gzip --ng 禁止GZIP
    --snapshots -S 设置快照目录
    --delay -d 设置反馈延时(ms)
    --id -i 设置数据的id属性(e.g. _id)
    --foreignKeySuffix --fks 设置外键后缀(如post_id中的_id)
    --quiet -q 禁止输出日志消息
    --help -h 显示帮助信息
    --version -v 显示版本号

    配置

    使用 json-server --help 可以查看到所有配置项。接下来我演示几个常见的配置操作。

    端口

    使用 -p 或者 --port 配置端口号,例如配置 6666 端口

    json-server -p 6666 db.json
    

    启动后

    \{^_^}/ hi!
    
    Loading db.json
    Done
    
    Resources
    http://localhost:6666/posts
    http://localhost:6666/comments
    http://localhost:6666/profile
    
    Home
    http://localhost:6666
    

    主机地址

    json-server --host 0.0.0.0 db.json
    

    这里设置了 0.0.0.0 ,之后通过本机 IP 来访问即可。同一个局域网内的其他设备也可以通过这个地址来访问。

    查询的常用操作

    查询是日常项目中接触最多的操作,所以查询是重点。

    普通查询

    30秒起步 的那份数据。

    查询 /posts 所有数据

    http://0.0.0.0:3000/posts
    

    查询 /comments 所有数据

     http://localhost:3000/comments
    

    查询 /profile 所有数据

    http://localhost:3000/profile
    

    id查询

    db.json 的内容修改一下。

    {
      "posts": [
        {
          "id": 1,
          "title": "文章111",
          "author": "张三"
        },
        {
          "id": 2,
          "title": "文章222",
          "author": "李四"
        }
      ]
    }
    

    此时只有 posts 接口,里面有2条数据,id 分别为 12

    查询的公式是:

    http://localhost:3000/posts/{id}
    

    查询 id2 的数据

    http://localhost:3000/posts/2
    
    15.png

    条件查询

    准备以下数据。

    {
      "posts": [
        {
          "id": 1,
          "title": "文章111",
          "author": "张三"
        },
        {
          "id": 2,
          "title": "文章222",
          "author": "李四"
        },
        {
          "id": 3,
          "title": "文章333",
          "author": "张三"
        }
      ]
    }
    

    可以看到里面有 2条张三 的数据,1条李四 的数据。

    单一条件查询

    查找 author张三 的所有数据。

    查询 author张三 的数据

    http://localhost:3000/posts?author=张三
    
    16.png

    http://localhost:3000/posts 后面加一个 ? ,然后写上筛选条件即可。

    多条件查询(且)

    上面的数据,有2条张三的。

    这次要筛选的是 author = 张三title = 文章333 的数据

    http://localhost:3000/posts?author=张三&title=文章333
    
    17.png

    符合条件赛选的时候,使用 & 号添加条件。

    多条件查询(或)

    这次要筛选的是 title = 222title = 333 这两条数据出来。

    http://localhost:3000/posts?title=文章222&title=文章333
    
    18.png

    重复使用 title ,会把符合条件的都筛查出来。

    当然,我们还可以使用 模糊查询 来达到类似的效果,稍后会讲到。

    深度属性查询

    这里需要准备另一份数据才能展示这个知识点。

    数据内容如下

    {
      "posts": [
        {
          "id": 1,
          "title": "文章111",
          "authorInfo": {
            "name": "张三",
            "age": 20
          }
        },
        {
          "id": 2,
          "title": "文章222",
          "authorInfo": {
            "name": "李四",
            "age": 24
          }
        }
      ]
    }
    

    可以看到 authorInfo 里面还有子属性。

    查询 authorInfo.name = 张三 的数据。

    http://localhost:3000/posts?authorInfo.name=张三
    
    19.png

    这里需要使用 . 的方式来访问子级数据,有点像 js 用点语法访问对象属性那样。

    工作中我遇到这样的接口不多。

    分页查询

    使用 _page_limit(可选) 对数据进行分页。需要注意,_page_limit 前面都要有下划线

    • _page:页码
    • _limit:每页的数据量

    修改 db.json 里的数据方便测试分页功能,如下所示

    {
      "comments": [
        { "id": 1, "body": "some comment 1", "postId": 1 },
        { "id": 2, "body": "some comment 2", "postId": 1 },
        { "id": 3, "body": "some comment 3", "postId": 2 },
        { "id": 4, "body": "some comment 4", "postId": 3 },
        { "id": 5, "body": "some comment 5", "postId": 1 },
        { "id": 6, "body": "some comment 6", "postId": 3 },
        { "id": 7, "body": "some comment 7", "postId": 3 },
        { "id": 8, "body": "some comment 8", "postId": 1 },
        { "id": 9, "body": "some comment 9", "postId": 2 },
        { "id": 10, "body": "some comment 10", "postId": 2 },
        { "id": 11, "body": "some comment 11", "postId": 3 },
        { "id": 12, "body": "some comment 11", "postId": 1 }
      ]
    }
    

    准备了12条数据。

    需要获取第2页的数据,每页3条:

    http://localhost:3000/comments?_page=2&_limit=3
    
    20.png

    除了要返回的数据外,还会在 Headers 里返回 总数;第一个、前一个、下一个、最后一个的链接。我用 axios 发个请求演示一下。

    axios.get('http://localhost:3000/comments', {
      params: {
       _page: 2,
       _limit: 3
      }
    })
      .then(res => {
        console.log(res)
      })
      .catch(err => {
        console.error(err)
      })
    

    返回结果如下所示

    21.png

    x-total-count 存放总数

    link 字段里存放的是 第一个、前一个、下一个、最后一个 的链接地址

    "
    <http://localhost:3000/comments?_page=1&_limit=3>; rel=\"first\", <http://localhost:3000/comments?_page=1&_limit=3>; rel=\"prev\", <http://localhost:3000/comments?_page=3&_limit=3>; rel=\"next\", <http://localhost:3000/comments?_page=4&_limit=3>; rel=\"last\"
    "
    

    排序查询

    需要添加 排序的标记 ( _sort ),然后设置 排序规则 ( _order )

    其中,排序规则有 升序 ( asc )降序 ( desc )

    http://localhost:3000/{接口名}?_sort=要排序的字段名&_order=排序规则
    

    以这份数据为例:

    {
      "comments": [
        { "id": 11, "body": "some comment 1", "postId": 1 },
        { "id": 2, "body": "some comment 2", "postId": 1 },
        { "id": 3, "body": "some comment 3", "postId": 2 },
        { "id": 10, "body": "some comment 4", "postId": 3 },
        { "id": 7, "body": "some comment 5", "postId": 1 },
        { "id": 6, "body": "some comment 6", "postId": 3 },
        { "id": 5, "body": "some comment 7", "postId": 3 },
        { "id": 8, "body": "some comment 8", "postId": 1 },
        { "id": 9, "body": "some comment 9", "postId": 2 },
        { "id": 4, "body": "some comment 10", "postId": 2 },
        { "id": 1, "body": "some comment 11", "postId": 3 },
        { "id": 12, "body": "some comment 11", "postId": 1 }
      ]
    }
    

    id 的排序是乱的,如果使用普通的方式请求回来的数据是原模原样返回的。

    升序

    id 为参考字段进行升序排列返回给客户端。

    http://localhost:3000/comments?_sort=id
    
    或
    http://localhost:3000/comments?_sort=id&_order=asc
    
    22.png

    返回的结果就会以 id 为参考字段升序排好。

    普通升序排列的话,_order=asc 可以不传。只需指定 参考字段 ( _sort ) 即可。

    降序

    降序必须填好 _order=desc

    http://localhost:3000/comments?_sort=id&_order=desc
    
    23.png

    多字段排序

    这次的需求是:

    1. 首先按 postId 升序排列

    2. 1 的基础上再对 id 进行倒序排列

    多个字段用 , 分格。

    http://localhost:3000/comments?_sort=postId,id&_order=asc,desc
    

    返回结果:

    {
      "comments": [
        { "id": 12, "body": "some comment 11", "postId": 1 },
        { "id": 11, "body": "some comment 1", "postId": 1 },
        { "id": 8, "body": "some comment 8", "postId": 1 },
        { "id": 7, "body": "some comment 5", "postId": 1 },
        { "id": 2, "body": "some comment 2", "postId": 1 },
        { "id": 9, "body": "some comment 9", "postId": 2 },
        { "id": 4, "body": "some comment 10", "postId": 2 },
        { "id": 3, "body": "some comment 3", "postId": 2 },
        { "id": 10, "body": "some comment 4", "postId": 3 },
        { "id": 6, "body": "some comment 6", "postId": 3 },
        { "id": 5, "body": "some comment 7", "postId": 3 },
        { "id": 1, "body": "some comment 11", "postId": 3 }
      ]
    }
    

    符合需求。

    切片查询

    切片的意思是指定 ;也可以指定 片段长度

    用到的关键字有:

    • _start:开始位置(下标,从0开始)
    • _end:结束位置
    • _limit:片段长度

    总数 会放在 headers 里。

    以这份数据为例

    {
      "comments": [
        { "id": 1, "body": "some comment 1", "postId": 1 },
        { "id": 2, "body": "some comment 2", "postId": 1 },
        { "id": 3, "body": "some comment 3", "postId": 2 },
        { "id": 4, "body": "some comment 4", "postId": 3 },
        { "id": 5, "body": "some comment 5", "postId": 1 },
        { "id": 6, "body": "some comment 6", "postId": 3 },
        { "id": 7, "body": "some comment 7", "postId": 3 },
        { "id": 8, "body": "some comment 8", "postId": 1 },
        { "id": 9, "body": "some comment 9", "postId": 2 },
        { "id": 10, "body": "some comment 10", "postId": 2 },
        { "id": 11, "body": "some comment 11", "postId": 3 },
        { "id": 12, "body": "some comment 11", "postId": 1 }
      ]
    }
    

    需求:返回下标从 2-6 的数据

    使用 _start_end 的方式

    http://localhost:3000/comments?_start=2&_end=6
    

    使用 _start_limit 的方式

    http://localhost:3000/comments?_start=2&_limit=4
    
    24.png

    范围查询

    范围查询包括 大于等于小于等于不等于 三种情况。

    大于等于 _get

    大于等于 使用的关键字是 _get 。注意,前面有个下划线的。

    需求:查询 comments 接口 id 大于等于 4 的数据

    http://localhost:3000/comments?id_gte=4
    
    25.png

    小于等于 _lte

    需求:查询 comments 接口 id 小于等于 4 的数据

    http://localhost:3000/comments?id_lte=4
    
    26.png

    联合一起使用

    需求:查询 comments 接口 id 大于等于 4 且 小于等于 6 的数据

    http://localhost:3000/comments?id_gte=4&id_lte=6
    
    27.png

    不等于 _ne

    需求:查询 comments 接口 id 不等于 2 的数据

    http://localhost:3000/comments?id_ne=2
    
    28.png

    模糊查询

    模糊查询的关键字是 _like

    需求:查询 comments 接口 body 包含 1 的数据

    29.png

    全文查询

    全文查询的关键字是 q

    准备以下数据比较好演示

    {
      "authors": [
        { "id": 1, "name": "zhangsan", "age": 18},
        { "id": 2, "name": "lisi", "age": 21},
        { "id": 3, "name": "wangwu", "age": 24}
      ]
    }
    

    查询所有字段中包含 2 的数据出来

    http://localhost:3000/authors?q=2
    
    30.png

    因为 id3 的那条数据里 age24 ,也算是包含了 2

    外键关联查询

    外键查询需要 2个接口 关联查询。

    准备以下数据方便演示

    {
      "posts": [
        { "id": 1, "title": "文章111", "author": "张三" },
        { "id": 2, "title": "文章222", "author": "李四" }
      ],
      "comments": [
        { "id": 1, "body": "some comment 1", "postId": 1 },
        { "id": 2, "body": "some comment 2", "postId": 1 },
        { "id": 3, "body": "some comment 3", "postId": 2 }
      ]
    }
    

    posts 里有2条数据。

    comments 里有3条数据,其中每条数据都有一个 postId,是对应 posts 每条数据的 id

    需求:查询 postsid1 的所有 comments 内容

    http://localhost:3000/posts/1/comments
    
    31.png

    关系拼装

    关系拼装可以把关联的2个接口的数据拼接起来并返回。

    其中有2种查询关系:

    • 包含子资源 _embed
    • 包含父资源 _expand

    准备以下数据方便演示

    {
      "posts": [
        { "id": 1, "title": "文章111", "author": "张三" },
        { "id": 2, "title": "文章222", "author": "李四" }
      ],
      "comments": [
        { "id": 1, "body": "some comment 1", "postId": 1 },
        { "id": 2, "body": "some comment 2", "postId": 1 },
        { "id": 3, "body": "some comment 3", "postId": 2 }
      ]
    }
    

    包含子资源 _embed

    http://localhost:3000/posts?_embed=comments
    
    32.png

    还可以拼接多个条件。

    需求:在 comments 里,把 postsid2 的数据找出来并拼接起来

    http://localhost:3000/posts/2?_embed=comments
    
    33.png

    包含父资源 _expand

    http://localhost:3000/comments?_expand=post
    
    34.png

    配置路由

    有时候我们的 api地址 可能不像上面所有案例中那么简单,此时就可以使用 自定义路由 的方法来模拟。

    比如模拟下面这个接口:

    http://localhost:3000/api/users/1
    

    实现的步骤如下所示:

    1. 创建 routes.json 文件(也可以不叫这个名字)
    2. 启动服务时使用 --routes 参数

    1、创建 routes.json ,并输入以下内容。

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

    2、启动服务

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

    3、访问

    http://localhost:3000/api/posts
    

    静态资源

    静态资源包含 htmlcssjs 、图片、视频等资源。

    配置

    配置方式分2种:

    • 默认配置
    • 指定资源位置

    默认配置

    需要在根目录下创建 public 文件夹,里面放入 html 等文件。

    35.png

    然后在浏览器访问一下 http://localhost:3000/

    36.png

    你也可以加入自己的 cssjs 进行设计交互。

    指定资源位置

    json-server 配资静态资源的默认方式是在根目录下创建 public 文件夹,然后里面放入静态资源。

    但如果你不想使用 public 作为静态资源的文件夹,也可以自己起过另一个名字,然后在启动环境时使用 --static 来指定目标目录就行了。

    比如我创建了一个 some-other-dir 作为静态资源的目录,使用以下命令指定以下即可。

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

    多媒体资源

    除了放 htmlcssjs 资源外,还可以放图片和视频。

    我以图片为例,我在 public 目录下添加一个图片。

    37.png

    直接在 http://localhost:3000/ 后面跟着 图片文件名 即可。

    38.png

    其他

    生成动态数据

    如果我们要模拟100条数据,甚至更多的话,创建 json 文件然后一条一条录入的方式真的很不合时。

    此时我们可以使用 js 通过循环的方式来实现数据创建。

    1、首先在根目录下创建一个 db.js 的文件。

    2、输入一下内容

    module.exports = () => {
      const data = { users: [] }
      // 创建 100 个 users
      for (let i = 0; i < 100; i++) {
        data.users.push({ id: i, name: `user${i}` })
      }
      return data
    }
    

    3、运行 js 文件

    json-server db.js
    

    4、查询一下

     http://localhost:3000/users
    
    39.png

    100条数据就直接生成了。

    需要什么字段可以自己在 js 文件里配置。

    查询整个数据库

    访问以下地址可以获得整个数据库的数据。

     http://localhost:3000/db
    

    远程模式

    如果想使用互联网上的数据,也可以直接运行 json-server 然后加上远端的地址即可。

    json-server http://jsonplaceholder.typicode.com/db
    

    如果本文能给您带来帮助,请帮我 点个赞 呗~

    转自:『前端必备』本地数据接口 —— json-server 从入门到膨胀

    相关文章

      网友评论

          本文标题:『前端必备』本地数据接口 —— json-server 从入门到

          本文链接:https://www.haomeiwen.com/subject/kzbafrtx.html