服务计算|| 模仿 Github,设计一个博客网站的 API
一、RESTful HTTP 的实践
设计RESTful HTTP应用程序
-
基础原理
REST 是一种风格,而不是标准。因为既没有 REST RFC,也没有 REST 协议规范或者类似的规定。REST 架构是 Roy Fielding(他也是 HTTP 和 URI 规范的主要作者之一)在一篇论文中描述的。像 REST 这样的架构风格通常会定义一组高层决定让应用程序去实现。所有实现了某种特定架构风格的应用程序,都使用相同的模式,也用相同的方式使用别的架构元素,如缓存,分布式策略等。Roy Fielding 把 REST 定义成一种架构风格,其目标是“使延迟和网络交互最小化,同时使组件实现的独立性和扩展性最大化”
虽然 REST 受 Web 技术的影响很深,但是理论上 REST 架构风格并非绑定在 HTTP 上。然而,HTTP 是唯一与 REST 相关的实例。基于该原因,本文描述了通过 HTTP 实现的 REST,通常它也被称为 RESTful HTTP。
REST 并没有创造新的技术,组件或服务,隐藏在 RESTful HTTP 背后的理念是使用 Web 的现有特征和能力。RESTful HTTP 定义了如何更好地使用现有 Web 标准中的一些准则和约束。
-
应用统一接口
表 1 列出了大部分重要的方法 GET,DELETE,PUT 和 POST 的典型用法:
重要 方法 典型用法 典型状态码 安全? 幂等? GET - 获取表示- 变更时获取表示(缓存) 200(OK) - 表示已在响应中发出204(无内容) - 资源有空表示301(Moved Permanently) - 资源的 URI 已被更新303(See Other) - 其他(如,负载均衡)304(not modified)- 资源未更改(缓存)400 (bad request)- 指代坏请求(如,参数错误)404 (not found)- 资源不存在406 (not acceptable)- 服务端不支持所需表示500 (internal server error)- 通用错误响应503 (Service Unavailable)- 服务端当前无法处理请求 是 是 DELETE - 删除资源 200 (OK)- 资源已被删除301 (Moved Permanently)- 资源的 URI 已更改 303 (See Other)- 其他,如负载均衡400 (bad request)- 指代坏请求 t 404 (not found)- 资源不存在 409 (conflict)- 通用冲突500 (internal server error)- 通用错误响应 503 (Service Unavailable)- 服务端当前无法处理请求 否 是 PUT - 用客户端管理的实例号创建一个资源- 通过替换的方式更新资源- 如果未被修改,则更新资源(乐观锁) 200 (OK)- 如果已存在资源被更改 201 (created)- 如果新资源被创建301(Moved Permanently)- 资源的 URI 已更改303 (See Other)- 其他(如,负载均衡)400 (bad request)- 指代坏请求404 (not found)- 资源不存在406 (not acceptable)- 服务端不支持所需表示 /p>409 (conflict)- 通用冲突412 (Precondition Failed)- 前置条件失败(如执行条件更新时的冲突)415 (unsupported media type)- 接受到的表示不受支持500 (internal server error)- 通用错误响应503 (Service Unavailable)- 服务当前无法处理请求 否 是 POST - 使用服务端管理的(自动产生)的实例号创建资源- 创建子资源- 部分更新资源- 如果没有被修改,则不过更新资源(乐观锁) 200(OK)- 如果现有资源已被更改 201(created)- 如果新资源被创建 202(accepted)- 已接受处理请求但尚未完成(异步处理)301(Moved Permanently)- 资源的 URI 被更新 303(See Other)- 其他(如,负载均衡)400(bad request)- 指代坏请求 404 (not found)- 资源不存在 406 (not acceptable)- 服务端不支持所需表示 409 (conflict)- 通用冲突 412 (Precondition Failed)- 前置条件失败(如执行条件更新时的冲突) 415 (unsupported media type)- 接受到的表示不受支持500 (internal server error)- 通用错误响应 503 (Service Unavailable)- 服务当前无法处理请求 否 否
二、API接口设计
-
登录
curl -username "用户名" -password "密码" https://api.github.com/login
登录成功
返回200,登录成功,跳转页面到个人主页
登录失败
使用无效的凭据进行身份验证将返回
401 Unauthorized
:curl -i https://api.github.com -u foo:bar HTTP / 1.1 401未经授权 { “ message”:“错误的凭据”, “ documentation_url”:“ https://developer.github.com/v3” }
在短时间内检测到多个具有无效凭据的请求后,API会临时拒绝该用户的所有身份验证尝试(包括具有有效凭据的请求)
403 Forbidden
:curl -i https://api.github.com -u valid_username:valid_password HTTP / 1.1 403禁止 { “ message”:“已超过最大登录尝试次数。请稍后再试。”, “ documentation_url”:“ https:/ /developer.github.com/v3“ }
-
注册
curl -username "用户名" -email "邮箱" -password "密码" https://api.github.com/logon
注册成功
返回200,注册成功,跳转页面到个人主页
-
用户个人界面
curl -a https://api.github.com/username
返回json
{ "username":"xxxxx" "id":x "email":"xxxx" "description":"xxxxxxxxxxxxx" "articles_num":x }
-
博客列表界面
curl -a https://api.github.com/username/articles
分页
curl'https://api.github.com/username/articles/pages=2
列表对应博客页码
curl'https://api.github.com/username/articles/pages=2&per_page=10
返回json
{ "username":"xxx" "articles":[ { "A_id":x, "title":"xxxx", "author": { "username":"xxxxx", "id":x, "email":"xxxx", "description":"xxxxxxxxxxxxx", "articles_num":x, }, "description":"xxxxx", "private":true, "visit":xx, "mark":xx, "commamd":xx, "farvitor":xx, "created":"0000-00-00/00:00:00", "word":xxx, }, { "A_id":x, "title":"xxxx", "author": { "username":"xxxxx", "id":x, "email":"xxxx", "description":"xxxxxxxxxxxxx", "articles_num":x, }, "description":"xxxxx", "private":true, "visit":xx, "mark":xx, "commamd":xx, "farvitor":xx, "created":"0000-00-00/00:00:00", "word":xxx, }, ... ] }
-
博客文章界面
curl https://api.github.com/username/articles/id=1
id不存在返回404
返回json
{ "A_id":x, "title":"xxxx", "author": { "username":"xxxxx", "id":x, "email":"xxxx", "description":"xxxxxxxxxxxxx", "articles_num":x, }, "description":"xxxxx", "private":true, "visit":xx, "mark":xx, "commamd":xx, "farvitor":xx, "created":"0000-00-00/00:00:00", "word":xxx, "content":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "command_descirption":[ { "username":xxxx, "Cid":xxx, "time":"0000-00-00/00:00:00", "content":"xxx", "url":"xxxxx", } ], }
-
博客评论
curl https://api.github.com/username/articles/id=1&command=1
返回json
{ "command_descirption": { "username":xxxx, "Cid":xxx, "time":"0000-00-00/00:00:00", "content":"xxx", "url":"xxxxx", }, { "username":xxxx, "Cid":xxx, "time":"0000-00-00/00:00:00", "content":"xxx", "url":"xxxxx", }, { "username":xxxx, "Cid":xxx, "time":"0000-00-00/00:00:00", "content":"xxx", "url":"xxxxx", }, ... }