JSON 与 RESTful API

现代 Web 应用通常采用前后端分离架构。前端页面不再依赖整页刷新完成操作,而是通过 API(应用程序编程接口) 与后端交换结构化的 JSON 数据,从而实现添加、更新、删除等无刷新交互。

认识 JSON 数据格式

JSON(JavaScript Object Notation) 是一种轻量级的纯文本数据交换格式,常用于前后端之间传输数据。它主要由以下几种类型组成:

  • 对象(Object):用花括号 {} 包裹的一组键值对,键名和字符串值必须使用双引号 "",例如:{"book_id": 1, "name": "乌鸦"}。
  • 数组(Array):用方括号 [] 包裹的有序列表,例如:[1, 2, 3]。
  • 布尔值、数字与 null:true、false、123、null 等值不需要加引号。

RESTful API 设计规范与 CRUD

REST 风格的 API 通常把数据抽象为“资源”,并使用标准的 HTTP 方法表示对这些资源的操作。常见的业务操作包括创建、读取、更新和删除,也就是 CRUD。

业务操作HTTP 方法API 请求路径提交数据与 Content-Type预期成功状态码
查看我的书架列表 (Read)GET/api/bookshelf无请求体200 OK
添加一本新书到书架 (Create)POST/api/bookshelf{"book_id": 1}
application/json
201 Created
查询单本书的阅读记录 (Read)GET/api/bookshelf/1无请求体200 OK
更新某本书的阅读进度 (Update)PUT/api/bookshelf/1{"chapter": 2}
application/json
200 OK
将某本书从书架移除 (Delete)DELETE/api/bookshelf/1无请求体204 No Content

加入书架不整页跳转,POST 请求提交 JSON 书籍编号

我的书架页面通过 GET 接口读取 JSON 后显示收藏小说

第二章保存按钮发出 PUT,请求体指定 chapter 为 2

用 curl 实践 API 调用

下面使用 curl 命令,完整演示对示范书(book_id = 1)的 API 操作流程。

  1. 添加书籍到书架(POST + JSON):

    向书架接口提交一个 JSON 请求体,把书籍编号为 1 的书添加到书架中。

    crow@kali:~$ curl -sS -i -b cookies.txt -H 'Content-Type: application/json' -d '{"book_id":1}' "$target_url/api/bookshelf"
    HTTP/1.1 201 CREATED
    ...
    {"book_id":1,"chapter":1,"chapter_title":"第一章 第十三张床","sync_reference":"READ-1-1","title":"我在医院学斩鬼"}
    
  2. 更新阅读进度到第二章(PUT + JSON):

    使用 PUT 请求更新指定书籍的阅读进度。这里的 chapter 字段必须是整数,而不是字符串。

    crow@kali:~$ curl -sS -b cookies.txt -X PUT -H 'Content-Type: application/json' -d '{"chapter":2}' "$target_url/api/bookshelf/1"
    {"book_id":1,"chapter":2,"chapter_title":"第二章 夜班守则","sync_reference":"READ-1-2","title":"我在医院学斩鬼"}
    
  3. 重新查询当前进度(GET):

    再次请求该书籍的书架记录,确认阅读进度已经更新到第二章。

    crow@kali:~$ curl -sS -b cookies.txt "$target_url/api/bookshelf/1"
    {"book_id":1,"chapter":2,"chapter_title":"第二章 夜班守则","sync_reference":"READ-1-2","title":"我在医院学斩鬼"}
    

常见错误与排错思路

  • 如果向 API 提交 JSON 时漏掉了 -H 'Content-Type: application/json',服务器可能无法识别请求体类型,并返回 415 Unsupported Media Type。
  • 如果将数值字段误写成字符串,例如 {"chapter":"2"},服务器可能返回 400 Bad Request。
  • 请求失败时,可以按顺序检查:请求头是否声明了正确内容类型、请求体格式是否合法、字段名称是否正确、字段值类型是否符合接口要求。

改正请求时先看哪里

练习

书架接口已确认 Cookie 有效,要求 application/json,且 chapter 必须是整数。当前请求已经声明了正确内容类型,但请求体是 {"chapter":"2"},服务器返回 400,随后读取进度仍未改变。最直接的修正是哪项?

A. 把 chapter 的值改成数值 2 后重新发送。 B. 修改页面标题。 C. 换一个 User-Agent 即可,正文不影响结果。 D. 重复发送原请求,400 必然自动变成 200。

提交选项字母。

提交答案

题解 Hint

除了 GET 和 POST,RESTful 接口还用 PUT、DELETE 等方法表达不同操作。下面用 DELETE 亲手删除一条资源。

用 DELETE 方法删除一条置顶书评

Lab

启动笔趣城,点 TARGET Web 打开网站,需要时把入口地址复制到本机 curl。

书评接口在 /api/reviews。先用 GET 看看列表,其中有一条被站务置顶锁定(locked 为 true)的书评。用 DELETE 方法删除这条锁定书评,服务器会在响应里返回一个审核编号。提交这个以 COIN 开头的审核编号。

测试范围是当前实例,提交成功会结束会话。

加载会话状态…

提交 coin

题解 Hint