关于RESTful一些注意事项,接口开发规范

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。

最近在研究restful,公司开发要使用,所以自己就去网上找了好些资料,并整理了一套公司开发的接口规范。当然,我也只是刚刚入坑。还不是很全面。但是这就是一个过程。一点点,总会好起来的。以下是就是RESTful接口规范:

一、   URI

URI规范

1.不用大写;

2.用中杠 - 不用下杠 _ 

3.参数列表要encode

4.URI中的名词表示资源集合,使用复数形式。

5.RESTful架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词(特殊情况可以使用动词),而且所用的名词往往与数据库的表格名对应

 

资源集合 vs单个资源

URI表示资源的两种方式:资源集合、单个资源

资源集合:

       /zoos //所有动物园

       /zoos/1/animals //id1的动物园中的所有动物

单个资源:

       /zoos/1//id1的动物园

       /zoos/1;2;3//id123的动物园

 

避免层级过深的URI

url中表达层级,用于 按实体关联关系进行对象导航 ,一般根据id导航。

过深的导航容易导致url膨胀,不易维护,如 GET /zoos/1/areas/3/animals/4 ,尽量使用查询参数代替路径中的实体导航,如 GET/animals?zoo=1&area=3 

 

 

二、   版本

应该将API的版本号放入到URI

           https://api.example.com/v1/zoos

 

 

三、 Request

HTTP方法

通过标准HTTP方法对资源CRUD

GET:查询(从服务器取出资源一项或多项)

GET /zoos

GET /zoos/1

GET/zoos/1/employees

POST:创建单个新资源。 POST一般向资源集合uri发起

POST/animals  //新增动物

POST/zoos/1/employees //id1的动物园雇佣员工

PUT:更新单个资源(全量),客户端提供完整的更新后的资源。与之对应的是 PATCHPATCH负责部分更新,客户端提供要更新的那些字段。 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  //删除id1的动物园内的所有动物

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

HEAD:获取资源的元数据

OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的

PATCH:在服务器更新资源(客户端提供改变的属性)

 

安全性和幂等性

1.     安全性 :不会改变资源状态,可以理解为只读的;

2.     幂等性 :执行1次和执行N次,对资源状态改变的效果是等价的。

.

安全性

幂等性

GET

POST

×

×

PUT

×

DELETE

×

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

复杂查询

查询可以捎带以下参数:

.

示例

备注

过滤条件

?type=1&age=16

允许一定的uri冗余,如 /zoos/1  /zoos?id=1

排序

?sort=age&order=asc

指定返回结果按照哪个属性排序,以及排序顺序

投影

?whitelist=id,name,email

分页

? page=2&per_page=100

指定第几页,以及每页的记录数

Bookmarker

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

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

快捷方式:GET /trades#recently-closed或者GET /trades/recently-closed

状态码

    服务器向用户返回的状态码和提示信息,常见的有以下一些(方括号中是该状态码对应的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 - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。

状态码的完全列表参见这里

 

URI失效

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

 

四、Response

1.    不要包装:

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

{

   "success":true,

   "data":{"id":1,"name":"xiaotuan"},

}

2.    HTTP方法成功处理后的数据格式:

·

response 格式

GET

单个对象、集合

POST

新增成功的对象

PUT/PATCH

更新成功的对象

DELETE

 

五、错误处理

1.     不要发生了错误但给2xx响应,客户端可能会缓存成功的http请求;

2.     正确设置http状态码,不要自定义;

3.     Response body提供

:返回的信息中将error作为键名,出错信息作为键值即可

1)错误的代码(日志/问题追查);

2)错误的描述文本(展示给用户)。

 

对第三点的实现稍微多说一点:

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

业务类异常必须提供2种信息:

1.     如果抛出该类异常,HTTP响应状态码应该设成什么;

2.     异常的文本描述;

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

1.     设置 HTTP响应状态码:对业务类异常,用它指定的 HTTPcode;对非业务类异常,统一500

2.     Response Body的错误码:异常类名

3.     Response Body的错误描述:对业务类异常,用它指定的错误文本;对非业务类异常,线上可以统一文案如服务器端错误,请稍后再试,开发或测试环境中用异常的 stacktrace,服务器端提供该行为的开关。

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

状态码

使用场景

400 bad request

常用在参数校验

401 unauthorized

未经验证的用户,常见于未登录。如果经过验证后依然没权限,应该 403(即 authenticationauthorization的区别)。

403 forbidden

无权限

404 not found

资源不存在

500 internal server error

非业务类异常

503 service unavaliable

由容器抛出,自己的代码不要抛这个异常

 

六、其他

1API的身份认证应该使用OAuth2.0框架

2)服务器返回的数据格式,应该尽量使用JSON,避免使用XML

3)比较复杂的接口不能确定是使用POST还是PUT时,要看具体的业务层代码,看看接口产生的结果是否幂等,如果幂等用PUT,相反用POST

      如:接口接收到一资源,资源存在更新,不存在插入新数据,这个接口就要用PUT

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/450782.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【老杜】MySQL—day01

文章目录day01课堂笔记1、数据库概述及数据准备1.1、什么是数据库1.2、什么是数据库管理系统1.3、SQL概述1.4、安装MySQL数据库管理系统。1.4、MySQL数据库的完美卸载!1.5、MySQL的服务1.6、用命令来启动和关闭mysql服务1.7、登录mysql数据库2、MySQL常用命令&#…

【转载】DRuid 大数据分析之查询

