RESTful API规范

RESTful 规范指南:

1. HTTP 协议

API 与用户的通信协议, 总是使用 HTTPS 协议

2. 域名:


# 子域名方式:(解决跨域的问题)
    www.baidu.com
    api.baidu.com
# 存在跨域的风险
    
    
# =========================================
# URL 方式:
    www.baidu.com
    www.baidu.com/api/

3. 版本:


URL  如: https://api.baidu.com/v1/   
# 一般情况下都放在 url 上
请求头:                           跨域时, 引发发送多次请求

4. 路径

视网络上的一切都为资源, 均使用名词表示(可使用复数)


https://api.baidu.com/v1/zoos
https://api.baidu.com/v1/animals
https://api.baidu.com/v1/employees

5. method


GET:     从服务器取出资源(一项或多项)
POST:    在服务器新建一个资源
PUT:     在服务器更新资源( 客户端提供改变后的完整资源 )
PATCH:   在服务器更新资源( 客户端提供改变的属性 )
DELETE:  在服务器删除资源

6. 过滤:

通过在 URL 上传参的形式传递搜索条件


https://api.baidu.com/v1/zoos?limit=10      : 指定返回记录的数量
https://api.baidu.com/v1/zoos?offset=10     : 指定返回记录的开始位置
https://api.baidu.com/v1/zoos?page=2&per_page=100  : 指定第几页, 以及每页的记录数
https://api.baidu.com/v1/zoos?sortby=name&order=asc    : 指定返回结果按照那个属性排序, 以及排序顺序
https://api.baidu.com/v1/zoos?animal_type_id = 1        : 指定筛选条件   

7. 状态码:

  • 常用状态码:

200 – OK – 一切正常 
201 – OK – 新资源已经被创建 
204 – OK – 资源删除成功

304 – 没有变化,客户端可以使用缓存数据

400 – Bad Request – 调用不合法,确切的错误应该在error payload中描述,例如:“JSON 不合法 ” 
401 – 未认证,调用需要用户通过认证 
403 – 不允许的,服务端正常解析和请求,但是调用被回绝或者不被允许 
404 – 未找到,指定的资源不存在 
422 – 不可指定的请求体 – 只有服务器不能处理实体时使用,比如图像不能被格式化,或者重要字段丢失。

500 – Internal Server Error – 标准服务端错误,API开发人员应该尽量避开这种错误
  • 状态码和 code 结合使用
  • 全部状态码:

建议不要在回复中使用裸状态代码。REST框架包含一组命名常量,您可以使用这些常量使代码更加明显和可读。

from rest_framework import status
from rest_framework.response import Response

def empty_view(self):
    content = {‘please move along‘: ‘nothing to see here‘}
    return Response(content, status=status.HTTP_404_NOT_FOUND)


# =========================================================
status下面列出了模块中包含的完整HTTP状态代码集。

该模块还包括一组辅助函数,用于测试状态代码是否在给定范围内。

from rest_framework import status
from rest_framework.test import APITestCase

class ExampleTestCase(APITestCase):
    def test_url_root(self):
        url = reverse(‘index‘)
        response = self.client.get(url)
        self.assertTrue(status.is_success(response.status_code))
有关正确使用HTTP状态代码的详细信息,请参阅RFC 2616 和RFC 6585。
# =========================================================
信息 - 1xx
此类状态代码表示临时响应。默认情况下,REST框架中没有使用1xx状态代码。

HTTP_100_CONTINUE
HTTP_101_SWITCHING_PROTOCOLS

# =========================================================
成功 - 2xx
此类状态代码表示已成功接收,理解和接受客户端的请求。

HTTP_200_OK
HTTP_201_CREATED
HTTP_202_ACCEPTED
HTTP_203_NON_AUTHORITATIVE_INFORMATION
HTTP_204_NO_CONTENT
HTTP_205_RESET_CONTENT
HTTP_206_PARTIAL_CONTENT
HTTP_207_MULTI_STATUS

# =========================================================
重定向 - 3xx
此类状态代码指示用户代理需要采取进一步操作才能完成请求。

