RESTful API 概述

基本概念

REST 英文全称:Representational State Transfer,直译为:表现层状态转移。首次是由Roy Thomas Fielding在他2000年的博士论文中提出。

REST是一种描述网络中clientserver之间的资源交互方式。

RESTful API就是完全遵循REST方式的一套API设计规范,简单来说,通过API来描述资源的访问方式:

  • 通过HTTP URL描述访问什么资源
  • 通过HTTP METHOD描述对资源的交互方式
  • 通过HTTP CODE描述资源的交互结果

幂等性

幂等性(Idempotence)本身是一个数学概念,在HTTP/1.1规范中幂等性是指

Methods can also have the property of “idempotence” in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.

如果某个方法调用一次或多次产生的副作用是相同的,那么这个方法具有幂等性。

比如在HTTP中使用GET获取某个资源,无论调用多少次,产生的额外效果都是从服务器获取资源,所以GET方式具有幂等性。

而POST方法用于在服务器上创建一个资源,由于最终创建的结果每次都是不同的,所以POST不具有幂等性。

但是PUT方法却是幂等的,因为每次调用产生的效果都是对资源进行更新。

安全方法

安全方法是指不修改资源的 HTTP 方法。譬如,当使用 GET 或者 HEAD 作为资源 URL,都必须不去改变资源的表现形式。

注意:安全方法并不是指服务器上的资源完全不变,而是指资源的表现形式。

比如GET方法导致数据上报,关联的一些数据记录等,他实际上是改变了服务器上的某些附加资源的,但是这并不会改变资源的表现形式。

HTTP方法特性概览

HTTP Method 幂等性 安全性
OPTIONS yes yes
GET yes yes
HEAD yes yes
PUT yes no
POST no no
DELETE yes no
PATCH no no

RESTful API设计规则

HTTP URL

HTTP URL只用于描述访问的资源,而不应该包含对资源的交互方式。HTTP URLBest Practice:

  • 将API部署在专用的域名上,如api.example.com
  • 不使用任何大写字符
  • 不使用下划线_,可使用中划线-代替来分割单词
  • 参数列表要进行URL编码
  • 不应该出现描述资源交互方式的动词,应尽量使用描述资源的名词
  • URI中的名词表示资源集合,应该使用复数形式
  • 应该避免资源层级太深,可以适当使用参数减少层级
  • 使用斜杆/表示资源之间的层级关系
  • URI的末尾避免使用/
  • 避免在URI中使用文件扩展名
  • 如果有必要,需要在URI中添加版本号标识

相应的示例如下:

// 下面列出几个bad case以及修改方法
/userPost // should use uppercase letter
-> /user-posts /user/post // should use resource plural
-> /users/posts /users/addPost // avoid using react verb
-> POST /users/posts /users/posts/ // remove the last `/`
-> /users/posts /users/posts/picture.gif // remove the extension `.gif`
-> /users/posts/picture /users/recent_posts // use `-` replace `_`
-> /users/recent-posts /users/posts?title=up up // param encode
-> /users/posts?name=up%20up /users/posts/games/picture/today // avoid too deep relations
-> /users/posts/picture?type=game&time=today /users/learning-posts // add version tag
-> /v1/users/learning-posts

补充说明:

  • /users/search像这个URI,虽然包含动词search,但是search并没有描述对资源的交互方式,所以这种URI也是可以的
  • /users/posts, /user-posts这样的两个URI,第一个描述了层级关系,第二个没有,但是两个URI任然能够很明确的表示资源,并没有谁最好的说法,可以结合所在团队的命名习惯等来选取

HTTP METHOD

严格使用下面的HTTP方法来描述资源CURD操作方式,应该尽量避免在POST方式中删除资源等违背直觉的操作:

  • GET: 查询资源
  • POST: 创建资源
  • PUT: 更新资源
  • DELETE: 删除资源

对于一些GET中一次性获取大量资源的情况下,比如获取一万个指定资源的情况,可能会出现HTTP URL超过长度限制,这个时候可以分批获取。

虽然新版的HTTP标准支持在GET请求中传送body,但是一些网络服务器并不能很好的支持,应该慎重使用。

另外对于复杂的资源获取,应该提供通用的资源筛选、排序、分页、字段选择等功能支持,并统一参数规范。例如:

Filtering:
GET /cars?color=red Returns a list of red cars
GET /cars?seats<=2 Returns a list of cars with a maximum of 2 seats Sorting:
GET /cars?sort=-manufactorer,+model Field selection:
GET /cars?fields=manufacturer,model,id,color Paging:
GET /cars?offset=10&limit=5

覆盖HTTP方法

一些HTTP客户端只支持GET和POST请求。为了能够加强这些客户端的访问能力,API需要能够覆盖HTTP方法。

尽管这里没有任何强制的标准,但流行的做法是API会接收一个请求头X-HTTP-Method-Override,它的值可以是PUT、PATCH或者DELETE三者之一。

注意,用来覆盖HTTP方法的header只能在POST请求中被接受。GET请求永远不能修改服务器上的数据。

HTTP RESPONSE

关于HTTP请求的返回值,有以下几点Best Practice:

  • 采用格式化返回数据,推荐json
  • 充分利用HTTP状态码来描述错误类型
  • 规范返回数据的统一格式,以及细分错误类型和提示
  • 应该尽量返回有用的错误信息和提示,唯一的错误码