转载自http://yangyangmyself.iteye.com/blog/23217591、Druid 查询概述上一节完成数据导入后,接下来讲讲Druid如何查询及统计分析导入的数据。Druid的查询是使用REST风格的HTTP请求查询服务节点(Broker、Historical、Realtime),这…

记录 Parameter with that position [1] did not exist; nested exception is java.lang.IllegalArgumentExce

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 报错如题: Parameter with that position [1] did not exist; nested exception is java.lang.IllegalArgumentException: Pa…

[转]简单的动态修改RDLC报表页边距和列宽的方法

本文转自:http://star704983.blog.163.com/blog/static/136661264201161604413204/ 1.修改页边距 XmlDocument XMLDoc new XmlDocument();XMLDoc.Load(System.Windows.Forms.Application.StartupPath "\Report_try-2.rdlc");XmlNamespaceManager xmn n…

函数式编程语言天生就慢吗?

摘要:近期,函数式编程得到了越来越多的关注,Lisp不仅重获青春还涌现出了一批新函数式编程语言。因此开发者们对函数式编程语言的运行快慢各抒己见,展开激烈讨论。本文将和大家一起讨论,函数式编程语言真的就慢吗&#…

【老杜】MySQL—day02

文章目录day02课堂笔记1、把查询结果去除重复记录【distinct】10、连接查询10.1、什么是连接查询?10.2、连接查询的分类?10.3、当两张表进行连接查询时,没有任何条件的限制会发生什么现象?10.4、怎么避免笛卡尔积现象?…

vue根据数组对象中某个唯一标识去重

由于在vue中,会自动在数组和对象中加入_obser__观察者模式的一些属性,所以直接用数组的filter去重(下面这种),indexOf不能准确识别 var arr [1, 2, 2, 3, 4, 5, 5, 6, 7, 7]; var arr2 arr.filter(function(x, index…

Springsecurity之AuthenticationProvider

2019独角兽企业重金招聘Python工程师标准>>> 注意:AuthenticationProvider与Authentication紧密联系,关于Authentication,看我的这篇博客。 先上一张图,如下图1 图1 AuthenticationProvider的类图 AuthenticationProvi…

Postman使用入门

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 Postman测试管理的单位是测试集(Collections),测试集内可以创建文件夹(Folder)和具体的请求(Requests…

编程需要知道多少数学知识?

摘要:许多人认为在开始学习编程之前必须对数学很在行或者数学分数很高。但一个人为了编程的话,需要学习多少数学呢? 实际上不需要很多 。这篇文章中我会深入探讨编程中所需要的数学知识。 下面是我在reddit的子论坛 r/learnprogramming 看到的…

HDU 6071 Lazy Running

链接HDU 6071 Lazy Running 给出四个点1,2,3,4,1和2,2和3,3和4,4和1之间有路相连,现在从2点出发,最后回到2点,要求路径大于等于\(K\),问路径长度最…

vue弹窗插件实战

vue做移动端经常碰到弹窗的需求, 这里写一个功能简单的vue弹窗 popup.vue <template><div class"popup-wrapper" v-show"visible" click"hide"><div class"popup-text">{{text}}</div></div> </temp…

【狂神说】Redis笔记

文章目录1、Nosql概述1.1 为什么要用Nosql1.2 什么是NoSQL1.3 阿里巴巴演进分析2、NoSQL的四大分类3、Redis入门3.1 概述3.2 Windows安装3.3 Linux安装3.4 测试性能3.5 基础的知识4、五大数据类型4.1 Redis-Key4.2 String&#xff08;字符串&#xff09;4.3 List&#xff08;列…

Postman用法说明

见&#xff1a;http://blog.csdn.net/flowerspring/article/details/52774399 Postman用法简介-Http请求模拟工具 在我们平时开发中&#xff0c;特别是需要与接口打交道时&#xff0c;无论是写接口还是用接口&#xff0c;拿到接口后肯定都得提前测试一下&#xff0c;这样的话就…

位、字,字节与KB的关系?

位&#xff1a;我们常说的bit&#xff0c;位就是传说中提到的计算机中的最小数据单位&#xff1a;说白了就是0或者1&#xff1b;计算机内存中的存储都是01这两个东西。 字节&#xff1a;英文单词&#xff1a;&#xff08;byte&#xff09;&#xff0c;byte是存储空间的基本计量…

C++ string 介绍

之所以抛弃char *的字符串而选用C标准程序库中的string类&#xff0c;是因为他和前者比较起来&#xff0c;不必担心内存是否足够、字符串长度等等&#xff0c;而且作为一个类出现&#xff0c;他集成的操作函数足以完成我们大多数情况下(甚至是100%)的需要。我们可以用 进行赋…

Linux核心总结

文章目录1.首先了解一下linux的目录结构2.linux的基本命令之使用命令开关机3.linux的基本命令之目录管理1.ls—列出目录命令2.cd—切换目录命令3.pwd—查看当前所在目录命令4.mkdir—创建文件夹命令5.rmdir—删除文件夹命令6.cp—复制文件命令7.rm—传说中的删库跑路命令8.mv—…

Java多线程系列---“JUC锁”01之 框架

本章&#xff0c;我们介绍锁的架构&#xff1b;后面的章节将会对它们逐个进行分析介绍。目录如下&#xff1a; 01. Java多线程系列--“JUC锁”01之 框架02. Java多线程系列--“JUC锁”02之 互斥锁ReentrantLock06. Java多线程系列--“JUC锁”03之 Condition条件07. Java多线程系…

IDEA配置jdk (SDK)

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 提前安装jdk&#xff0c;配置环境变量 一、配置jdk 1、依次点开File -->Project Structure&#xff0c;点击左侧标签页&#xff0c…