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 服务器?

  1. 使用最佳实践来构建 API,当构建你的 API 的时候,可以作为参考时限。
  2. 可以运行在 Windows、Linux 和 macOS 平台上,而不需要任何的安装或者预先的执行,或者 Docker 环境
  3. 功能列表如下

功能

  • 支持的 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 运行时,和所有需要的第三方依赖。不需要安装,也不需要预先设置。

  1. 访问 最新发布版本
  2. 根据你的操作系统下载对应版本
  3. 解压并执行

例如下载 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-datacontent-type: application/json。使用的用户名和密码必须来自 Users 中的 usernamepassword 字段。

获取 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,详细内容可以参考 GitHubStormPath'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 教程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值