服务计算 模仿 Github API 简单设计一个博客 API
程序员文章站
2022-07-08 16:44:51
...
模仿 Github API 简单设计一个博客网站的 API
REST 是一种基于超媒体构建分布式系统的架构风格。 REST 独立于任何基础协议,并且不一定绑定到 HTTP。
REST API 设计原则
- REST API 围绕资源设计,资源是可由客户端访问的任何类型的对象、数据或服务。
- 每个资源有一个标识符,即唯一标识该资源的 URI。
- 客户端通过交换资源的表示形式来与服务交互。 许多 Web API 使用 JSON 作为交换格式。
- REST API 使用统一接口,使用标准 HTTP 谓词对资源执行操作。 最常见的操作是 GET、POST、PUT、PATCH 和 DELETE。
- REST API 使用无状态请求模型。 HTTP 请求应是独立的并可按任意顺序发生,每个请求应是原子操作。
- REST API 由表示形式中包含的超媒体链接驱动。
简单博客 API 设计
当前版本
- v1
Accept: application/vnd.ssblog.v1+json
架构图
- 所有 API 访问都通过 https 进行,通过
https://api.ssblog.com
来访问所有数据。
curl -i https://api.ssblog.com/username
HTTP/1.1 200 OK
Server: nginx
Date: Fri, 12 Nov 2019 23:33:14 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Status: 200 OK
ETag: "a00049ba79152d03380c34652f2cb558"
X-SSBlog-Media-Type: ssblog.v1
X-RateLimit-Limit: 5000
X-RateLimit-Remaining: 4987
X-RateLimit-Reset: 1350085394
Content-Length: 5
Cache-Control: max-age=0, private, must-revalidate
X-Content-Type-Options: nosniff
操作
用户登录
- 基本认证
curl -i https://api.ssblog.com -u username:password
- OAuth2 授权
curl 'https://api.ssblog.com/users/whatever?client_id=xxxx&client_secret=yyyy'
- 登陆限制失败,使用无效的凭据进行身份验证返回 401
curl -i https://api.ssblog.com -u invalid_user:password
HTTP/1.1 401 Unauthorized
{
"message": "Bad credentials",
"documentation_url": "https://developer.ssblog.com/v1"
}
- 在短时间内检测到多个具有无效凭据的请求后,API会临时拒绝该用户的所有身份验证尝试(包括具有有效凭据的请求)返回
403 Forbidden
curl -i https://api.github.com -u valid_username:valid_password
HTTP/1.1 403 Forbidden
{
"message": "Maximum number of login attempts exceeded. Please try again later.",
"documentation_url": "https://developer.ssblog.com/v1"
}
获取当前登录用户信息
GET /username
- 返回示例
Status:200 OK
{
"Username": "username",
"UserId": "4566ea6b-f2b3",
"BlogId": 3,
"DisplayName": "XXX",
"Avatar": "https://api.ssblog.com/username/avatar",
"Seniority": "level",
}
查看用户关注的人
GET /username/follows
- 返回示例
Status:200 OK
{
"number": 7,
"users":[
{
"username": "user1",
"user_url": "user_url1"
},
...
]
}
查看关注者
GET /username/followers
- 返回示例
Status:200 OK
{
"number": 5,
"users":[
{
"username": "userA",
"user_url": "user_urlA"
},
...
]
}
查看博客
- 获得用户博客列表时,将获得每个存储库的摘要表示。
Get /username/blogs
- 返回示例
Status:200 OK
{
"post_count": 72,
"items": [
{
"blogId": 40823,
"title": "CS-learning",
"Username": "username",
"blog_url": "https://api.ssblog.com/username/blogs/40823",
"Data": "2019-10-30",
"secret": false
},
...
]
}
获取单个博客
Get https://api.ssblog.com/username/blogs/{blogId}
- 返回示例
Status:200 OK
{
"blogId": 40823,
"title": "CS-learning",
"owner": {
"Username": "username",
"UserId": "4566ea6b-f2b3",
"url": "https://api.ssblog.com/username"
},
"blog_url": "https://api.ssblog.com/username/blogs/40823",
"pageviews": 222,
"tags": {
"CS",
...
}
"pageSize": 10,
"Data": "2019-10-30",
"secret": false,
"comments": "https://api.ssblog.com/username/blogs/40823/comments"
}
查看文章评论
Get /username/blogs/{blogId}/comments
- 返回示例
Status:200 OK
{
"blogId": 40823,
"author": "username",
"blog_url": "https://api.ssblog.com/username/blogs/40823",
"count": 3,
"items": [
{
"content": "...",
"user": {
"Username": "username",
"url": "https://api.ssblog.com/username"
},
"Date": "2019-11-2"
}
...
]
}
添加收藏
POST https://api.ssblog.com/another_user/favorate
Content-Type: application/json; charset=utf-8
Content-Length: ...
{
"title": "CS-learning",
"blog_url": "https://api.ssblog.com/username/blogs/40823"
}
- 返回示例
Status 201 OK
{
"user":{
"username": "another_user",
"userId": "3679ee1-2d17",
"user_url": "https://api.ssblog.com/another_user"
},
"title": "CS-learning",
"fav_url": "https://api.ssblog.com/username/blogs/40823"
}
添加评论
POST /username/blogs/40823/comments
{
"body": "..."
}
- 返回示例
Status:201 CREATE
{
"blogId": 40823,
"author": "username",
"blog_url": "https://api.ssblog.com/username/blogs/40823",
"content": "...",
"user": {
"Username": "username",
"url": "https://api.ssblog.com/username"
},
"Date": "2019-11-3"
}
发布博客
POST /username/blogs
{
"body": "",
"title": "new blog",
"secret": false,
"tags": {
"CS",
...
}
}
- 返回示例
Status: 201 CREATED
{
"blogId": 57336,
"title": "new blog",
"owner": {
"Username": "username",
"UserId": "4566ea6b-f2b3",
"url": "https://api.ssblog.com/username"
},
"blog_url": "https://api.ssblog.com/username/blogs/57336",
"pageviews": 0,
"tags": {
"CS",
...
}
"pageSize": 10,
"Data": "2019-11-10",
"secret": false,
"comments": "https://api.ssblog.com/username/blogs/57336/comments"
}
修改博客
PUT /username/blogs/57336
{
"body": "...",
"title": "new title",
...
}
- 返回示例
Status:200 OK
{
"blogId": 57336,
"title": "new title",
"owner": {
"Username": "username",
"UserId": "4566ea6b-f2b3",
"url": "https://api.ssblog.com/username"
},
"blog_url": "https://api.ssblog.com/username/blogs/57336",
"pageviews": 10,
"tags": {
"CS",
...
}
"pageSize": 10,
"Data": "2019-11-10",
"secret": false,
"comments": "https://api.ssblog.com/username/blogs/57336/comments"
}
删除博客
DELETE /username/blogs/57336
- 返回示例
Status: 204 NO CONTENT
上一篇: rpm包方式升级OpenSSL8.0版本
下一篇: BeanMapping发布1.0.2版本