Sevice Computing:模仿 Github设计一个博客网站的 API

一、名词解释:API & REST

什么是API?

API是Application Programming Interface(应用程序接口)的缩写,它是拿来描述一个类库的特征或是如何去运用它。

什么是REST?

REST是Representational State Transfer(表现层状态转移)的缩写,它是由罗伊·菲尔丁(Roy Fielding)在2000年提出的软件软件架构模式,是用来描述创建HTTP API的标准方法的。

REST(Representational State Transfer)是Roy Fielding博士在2000年提出的软件软件架构模式。REST 是一种风格,而不是标准。因为既没有 REST RFC,也没有 REST 协议规范或者类似的规定。它只是提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件。Roy Fielding 把 REST 定义成一种架构风格,其目标是“使延迟和网络交互最小化,同时使组件实现的独立性和扩展性最大化”。

二、理解 Github API

通过网址https://api.github.com/users/用户名中我们可以看到关于用户个人的所有信息
下图为输入https://api.github.com/users/ZhengweiZhao后获取到的我的GitHub信息:

{
  "login": "ZhengweiZhao",
  "id": 55046922,
  "node_id": "MDQ6VXNlcjU1MDQ2OTIy",
  "avatar_url": "https://avatars1.githubusercontent.com/u/55046922?v=4",
  "gravatar_id": "",
  "url": "https://api.github.com/users/ZhengweiZhao",
  "html_url": "https://github.com/ZhengweiZhao",
  "followers_url": "https://api.github.com/users/ZhengweiZhao/followers",
  "following_url": "https://api.github.com/users/ZhengweiZhao/following{/other_user}",
  "gists_url": "https://api.github.com/users/ZhengweiZhao/gists{/gist_id}",
  "starred_url": "https://api.github.com/users/ZhengweiZhao/starred{/owner}{/repo}",
  "subscriptions_url": "https://api.github.com/users/ZhengweiZhao/subscriptions",
  "organizations_url": "https://api.github.com/users/ZhengweiZhao/orgs",
  "repos_url": "https://api.github.com/users/ZhengweiZhao/repos",
  "events_url": "https://api.github.com/users/ZhengweiZhao/events{/privacy}",
  "received_events_url": "https://api.github.com/users/ZhengweiZhao/received_events",
  "type": "User",
  "site_admin": false,
  "name": null,
  "company": null,
  "blog": "",
  "location": null,
  "email": null,
  "hireable": null,
  "bio": null,
  "public_repos": 14,
  "public_gists": 0,
  "followers": 0,
  "following": 0,
  "created_at": "2019-09-08T08:39:16Z",
  "updated_at": "2019-10-26T12:48:52Z"
}

其中包括很多xxx_url这些是查询其他部分信息的地址,比如

  • 获取个人所有repo

输入url https://api.github.com/users/用户名/repos

会得到一个repo的JSON格式列表,如下图所示:
在这里插入图片描述

三、REST API 设计原则

HTTP 协议定义了大量为请求赋于语义的方法。API访问都是通过HTTPS协议进行的,并通过https://api.blog.com进行访问,数据以JSON的形式发送和接收。

使用 HTTP 设计 RESTful API 时的一些主要原则:

  • REST API 围绕资源设计,资源是可由客户端访问的任何类型的对象、数据或服务。
  • 每个资源有一个标识符,即,唯一标识该资源的 URI。
  • 客户端通过交换资源的表示形式来与服务交互。 许多 Web API 使用 JSON 作为交换格式。
  • REST API 使用统一接口,这有助于分离客户端和服务实现。 对于基于 HTTP 构建的 REST API,统一接口包括使用标准 HTTP 谓词对资源执行操作。 最常见的操作是 GET、POST、PUT、PATCH 和 DELETE。
  • REST API 使用无状态请求模型。 HTTP 请求应是独立的并可按任意顺序发生,因此保留请求之间的瞬时状态信息并不可行。 信息的唯一存储位置就在资源内,并且每个请求应是原子操作。
  • REST API 由表示形式中包含的超媒体链接驱动。

基本操作:

  • GET
    GET 检索位于指定 URI 处的资源的表示形式。 响应消息的正文包含所请求资源的详细信息。
    成功的 GET 方法通常返回 HTTP 状态代码 200(正常)。 如果找不到资源,该方法应返回 404(未找到)。

  • POST
    POST 在指定的 URI 处创建新资源。服务器为新资源分配 URI,并将该 URI 返回给客户端。 在 REST 模型中,我们经常向集合应用 POST 请求。 新资源将添加到集合中。 还可以使用 POST 请求将待处理数据提交到现有资源,且不创建任何新资源。 请求消息的正文将提供新资源的详细信息。 请注意,POST 还用于触发不实际创建资源的操作。

  • PUT
    PUT 在指定的 URI 处创建或替换资源。请求消息的正文指定要创建或更新的资源。客户端指定资源的 URI。请求正文包含资源的完整表示形式。 如果已存在具有此 URI 的资源,则替换该资源。 否则创建新资源(如果服务器支持此操作)。 PUT 请求往往应用到单项资源(例如特定的客户)而不是集合。

  • PATCH
    PATCH 对资源执行部分更新。 请求正文包含要应用到资源的一组更改。 客户端指定资源的 URI。这比使用 PUT 更高效,因为客户端只发送更改,而无需发送资源的整个表示形式。

  • DELETE

  • DELETE 删除位于指定 URI 处的资源。

