一个会保存写操作的 JSONPlaceholder 替代品

同样类型的资源,但写操作会被保存,错误输入会被拒绝,错误也可以随时触发。

示例最后一次针对 API 运行于

JSONPlaceholder 的写操作是假的:POST 返回 id: 101,但对这个 id 发 GET 会返回 404,DELETE 之后记录也还在。如果你的应用需要读回刚写入的内容,请用 https://api.testingapis.com/api登录后查看。 它有同样类型的资源(帖子、评论、相册、照片、待办和用户),创建、更新和删除都会被保存。它还会用 400 拒绝无效输入,并能按需让任何请求失败, 所以你也可以构建和测试各种错误状态。它免费、无需密钥,并允许任何来源的请求。

会被保存的写操作

JSONPlaceholder 对新帖子是这样处理的:

Terminal
$ curl -X POST https://jsonplaceholder.typicode.com/posts \
  -H "Content-Type: application/json" \
  -d '{"title":"hello","body":"world","userId":1}'
{ "title": "hello", "body": "world", "userId": 1, "id": 101 }

$ curl -i https://jsonplaceholder.typicode.com/posts/101
HTTP/1.1 404 Not Found

在这里走同样的步骤:创建帖子、读回、编辑、删除,然后确认它已不存在。

Terminal
$ curl -X POST https://api.testingapis.com/api/Posts \
  -H "Content-Type: application/json" \
  -d '{"userId":101,"title":"Hello from the guide","body":"Checking that writes persist."}'
{"message":"Post created successfully","data":{"id":16,"userId":101,"title":"Hello from the guide","body":"Checking that writes persist.","tags":[],"publishedAt":"2026-10-07T02:58:58Z","likes":0}}

$ curl https://api.testingapis.com/api/Posts/16
{"id":16,"userId":101,"title":"Hello from the guide","body":"Checking that writes persist.","tags":[],"publishedAt":"2026-10-07T02:58:58Z","likes":0}

$ curl -X PUT https://api.testingapis.com/api/Posts/16 \
  -H "Content-Type: application/json" \
  -d '{"userId":101,"title":"Edited title","body":"Checking that writes persist."}'
{"message":"Post updated successfully","data":{"id":16,"userId":101,"title":"Edited title",...}}

$ curl -X DELETE https://api.testingapis.com/api/Posts/16
{"message":"Post deleted successfully"}

$ curl -i https://api.testingapis.com/api/Posts/16
HTTP/1.1 404 Not Found

{"status":404,"error":"Not Found","message":"Post with ID 16 does not exist."}

路由对照

JSONPlaceholdertestingapis.com记录
/posts/api/posts15(JSONPlaceholder:100)
/posts/1/comments/api/posts/1/comments帖子 1 的评论
/comments/api/commentsdocs50(500)
/albums/api/albumsdocs10(100)
/albums/1/photos/api/albums/1/photos登录后查看每个相册 5 张
/photos/api/photosdocs50(5,000)
/todos/api/todos30(200)
/users/api/peopledocs20(10),带地址、地理坐标和公司
/users/1/posts/api/posts/user/101用户 id 从 101 开始

路径不区分大小写:/api/posts 和 /api/Posts 是一样的。记录数比 JSONPlaceholder 少,但每条记录的字段更多。 帖子有标签、点赞和发布日期,待办有优先级和截止日期,人员有嵌套的地址和公司。API 文档还列出了另外 13 种资源,从商品和购物车到图书、电影和国家。

GET/api/posts/1

错误的输入会收到错误

JSONPlaceholder 接受任何请求体,即使是空的。在这里,缺少必填字段会返回带消息的 400,所以你表单的错误分支能显示真实的内容:

Terminal
$ curl -i -X POST https://jsonplaceholder.typicode.com/posts -H "Content-Type: application/json" -d '{}'
HTTP/1.1 201 Created

{ "id": 101 }

$ curl -i -X POST https://api.testingapis.com/api/Posts -H "Content-Type: application/json" -d '{"title":""}'
HTTP/1.1 400 Bad Request

{"status":400,"error":"Bad Request","message":"Missing required field: title"}

按需获得错误和慢响应

给任意请求加上 ?error=500 就会以该状态码失败,加上 ?delay=3 会晚三秒响应。两者结合,?delay=2&error=503 会先显示加载状态再显示错误。错误响应指南介绍了超时、重试和限流。

GET/api/todos/1?error=503

筛选、排序和分页

两个 API 都能按字段筛选列表,比如 ?userId=101,也都支持排序、搜索和分页。只是参数名不同:

JSONPlaceholdertestingapis.com
筛选?userId=1?userId=101
分页?_page=2&_limit=10?page=2&limit=10
排序?_sort=id&_order=desc?sort=id&order=desc
搜索?q=word?q=word
总数X-Total-CountX-Total-Count、X-Total-Pages

迁移一个应用

读操作和 JSONPlaceholder 一样直接返回记录。写操作会用一条消息包裹记录,形如 { message, data },用户 id 从 101 开始。这就是大多数应用需要做的两处修改:

JavaScript
// Before
const BASE = "https://jsonplaceholder.typicode.com";
const post = await (await fetch(`${BASE}/posts/1`)).json();

const created = await (await fetch(`${BASE}/posts`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ userId: 1, title: "Hi", body: "There" }),
})).json();

// After
const BASE = "https://api.testingapis.com/api";
const post = await (await fetch(`${BASE}/posts/1`)).json();

const { data: created } = await (await fetch(`${BASE}/posts`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ userId: 101, title: "Hi", body: "There" }),
})).json();
这个示例使用的是面向已登录成员的端点。登录创建免费账户

什么时候 JSONPlaceholder 更合适

  • 你需要大列表,比如用 5,000 张照片测试虚拟滚动。
  • 你在跟一个使用 JSONPlaceholder 确切 id 和字段的教程。
  • 你只读数据,从不需要写入的内容在之后出现。

想进一步了解,CRUD 测试课程讲解了如何确认每一次创建、更新和删除确实发生了。