HTTP_300_MULTIPLE_CHOICES
HTTP_301_MOVED_PERMANENTLY
HTTP_302_FOUND
HTTP_303_SEE_OTHER
HTTP_304_NOT_MODIFIED
HTTP_305_USE_PROXY
HTTP_306_RESERVED
HTTP_307_TEMPORARY_REDIRECT

# =========================================================
客户端错误 - 4xx
4xx类状态代码适用于客户端似乎有错误的情况。除了在响应HEAD请求时,服务器应该包括一个实体,其中包含错误情况的解释,以及它是暂时的还是永久的。

HTTP_400_BAD_REQUEST
HTTP_401_UNAUTHORIZED
HTTP_402_PAYMENT_REQUIRED
HTTP_403_FORBIDDEN
HTTP_404_NOT_FOUND
HTTP_405_METHOD_NOT_ALLOWED
HTTP_406_NOT_ACCEPTABLE
HTTP_407_PROXY_AUTHENTICATION_REQUIRED
HTTP_408_REQUEST_TIMEOUT
HTTP_409_CONFLICT
HTTP_410_GONE
HTTP_411_LENGTH_REQUIRED
HTTP_412_PRECONDITION_FAILED
HTTP_413_REQUEST_ENTITY_TOO_LARGE
HTTP_414_REQUEST_URI_TOO_LONG
HTTP_415_UNSUPPORTED_MEDIA_TYPE
HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE
HTTP_417_EXPECTATION_FAILED
HTTP_422_UNPROCESSABLE_ENTITY
HTTP_423_LOCKED
HTTP_424_FAILED_DEPENDENCY
HTTP_428_PRECONDITION_REQUIRED
HTTP_429_TOO_MANY_REQUESTS
HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE
HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS

# =========================================================
服务器错误 - 5xx
以数字“5”开头的响应状态代码表示服务器知道它已经错误或无法执行请求的情况。除了在响应HEAD请求时,服务器应该包括一个实体,其中包含错误情况的解释,以及它是暂时的还是永久的。

HTTP_500_INTERNAL_SERVER_ERROR
HTTP_501_NOT_IMPLEMENTED
HTTP_502_BAD_GATEWAY
HTTP_503_SERVICE_UNAVAILABLE
HTTP_504_GATEWAY_TIMEOUT
HTTP_505_HTTP_VERSION_NOT_SUPPORTED
HTTP_507_INSUFFICIENT_STORAGE
HTTP_511_NETWORK_AUTHENTICATION_REQUIRED

# =========================================================
助手功能
以下辅助函数可用于标识响应代码的类别。

is_informational()  # 1xx
is_success()        # 2xx
is_redirect()       # 3xx
is_client_error()   # 4xx
is_server_error()   # 5xx

8. 错误处理

状态码是 4xx 时, 应返回错误信息, error 当作 key


{
    error: ‘Invalid API key‘
}

9. 返回结果

针对不同操作, 服务器向用户返回的结果应该符合以下规范:


GET /collection: 返回资源对象的列表 (数组)
GET /collection/resource: 返回单个资源对象
POST /collection: 返回新生成的资源对象
PUT /collection/resource:  返回完整的资源对象
PATCH /collection/resource: 返回完整的资源对象
DELETE /collection/resource: 返回一个空文档

Restful API 的设计规范–进阶篇 原文链接

本文总结了 RESTful API 设计相关的一些原则,只覆盖了常见的场景。有些规则只是针对自己项目而言,并非其他做法都是错误的。

1. URI

URI 表示资源,资源一般对应服务器端领域模型中的实体类。 URI规范

  • 不用大写;
  • 用中杠-而不用下杠_;
  • 参数列表要encode;
  • URI中的名词表示资源集合,使用复数形式;

资源集合与单个资源 资源集合:


    /zoos //所有动物园
    /zoos/1/animals //id为1的动物园内的所有动物

单个资源:


    /zoos/1 //id为1的动物园
    /zoos/1;2;3 //id为1,2,3的动物园