常用的HTTP状态码:

  • 200 OK - 对成功的GET、PUT、PATCH或DELETE操作进行响应。也可以被用在不创建新资源的POST操作上
  • 201 Created - 对创建新资源的POST操作进行响应。应该带着指向新资源地址的Location header)
  • 204 No Content - 对不会返回响应体的成功请求进行响应(比如DELETE请求)
  • 304 Not Modified - HTTP缓存header生效的时候用
  • 400 Bad Request - 请求异常,比如请求中的body无法解析
  • 401 Unauthorized - 没有进行认证或者认证非法。当API通过浏览器访问的时候,可以用来弹出一个认证对话框
  • 403 Forbidden - 当认证成功,但是认证过的用户没有访问资源的权限
  • 404 Not Found - 当一个不存在的资源被请求
  • 405 Method Not Allowed - 所请求的HTTP方法不允许当前认证用户访问
  • 410 Gone - 表示当前请求的资源不再可用。当调用老版本API的时候很有用
  • 415 Unsupported Media Type - 如果请求中的内容类型是错误的
  • 422 Unprocessable Entity - 用来表示校验错误
  • 429 Too Many Requests - 由于请求频次达到上限而被拒绝访问

参考文档

RESTFul API最佳实践的更多相关文章

  1. 我所理解的Restful API最佳实践

    一直在公司负责API数据接口的开发,期间也遇到了不小的坑,本篇博客算是做一个小小的记录. 1. 不要纠结于无意义的规范    在开始本文之前,我想先说这么一句:RESTful 真的很好,但它只是一种软 ...

  2. 我所认为的RESTful API最佳实践

    我所认为的RESTful API最佳实践 不要纠结于无意义的规范 在开始本文之前,我想先说这么一句:RESTful 真的很好,但它只是一种软件架构风格,过度纠结如何遵守规范只是徒增烦恼,也违背了使用它 ...

  3. REST与RESTFul API最佳实践

    我经常会面试一些做PHP的开发者,让我很奇怪的是,10个人总有8个多不知道什么是REST服务,甚至是没有听说过.但RESTFul API已经是现在互联网里对外开放接口的主流模式,可参考: 豆瓣API  ...

  4. Restful Api 最佳实践

    Web APIs has become an very important topic in the last year. We at M-Way Solutions are working ever ...

  5. RESTful API 最佳实践(转)

    原文:http://www.ruanyifeng.com/blog/2018/10/restful-api-best-practices.html 阮一峰老师的文章,他的文章把难懂的东西讲的易懂 RE ...

  6. Restful API 最佳实践 (理论篇)

    参考: http://www.ibm.com/developerworks/cn/web/1103_chenyan_restapi/ 规划好 资源标示结构 和 URI模式, 是API设计成功的关键 原 ...

  7. RESTful API 最佳实践----转载阮一峰

    文章地址http://www.ruanyifeng.com/blog/2018/10/restful-api-best-practices.html

  8. 我们必须要知道的RESTful服务最佳实践

    看过很多RESTful相关的文章总结,参齐不齐,结合工作中的使用,非常有必要归纳一下关于RESTful架构方式了,RESTful只是一种架构方式的约束,给出一种约定的标准,完全严格遵守RESTful标 ...

  9. ASP.NET Core Web API 最佳实践指南

    原文地址: ASP.NET-Core-Web-API-Best-Practices-Guide 介绍 当我们编写一个项目的时候,我们的主要目标是使它能如期运行,并尽可能地满足所有用户需求. 但是,你难 ...

随机推荐

  1. Jquery toastr提示框

    toastr是一个基于JQuery的消息提示插件; 1. 下载toastr和jquery https://jquery.com/download/ https://codeseven.github.i ...

  2. 国庆佳节第四天,谈谈我月收入增加 4K 的故事

    01.起承 在我下定决心改变的这将近 1 年的时间里,遇到了很多很多有故事的人,以及有趣的事.自我的认知改变特别大!尤其是收入,比去年同时期增加了 4K. 4K,可能也就买 100 斤猪肉.但是对于身 ...

  3. 体验Code::Blocks下的Windows GUI编程(32 bit and 64 bit)

    0. 前言 不知道为什么,几乎所有的C++编程教程都是从命令行版(控制台应用程序)的Hello World开始的.然而,对于现在的年轻人来说,从小就用鼠标点击窗口或图标操作电脑,对于那个神秘黑色的窗口 ...

  4. python句柄部分操作

    ```python3# 通过窗口类名.窗口标题获取控件句柄hwnd = win32gui.FindWindow("ClassName", "TitleName" ...

  5. C++代码注入

    一.C++代码注入原则: 在注入代码中不允许使用API. 在注入代码中不允许使用全局变量. 在注入代码中不允许使用字符串(编译时也被当做全局变量). 在注入代码中不允许使用函数嵌套. 二.注入代码编写 ...

  6. Spring 源码阅读 一

    终于,有一天我也来看Spring的源码了,看了一阵之后感觉心情那叫一个舒畅,对Spring底层的实现也有了进一步的了解, 最直观的感受就是Spring的命名风格很赞,很长,真的长到使人见名知意, 闲言 ...

  7. @DateTimeFormat注解

    @DateTimeFormat在spring-context依赖下,所在包如下 当form表单中出现时间字段需要跟pojo对象中的成员变量进行数据绑定时,springmvc框架中的时间数据无法自动绑定 ...

  8. 服务器时间误差导致的google sign-in后台验证错误(远程调试java程序)

    https://developers.google.com/identity/sign-in/web/backend-auth import com.google.api.client.googlea ...

  9. Vue-懒加载(判断元素是否在可视区域内)

    上公式: 元素距离顶部高度(elOffsetTop) >= dom滚动高度(docScrollTop) 并且元素距离顶部高度(elOffsetTop) < (dom滚动高度 + 视窗高度) ...

  10. linux分区与挂载

    分区是将一个硬盘驱动器分成若干个逻辑驱动器,分区是把硬盘连续的区块当做一个独立的磁盘使用.分区表是一个硬盘分区的索引,分区的信息都会写进分区表.通常情况下,为磁盘分区通常使用fdisk,它是对基于MB ...