Fake JSON Server
Fake JSON Server
https://github.com/ttu/dotnet-fake-json-server
Fake JSON Server 是 Fake REST API,可以作为原型来模拟后端 API,活着临时用于 CRUD 的后端。Fake JSON Server 可以作为体验版的 GraphQL 查询和变化支持。
- 不需要定义资源类型,直接使用动态类型
- 不需要定义路由,路由动态处理
- 不需要数据库,数据保存在单个 JSON 文件中
- 不需要准备,只需要启动该服务器,API 就可以用于任何数据
为什么要使用它来替代其他的 Fake 服务器?
- 使用最佳实践来构建 API,当构建你的 API 的时候,可以作为参考时限。
- 可以运行在 Windows、Linux 和 macOS 平台上,而不需要任何的安装或者预先的执行,或者 Docker 环境
- 功能列表如下
功能
- 支持的 HTTP 方法
- 所有的 CRUD 操作 (GET、PUT、POST、PATCH、DELETE)
- 用来提取资源的方法 (HEAD、OPTIONS)
- 针对长时间的更新操作与查询提供的异步版本
- REST API 遵循多个来源的最佳实践
- 使用正确的状态吗、头部等等
- 由于各种最佳实践都有一点区别,这些冲突的地方基于你的观点
- Token、Basic 和 API Key 认证方式支持
- WebSocket 更新提示
- 针对查询的延迟与错误的仿真
- 静态文件支持
- Swagger 支持
- CORS
- 内容协商 (输出格式:JSON、CSV 与 XML)
- 使用 ETag 缓存并避免空中碰撞
- 可配置的定制化响应转换
- 体验版的 GraphQL 查询与修改支持
开发
- 使用 .NET 5
- 使用 JSON Flat File Data Store 来存储数据
- 可以安装微 dotnet 全局工具使用
- 可以不安装 .NET 就使用
- 使用 Docker
- 编译微自包含应用
目录
入门
使用 .NET CLI 启动
# Get source code from GitHub
$ git clone https://github.com/ttu/dotnet-fake-json-server.git
$ cd dotnet-fake-json-server/FakeServer
$ dotnet run
使用预先定义的数据文件和 url 启动服务器 ( 参数 )
# Optional arguments:
# --file <FILE> Data store's JSON file (default datastore.json)
# --urls <URL> Server url (default http://localhost:57602)
# --serve <PATH> Serve static files (default wwwroot)
# --version Prints the version of the app
$ dotnet run --file data.json --urls http://localhost:57602
安装为 .NET 全局工具
本服务器可以安装成 dotnet 全局工具。设置并保存文件到 %USERPROFILE%.dotnet\tools (Windows), $HOME/.dotnet/tools (Linux/macOS).。作为默认数据存储的 JSON 文件将被创建到执行目录中。
# install as a global tool
$ dotnet tool install --global FakeServer
# Example: Start server
$ fake-server --file data.json --urls http://localhost:57602
# Update to the newest version
$ dotnet tool update --global FakeServer
Docker
如果你的机器没有安装 .NET,可以通过 Docker 来使用。
# Get source code from GitHub
$ git clone https://github.com/ttu/dotnet-fake-json-server.git
$ cd dotnet-fake-json-server
$ docker build -t fakeapi .
# Run in foreground
$ docker run -it -p 57602:57602 --name fakeapi fakeapi
# Run in detached mode (run in background)
$ docker run -it -d -p 57602:57602 --name fakeapi fakeapi
# Start stopped container (remove -a to run in background)
$ docker start -a fakeapi
将 JSON 文件复制到/复制出 Docker 容器,文件名为 datastore.json。
# Copy file from host to container
$ docker cp datastore.json fakeapi:/app/datastore.json
# Copy file from container to host
$ docker cp fakeapi:/app/datastore.json datastore.json
111
自包含应用
作为自包含的应用,其中包含了 Fake JSON Server 本身,.NET 运行时,和所有需要的第三方依赖。不需要安装,也不需要预先设置。
- 访问 最新发布版本
- 根据你的操作系统下载对应版本
- 解压并执行
例如下载 macOS 的 0.11.0 版本
$ mkdir FakeServer && cd FakeServer
$ wget https://github.com/ttu/dotnet-fake-json-server/releases/download/0.11.0/fakeserver-osx-x64.tar.gz
$ tar -zxvf fakeserver-osx-x64.tar.gz
$ chmod +x FakeServer
$ ./FakeServer
静态文件支持
Fake Server 支持静态文件,静态文件的位置可以使用绝对路径,也可以使用相对于当前位置的相对路径。
$ dotnet run -s/--serve [fullpath/relative path]
# e.g.
$ dotnet run -s build
# Use Fake Server as a global tool
$ fake-server -s/--serve [fullpath/relative path]]
# e.g.
$ fake-server --serve c:\temp\react_app\build
$ fake-server --serve /home/user/app/dist
$ fake-server --serve ./build
当使用静态文件支持的时候,它假设用户服务于单页应用,而 REST API 将不再工作。如果还需要 API 支持,启动 Fake Server 的另外一个实例。
快速示例
# List collections (should be empty, if data.json didn't exist before)
$ curl http://localhost:57602/api
# Insert new user
$ curl -H "Content-type: application/json" -X POST -d '{ "name": "Phil", "age": 20, "location": "NY" }' http://localhost:57602/api/users/
# Insert another user
$ curl -H "Content-type: application/json" -X POST -d '{ "name": "James", "age": 40, "location": "SF" }' http://localhost:57602/api/users/
# List users
$ curl http://localhost:57602/api/users
# List users from NY
$ curl http://localhost:57602/api/users?location=NY
# Get User with Id 1
$ curl http://localhost:57602/api/users/1
...
# Add users to data.json manually
# Get all users
$ curl http://localhost:57602/api/users/
...
# Or open url http://localhost:57602/swagger/ with browser and use Swagger
示例项目
Redux TodoMVC 示例,使用 Fake JSON Server 作为后端服务。
特性
认证 Authentication
Fake REST API 支持 Token 和 BASIC 认证。
可以通过将 appsettings.json
中的 Authenticaion
中的 Enabled
设置为 false 来禁用。AuthenticationType
的类型可以是:
- token
- basic
- apikey
将支持的用户名和口令添加到 Users
仿数组中,而 API Key 则使用 ApiKey
属性进行设置。
"Authentication": {
"Enabled": true,
"AuthenticationType": "token",
"Users": [
{ "Username": "admin", "Password": "root" }
],
"ApiKey": "abcd1234"
}
Token 认证
API 服务器提供了用来生成访问令牌的端点 /token
。端点支持 content-type: multipart/form-data
和 content-type: application/json
。使用的用户名和密码必须来自 Users
中的 username
和 password
字段。
获取 Token
# content-type: multipart/form-data
$ curl -X POST -H 'content-type: multipart/form-data' -F username=admin -F password=root http://localhost:57602/token
# content-type: application/json
$ curl -X POST -H 'content-type: application/json' -d '{ "username": "admin", "password": "root" }' http://localhost:57602/token
令牌还可以使用 Client Credentials
认证流方式来获得。
$ curl -X POST -d "grant_type=client_credentials&client_id=admin&client_secret=root" http://localhost:57602/token
将获得的令牌添加到 Authorization 请求头中
$ curl -H 'Authorization: Bearer [TOKEN]' http://localhost:57602/api
Token 认证还提供了登出功能支持。默认令牌是不支持无效的,所以,通过 logout 来通过将 token 加入到黑名单。
$ curl -X POST -d '' -H 'Authorization: Bearer [TOKEN]' http://localhost:57602/logout
该实现非常类似于 SimpleTokenProvider,详细内容可以参考 GitHub 和 StormPath's blog post.
BASIC 认证
不建议在产品环境中使用 BASIC 认证,Base64 编码是可以逆向解密的。
将用户名和密码使用 Base64 编码之后,添加到 Authorization 请求头,例如:'Authorization: Basic YWRtaW46cm9vdA=='
$ curl -u admin:root http://localhost:57602/api
# -u argument creates Authorization header with encoded username and password
$ curl -H 'Authorization: Basic YWRtaW46cm9vdA==' http://localhost:57602/api
API Key 认证
API Key 使用 X-API-KEY
请求头,例如 X-API-KEY: abcd1234
.
$ curl -H 'X-API-KEY: abcd1234' http://localhost:57602/api
WebSockets 支持
API 将会使用 Web Socket 发送最后更新的方法 (POST, PUT, PATCH, DELETE), Path、collection 和可选的条目 id
{ "method": "PATCH", "path": "/api/users/2", "collection": "users", "itemId": 2 }
wwwroot/index.html 中包含一个 WebSocket 的示例。
CORS
CORS 已经被弃用,并全面支持。
静态文件
GET /
返回来自 wwwroot 或者自定义的位置 的静态文件。默认文件名为 index.html。
Swagger
Swagger 配置在端点 /swagger 下。
使用 ETag 实现缓存和避免空中碰撞
缓存可以禁用:
"Caching": {
"ETag": {
"Enabled": true
}
}
如果弃用了缓存,响应头中会添加 ETag 响应头。
$ curl -v 'http://localhost:57602/api/users?age=40'
200 OK
Headers:
ETag: "5yZCXmjhk5ozJyTK4-OJkkd_X18"
缓存不会改变的资源
如果请求包含 If-None-Match 请求头,该请求头的值将与响应体的内容相比较,如果该值与响应体的校验和匹配,那么会返回 304 Not Modified
。
$ curl -H "If-None-Match: \"5yZCXmjhk5ozJyTK4-OJkkd_X18\"" 'http://localhost:57602/api/users?age=40'
避免空中碰撞
如果 PUT 请求中包含 If-Match 请求头,其值将与被更新的项目相比较。如果该值匹配将要被更新的项目的校验和,那么将返回 412 Precondition Failed
内容协商
客户端可以通过 Accept 请求头来决定期望返回的表示类型。默认返回 JSON 格式 ( text/json,application/json)。
支持的协商类型是 JSON、CSV 和 XML
text/json
application/json
text/csv
text/xml
application/xml
获取 CSV 格式的所有用户
$ curl -H "Accept: text/csv" http://localhost:57603/api/users
如果提供的内容类型不被支持,将返回 406 Not Acceptable
路由、功能和示例
GET /
POST /token
POST /logout
POST /admin/reload
GET /api
HEAD /api
GET /api/{collection/object}
HEAD /api/{collection/object}
POST /api/{collection}
GET /api/{collection}/{id}
HEAD /api/{collection}/{id}
PUT /api/{collection}/{id}
PATCH /api/{collection}/{id}
DELETE /api/{collection}/{id}
PUT /api/{object}
PATCH /api/{object}
DELETE /api/{object}
OPTIONS /api/*
GET /async/queue/{id}
DELETE /async/queue/{id}
POST /async/{collection}
PUT /async/{collection}/{id}
PATCH /async/{collection}/{id}
DELETE /async/{collection}/{id}
OPTIONS /async/*
POST /graphql
集合与对象
Fake JSON Server 被设计作为原型,所以默认支持的仅有资源是集合。
如果该 JSON 文件只有单个对象在根上,那么作为单个对象使用。
{
"collection": [],
"object": {}
}
路由
动态路由使用条目集合的名称和 id:api/{collection}/{id}
。所有下面的示例都使用 users 作为集合名称。
如果由于某种原因,需要修改 /api 或者 /async ,通过 Config.cs 中的 ApiRoute 或者 AsyncRoute 来实现。
public class Config
{
public const string ApiRoute = "api";
public const string AsyncRoute = "async";
public const string GraphQLRoute = "graphql";
public const string TokenRoute = "token";
public const string TokenLogoutRoute = "logout";
}
例如,如果不希望使用 api 前缀,那么可以通过 ApiRoute 来删除 api 前缀。
public const string ApiRoute = "";
使用
# Query with default route
$ curl 'http://localhost:57602/api/users?skip=5&take=20'
# Query with updated route
$ curl 'http://localhost:57602/users?skip=5&take=20'
标识
id
用来作为标识字段,默认的 id 字段类型为整数,POST 操作总是使用整数作为 id 的类型。
"users":[
{ "id": 1 }
],
"sensors": [
{ "id": "E:52:F7:B3:65:CC" }
]
如果使用字符串作为标识类型,那么条目必须使用 PUT 插入,并且 appsetting.json 中的 UpsertOnPut 必须设置为 true。
返回码
异步操作遵循 REST 菜谱手册。更新将返回 202,使用 Location 响应头来将条目排入队列中。队列在操作处理中将返回 200,当 job 完成,而 Location 头对新条目变化的时候,返回 303
方法的返回码遵循 REST API 教程
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?