避免层级过深的URI /在URI中表示层级,用于按实体关联关系进行对象导航,一般跟进id导航; 过深的导航容易导致url膨胀,不易维护,如 GET /zoos/1/areas/3/animals/4,尽量使用查询参数代替路径中的实体导航,如GET /animals?zoo=1&area=3;

对Composite资源的访问 服务器端的组合实体必须在uri中通过父实体的id导航访问。

组合实体不是first-class的实体,它的生命周期完全依赖父实体,无法独立存在,在实现上通常是对数据库表中某些列的抽象,不直接对应表,也无id。一个常见的例子是 User — Address,Address是对User表中zipCode/country/city三个字段的简单抽象,无法独立于User存在。必须通过User索引到Address:GET /user/1/addresses


2. Request

HTTP方法 通过标准HTTP方法对资源CRUD: GET: 查询


    GET /zoos
    GET /zoos/1
    GET /zoos/1/employees

POST: 创建单个资源。POST一般向“资源集合”型URI发起; ··· javaascipt


POST /animals //新增动物
POST /zoos/1/employees //id为1的动物园的所有员工

PUT:更新单个资源(全量),客户端提供完整的更新后的资源。与之对应的是 PATCH,PATCH 负责部分更新,客户端提供要更新的那些字段。PUT/PATCH一般向“单个资源”型uri发起


    PUT /animals/1
    PUT /zoos/1

DELETE:删除


    DELETE /zoos/1/employees/2
    DELETE /zoos/1/employees/2;4;5
    DELETE /zoos/1/animals  //删除id为1的动物园内的所有动物

HEAD / OPTION 用的不多,就不多解释了。

安全性与幂等性 安全性:不会改变资源状态,可以理解为只读的; 幂等性:执行1次和执行N次,对资源状态改变的效果是等价的。 

安全性和幂等性均不保证反复请求能拿到相同的response。以 DELETE 为例,第一次DELETE返回200表示删除成功,第二次返回404提示资源不存在,这是允许的。

复杂查询 查询可以捎带以下参数: 

Bookmarker 经常使用的、复杂的查询标签化,降低维护成本。 如:


GET /trades?status=closed&sort=created,desc

快捷方式:


    GET /trades#recently-closed
    // 或者
    GET /trades/recently-closed

Format 只用以下常见的3种body format:

  1. Content-Type: application/json

    POST /v1/animal HTTP/1.1
    Host: api.example.org
    Accept: application/json
    Content-Type: application/json
    Content-Length: 24

    {   
      "name": "Gir",
      "animalType": "12"
    }
  1. Content-Type: application/x-www-form-urlencoded (浏览器POST表单用的格式)

    POST /login HTTP/1.1
    Host: example.com
    Content-Length: 31
    Accept: text/html
    Content-Type: application/x-www-form-urlencoded
    
    username=root&password=Zion0101
  1. Content-Type: multipart/form-data; boundary=—-RANDOM_jDMUxq4Ot5 (表单有文件上传时的格式)

Content Negotiation 资源可以有多种表示方式,如json、xml、pdf、excel等等,客户端可以指定自己期望的格式,通常有两种方式:

  1. http header Accept

Accept:application/xml;q=0.6,application/atom+xml;q=1.0

q为各项格式的偏好程度

  1. url中加文件后缀:/zoo/1.json

3. Response

  1. 不要包装

    response 的 body 直接就是数据,不要做多余的包装。错误示例:


    {
        "success":true,
        "data":{"id":1,"name":"xiaotuan"},
    }
  1. 各HTTP方法成功处理后的数据格式: 
  2. json格式的约定: 时间用长整形(毫秒数),客户端自己按需解析(moment.js) 不传null字段

分页response


    {
        "paging":{"limit":10,"offset":0,"total":729},
        "data":[{},{},{}...]
    }

4. 错误处理

  1. 不要发生了错误但给2xx响应,客户端可能会缓存成功的http请求;
  2. 正确设置http状态码,不要自定义;
  3. Response body 提供 1) 错误的代码(日志/问题追查);2) 错误的描述文本(展示给用户)。

