RESTful Style:修订间差异
imported>Soleverlee |
无编辑摘要 |
||
(未显示2个用户的8个中间版本) | |||
第10行: | 第10行: | ||
通过操作资源的表现形式来操作资源。 | 通过操作资源的表现形式来操作资源。 | ||
资源的表现形式则是XML或者HTML,取决于读者是机器还是人,是消费web服务的客户软件还是web浏览器。当然也可以是任何其他的格式。 | 资源的表现形式则是XML或者HTML,取决于读者是机器还是人,是消费web服务的客户软件还是web浏览器。当然也可以是任何其他的格式。 | ||
=HTTP状态码= | |||
<pre> | |||
200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。 | |||
201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。 | |||
202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务) | |||
204 NO CONTENT - [DELETE]:用户删除数据成功。 | |||
400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。 | |||
401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。 | |||
403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。 | |||
404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。 | |||
406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。 | |||
410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。 | |||
422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。 | |||
500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。 | |||
</pre> | |||
=错误处理= | |||
如果状态码是4xx,就应该向用户返回出错信息。一般来说,返回的信息中将error作为键名,出错信息作为键值即可。 | |||
<source lang="lua"> | |||
{error: "Invalid API key"} | |||
</source> | |||
=返回值= | |||
针对不同操作,服务器向用户返回的结果应该符合以下规范。 | |||
<pre> | |||
GET /collection:返回资源对象的列表(数组) | |||
GET /collection/resource:返回单个资源对象 | |||
POST /collection:返回新生成的资源对象 | |||
PUT /collection/resource:返回完整的资源对象 | |||
PATCH /collection/resource:返回完整的资源对象 | |||
DELETE /collection/resource:返回一个空文档 | |||
</pre> | |||
=Hypermedia API= | |||
RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。 | |||
比如,当用户向api.example.com的根目录发出请求,会得到这样一个文档。 | |||
<pre> | |||
{"link": { | |||
"rel": "collection https://www.example.com/zoos", | |||
"href": "https://api.example.com/zoos", | |||
"title": "List of zoos", | |||
"type": "application/vnd.yourformat+json" | |||
}} | |||
</pre> | |||
上面代码表示,文档中有一个link属性,用户读取这个属性就知道下一步该调用什么API了。rel表示这个API与当前网址的关系(collection关系,并给出该collection的网址),href表示API的路径,title表示API的标题,type表示返回类型。 | |||
Hypermedia API的设计被称为HATEOAS。Github的API就是这种设计,访问api.github.com会得到一个所有可用API的网址列表。 | |||
<pre> | |||
{ | |||
"current_user_url": "https://api.github.com/user", | |||
"current_user_authorizations_html_url": "https://github.com/settings/connections/applications{/client_id}", | |||
"authorizations_url": "https://api.github.com/authorizations", | |||
"code_search_url": "https://api.github.com/search/code?q={query}{&page,per_page,sort,order}", | |||
"emails_url": "https://api.github.com/user/emails", | |||
"emojis_url": "https://api.github.com/emojis", | |||
"events_url": "https://api.github.com/events", | |||
"feeds_url": "https://api.github.com/feeds", | |||
"followers_url": "https://api.github.com/user/followers", | |||
"following_url": "https://api.github.com/user/following{/target}", | |||
"gists_url": "https://api.github.com/gists{/gist_id}", | |||
"hub_url": "https://api.github.com/hub", | |||
"issue_search_url": "https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}", | |||
"issues_url": "https://api.github.com/issues", | |||
"keys_url": "https://api.github.com/user/keys", | |||
"notifications_url": "https://api.github.com/notifications", | |||
"organization_repositories_url": "https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}", | |||
"organization_url": "https://api.github.com/orgs/{org}", | |||
"public_gists_url": "https://api.github.com/gists/public", | |||
"rate_limit_url": "https://api.github.com/rate_limit", | |||
"repository_url": "https://api.github.com/repos/{owner}/{repo}", | |||
"repository_search_url": "https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}", | |||
"current_user_repositories_url": "https://api.github.com/user/repos{?type,page,per_page,sort}", | |||
"starred_url": "https://api.github.com/user/starred{/owner}{/repo}", | |||
"starred_gists_url": "https://api.github.com/gists/starred", | |||
"team_url": "https://api.github.com/teams", | |||
"user_url": "https://api.github.com/users/{user}", | |||
"user_organizations_url": "https://api.github.com/user/orgs", | |||
"user_repositories_url": "https://api.github.com/users/{user}/repos{?type,page,per_page,sort}", | |||
"user_search_url": "https://api.github.com/search/users?q={query}{&page,per_page,sort,order}" | |||
} | |||
</pre> | |||
Refer: | Refer: | ||
*http://www.oschina.net/translate/best-practices-for-a-pragmatic-restful-api?lang=eng |Best Practices for Designing a Pragmatic RESTful API | |||
*http://www.ruanyifeng.com/blog/2014/05/restful_api.html | |||
[[Category:HTTP]] | |||
[[Category: |
2024年1月18日 (四) 01:53的最新版本
含状态传输(英文:Representational State Transfer,简称REST)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。
目前在三种主流的Web服务实现方案中,因为REST模式与复杂的SOAP和XML-RPC相比更加简洁,越来越多的web服务开始采用REST风格设计和实现。例如,Amazon.com提供接近REST风格的Web服务进行图书查找;雅虎提供的Web服务也是REST风格的。
要点及标准
需要注意的是,REST是设计风格而不是标准。REST通常基于使用HTTP,URI,和XML以及HTML这些现有的广泛流行的协议和标准。
资源是由URI来指定。 对资源的操作包括获取、创建、修改和删除资源,这些操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法。 通过操作资源的表现形式来操作资源。 资源的表现形式则是XML或者HTML,取决于读者是机器还是人,是消费web服务的客户软件还是web浏览器。当然也可以是任何其他的格式。
HTTP状态码
200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。 201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。 202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务) 204 NO CONTENT - [DELETE]:用户删除数据成功。 400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。 401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。 403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。 404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。 406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。 410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。 422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。 500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。
错误处理
如果状态码是4xx,就应该向用户返回出错信息。一般来说,返回的信息中将error作为键名,出错信息作为键值即可。
{error: "Invalid API key"}
返回值
针对不同操作,服务器向用户返回的结果应该符合以下规范。
GET /collection:返回资源对象的列表(数组) GET /collection/resource:返回单个资源对象 POST /collection:返回新生成的资源对象 PUT /collection/resource:返回完整的资源对象 PATCH /collection/resource:返回完整的资源对象 DELETE /collection/resource:返回一个空文档
Hypermedia API
RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。 比如,当用户向api.example.com的根目录发出请求,会得到这样一个文档。
{"link": { "rel": "collection https://www.example.com/zoos", "href": "https://api.example.com/zoos", "title": "List of zoos", "type": "application/vnd.yourformat+json" }}
上面代码表示,文档中有一个link属性,用户读取这个属性就知道下一步该调用什么API了。rel表示这个API与当前网址的关系(collection关系,并给出该collection的网址),href表示API的路径,title表示API的标题,type表示返回类型。
Hypermedia API的设计被称为HATEOAS。Github的API就是这种设计,访问api.github.com会得到一个所有可用API的网址列表。
{ "current_user_url": "https://api.github.com/user", "current_user_authorizations_html_url": "https://github.com/settings/connections/applications{/client_id}", "authorizations_url": "https://api.github.com/authorizations", "code_search_url": "https://api.github.com/search/code?q={query}{&page,per_page,sort,order}", "emails_url": "https://api.github.com/user/emails", "emojis_url": "https://api.github.com/emojis", "events_url": "https://api.github.com/events", "feeds_url": "https://api.github.com/feeds", "followers_url": "https://api.github.com/user/followers", "following_url": "https://api.github.com/user/following{/target}", "gists_url": "https://api.github.com/gists{/gist_id}", "hub_url": "https://api.github.com/hub", "issue_search_url": "https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}", "issues_url": "https://api.github.com/issues", "keys_url": "https://api.github.com/user/keys", "notifications_url": "https://api.github.com/notifications", "organization_repositories_url": "https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}", "organization_url": "https://api.github.com/orgs/{org}", "public_gists_url": "https://api.github.com/gists/public", "rate_limit_url": "https://api.github.com/rate_limit", "repository_url": "https://api.github.com/repos/{owner}/{repo}", "repository_search_url": "https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}", "current_user_repositories_url": "https://api.github.com/user/repos{?type,page,per_page,sort}", "starred_url": "https://api.github.com/user/starred{/owner}{/repo}", "starred_gists_url": "https://api.github.com/gists/starred", "team_url": "https://api.github.com/teams", "user_url": "https://api.github.com/users/{user}", "user_organizations_url": "https://api.github.com/user/orgs", "user_repositories_url": "https://api.github.com/users/{user}/repos{?type,page,per_page,sort}", "user_search_url": "https://api.github.com/search/users?q={query}{&page,per_page,sort,order}" }
Refer:
- http://www.oschina.net/translate/best-practices-for-a-pragmatic-restful-api?lang=eng |Best Practices for Designing a Pragmatic RESTful API
- http://www.ruanyifeng.com/blog/2014/05/restful_api.html