错误名称及描述: 在这里插入图片描述
HTTP verbs:
在这里插入图片描述

四、博客网站的 API设计

1. 当前版本

Accept: application/vnd.myblog.v3+json

2. 概要

  • API访问都是通过HTTPS协议进行的,并通过https://api.myblog.com进行访问,数据以JSON的形式发送和接收。
  • 我们假设当前用户为zzw
curl -i https://api.myblog.com/users/zzw
HTTP/1.1 200 OK
Server: nginx
Date: Tue, 19 Nov 2019 23:33:14 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Status: 200 OK
ETag: "a00049ba79152d03380c34652f2cb612"
X-GitHub-Media-Type: myblog.v3
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
  • 空白字段不会被忽略而会显示null。
  • 所有时间戳以ISO 8601 format被返回:YYYY-MM-DDTHH:MM:SSZ

3. 基本操作

  • GET
    在获取所有blog的列表时,响应包含该blog的属性子集。这是blog的“摘要”表示。
    获取所有的blog的URL如下所示:

    GET /user/zzw/blogs
    

    在获取单个博客时,响应通常包括该博客的所有属性。这是资源的“详细”表示。
    获取某个指定的blog,例如,名为helloworld的blog,其URL如下:

    GET /user/zzw/blog/helloworld
    

    GET可用于用户信息:

    GET /user/:username
    
  • POST
    新建blog使用POST请求,URL如下:

    POST /user/zzw/newblog
    
  • PUT
    更新一篇文章,如newblog时,使用PUT请求,其URL如下:

    PUT /user/zzw/blogs/newblog
    

    (因为一篇博客的局部更新和GitHub一个repo的部分文件更新不同,所以这里将PATCH功能删除了,我认为PUT就足够了)

  • DELETE
    删除一篇文章使用DELETE请求,例如,删除名称为helloworld的文章,其URL如下:

    DELETE /example/articles/helloworld
    

4. 参数

许多API方法采用可选参数。对于GET请求,任何未在路径中指定为段的参数都可以作为HTTP查询字符串参数传递:

curl -i "https://api.myblog.com/blogs/zzw/helloworld/issues?state=closed"

其中,zzw是user的参数,helloworld是blog的参数,:state传递路径参数。

对于POST、PATCH、PUT和DELETE请求,URL中没有包含的参数,应该用“application/ JSON”的内容类型编码为JSON:

curl -i -u username -d '{"scopes":["public_repo"]}' https://api.myblog.com/authorizations

5. 身份认证

有两种方法可以进行身份验证。需要身份验证的请求在某些地方将返回404 Not Found,而不是403 Forbidden。这是为了防止私有存储库意外泄漏给未经授权的用户。

  • 基本认证
curl -u "username" https://api.myblog.com
  • OAuth2 token (sent in a header)
curl -H "Authorization: token OAUTH-TOKEN" https://api.myblog.com

6. 错误信息

  • 400
    发送无效或错误类型的JSON将导致400 Bad Request响应:
    	HTTP/1.1 400 Bad Request
    Content-Length: 35 
    
    {"message":"Problems parsing JSON"}
    
    
    	HTTP/1.1 400 Bad Request
    Content-Length: 40
    
    {"message":"Body should be a JSON object"}
    
  • 401
    使用无效凭据进行身份验证将返回401未经授权:
    curl -i https://api.myblog.com -u foo:bar
    HTTP/1.1 401 Unauthorized
    {
      "message": "Bad credentials",
      "documentation_url": "https://developer.myblog.com/v3"
    }
    
  • 403
    在短时间内检测到多个具有无效凭据的请求后,API会暂时拒绝该用户的所有身份验证尝试(包括具有有效凭据的请求),并设置403禁止:
    curl -i https://api.myblog.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.myblog.com/v3"
    }
    
  • 422
    发送无效的字段将导致422 Unprocessable Entity响应:
    	HTTP/1.1 422 Unprocessable Entity
    	Content-Length: 149
    	
    	{
    	  "message": "Validation Failed",
    	  "errors": [
    	    {
    	      "resource": "Issue",
    	      "field": "title",
    	      "code": "missing_field"
    	    }
    	  ]
    	}
    

7. 分页

默认情况下,返回多个条目的请求将被分页为30个条目。可以使用?page参数指定其他页面。对于某些资源,还可以使用?per_page参数将自定义页面大小设置为100。

curl 'https://api.myblog.com/user/zzw/blogs?page=2&per_page=100'

8. 链接标题

链接标题包含分页信息:

Link: <https://api.myblog.com/user/zzw/blogs?page=3&per_page=100>; rel="next",
  <https://api.myblog.com/user/zzw/blogs?page=50&per_page=100>; rel="last"

五、参考资料

GitHub API
RESTful HTTP 的实践
Web API 设计

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值