对第三点的实现稍微多说一点: Java 服务器端一般用异常表示 RESTful API 的错误。API 可能抛出两类异常:业务异常和非业务异常。业务异常由自己的业务代码抛出,表示一个用例的前置条件不满足、业务规则冲突等,比如参数校验不通过、权限校验失败。非业务类异常表示不在预期内的问题,通常由类库、框架抛出,或由于自己的代码逻辑错误导致,比如数据库连接失败、空指针异常、除0错误等等。 业务类异常必须提供2种信息:

  1. 如果抛出该类异常,HTTP 响应状态码应该设成什么;
  2. 异常的文本描述;

在Controller层使用统一的异常拦截器:

  1. 设置 HTTP 响应状态码:对业务类异常,用它指定的 HTTP code;对非业务类异常,统一500;
  2. Response Body 的错误码:异常类名
  3. Response Body 的错误描述:对业务类异常,用它指定的错误文本;对非业务类异常,线上可以统一文案如“服务器端错误,请稍后再试”,开发或测试环境中用异常的 stacktrace,服务器端提供该行为的开关。

常用的http状态码及使用场景:


5. 服务型资源

除了资源简单的CRUD,服务器端经常还会提供其他服务,这些服务无法直接用上面提到的URI映射。如:

  1. 按关键字搜索;
  2. 计算地球上两点间的距离;
  3. 批量向用户推送消息;

可以把这些服务看成资源,计算的结果是资源的presentation,按服务属性选择合适的HTTP方法。 例如:


    GET /search?q=filter?category=file  搜索
    GET /distance-calc?lats=47.480&lngs=-122.389&late=37.108&lnge=-122.448
    POST /batch-publish-msg
    [{"from":0,"to":1,"text":"abc"},{},{}...]

6. 异步任务

对耗时的异步任务,服务器端接受客户端传递的参数后,应返回创建成功的任务资源,其中包含了任务的执行状态。客户端可以轮训该任务获得最新的执行进度。


    // 提交任务:
    POST /batch-publish-msg
    [{"from":0,"to":1,"text":"abc"},{},{}...]
    
    // 返回:
    {"taskId":3,"createBy":"Anonymous","status":"running"}
    
    GET /task/3
    {"taskId":3,"createBy":"Anonymous","status":"success"}

如果任务的执行状态包括较多信息,可以把“执行状态”抽象成组合资源,客户端查询该状态资源了解任务的执行情况。


    提交任务:
    POST /batch-publish-msg
    [{"from":0,"to":1,"text":"abc"},{},{}...]
    
    返回:
    {"taskId":3,"createBy":"Anonymous"}
    
    GET /task/3/status
    {"progress":"50%","total":18,"success":8,"fail":1}

7. API演进

版本 常见的三种方式:

  1. 在uri中放版本信息:GET /v1/users/1
  2. Accept Header:Accept: application/json+v1
  3. 自定义 Header:X-Api-Version: 1

用第一种,虽然没有那么优雅,但最明显最方便。

URI失效 随着系统发展,总有一些API失效或者迁移,对失效的API,返回404 not found 或 410 gone;对迁移的API,返回 301 重定向。

原文地址:https://www.cnblogs.com/amou/p/9625368.html

时间: 2024-10-29 02:41:53

RESTful API规范的相关文章

RESTful API 规范

首先 RESTful 是一种软件架构风格或者说是一种设计风格,并不是标准,它只是提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件. 一.协议 在 url 接口中推荐使用 Https 协议,让网络接口更加安全.(简单讲是 Http 的安全版.即 Http 下加入SSL层,Https 的安全基础是 SSL,因此加密的详细内容就需要SSL) 二.接口 在 url 中可以体现这是个 API 接口. https://127.0.0.1:8000/api/ 三.版本 在 url 中可以体现版

Elasticsearch RESTful API请求详解

