欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

服务计算 模仿 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