可以使用行命令 curl 通过9200端口与 Elasticsearch 的 RESTful API 进行通信.   Elasticsearch RESTful API规范 例如,计算集群中文件的数量,我们就可以使用:       <1>     <2>                   <3>    <4> curl -XGET 'http://localhost:9200/_count?pretty' -d ' {  <5>     &qu

后端api规范说明文档

我们此次后端api的实现主要是按照RESTful api规范来设计的,就是符合REST架构下设计api的规范.简单的来说REST结构就是:利用URL定位资源,用HTTP动词(GET,POST,PUT,DELETE)来描述相应操作. RESTful api主要的意义在于它可以让在不同形式的前端所接受到的用户请求能够统一的发送到一个后台并返回不同的前端.RESTful api是由后端SERVER实现并提供给前端来调用的一个接口.前端调用API来向后台发起HTTP请求,后台响应请求并将处理结构反馈给前

RestFul Api 定义流程规范

(1)整理项目需求,编写Api需求文档,包括Api返回结果,查询参数等等. (2)定义RestFul Api接口. (3)测试RestFul Api接口. (4)编写Api说明文档,包括Api的名称,路径,Http方法,请求参数,功能模板,返回结果等等,方便各模块研发人员和测试人员使用. (5)测试人员测试Api,主要测试系统性能,还有一些特出场景测试,例如多线程,并发操作.编写Api测试报告 (6)Api接口调用,项目研发阶段. 备注:上述5和6可以同时进行,互不影响.主要产生三个Api文档:

微服务架构实战:Swagger规范RESTful API

转载本文需注明出处:EAII企业架构创新研究院,违者必究.如需加入微信群参与微课堂.架构设计与讨论直播请直接回复公众号:"EAII企业架构创新研究院".(微信号:eaworld)   导读:本文是EAII微服务系列文章之一.随着微服务架构的流行,REST风格也是大势所趋.那么,什么是REST?如何规范我们的RESTFUL API 文档?本文中,作者主要基于以上两个话题进行讨论并探讨在数字化企业云平台实践中如何规范RESTful文档. REST的引入 随着微服务架构的广泛流行,REST风

Restful API应遵循哪些规范?Python进阶

Restful API是目前比较成熟的一套互联网应用程序的API设计理念,Rest是一组架构约束条件和原则,如何Rest约束条件和原则的架构,我们就称为Restful架构,Restful架构具有结构清晰.符合标准.易于理解以及扩展方便等特点,受到越来越多网站的采用! Restful API接口规范包括以下部分: 一.协议 API与用户的通信协议,总是使用HTTPs协议. 二.域名 应该尽量将API部署在专用域名之下,如https://api.oldboyedu.com;如果确定API很简单,不会

RESTful API设计原则与规范

一.背景与基础概念 2 二.RESTful API应遵循的原则 3 1.协议(Protocol) 3 2.域名(ROOT URL) 3 3.版本(Versioning) 3 4.路径(Endpoints) 3 5.HTTP动词(HTTP Verbs) 4 6.过滤信息(Filtering) 5 7.状态码(Status Codes) 5 8.错误处理(Error handling) 6 9.返回结果(Response) 6 10.使用HATEOAS的Hypermedia API 6 11.认证(

转:RESTful API接口设计标准及规范

引自:RESTful API接口设计标准及规范 RESTful发展背景及简介网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机.平板.桌面电脑.其他专用设备…).因此,必须有一种统一的机制,方便不同的前端设备与后端进行通信.这导致API构架的流行,甚至出现"APIFirst"的设计思想.RESTful API是目前比较成熟的一套互联网应用程序的API设计理论. REST(Representational State Transfer)表述性状态转换,RES

利用 Django REST framework 编写 RESTful API

利用 Django REST framework 编写 RESTful API Updateat 2015/12/3: 增加 filter 最近在玩 Django,不得不说 rest_framework 真乃一大神器,可以轻易的甚至自动化的搞定很多事情,比如: 自动生成符合 RESTful 规范的 API 支持 OPTION.HEAD.POST.GET.PATCH.PUT.DELETE 根据 Content-Type 来动态的返回数据类型(如 text.json) 生成 browserable