RESTful API 设计总结
RESTful API 设计总结
@(技术-架构)[API, 规范, 设计]
RESTful的接口设计风格应用的越来越广泛,包括Spring Cloud等微服务架构平台之间的调用都是以RESTful设计风格为主,但是很多程序猿依然是停留在表面的理解上,没有深刻的去理解使用RESTful风格规范,同时在设计RESTful接口的时候是有很多细节需要思考,以下就是个人对RESTful接口的深入理解以及总结。
1、协议&域名&版本
协议:API与用户的通信协议,总是使用HTTPS协议。
域名:可以部署专有域名或者是主域名下加入URL里面。
版本:应该将API的版本号放入URL。
2、CURD的请求设计
REST的关键原则把API分解成一种逻辑上的资源。这些资源可以通过有具体含义的HTTP方法(GET, POST, PUT, PATCH, DELETE)来进行修改。
GET /users - 获取user列表
GET /users/12 - 获取指定ID为12的user对象
POST /users - 创建一个新的user
PUT /users/12 - 更新id为12的user
PATCH /users/12 - 对id为12的user进行部分更新
DELETE /users/12 - 删除id为12的user
① 新增:新增对象一般用到的是POST方法。
POST /users - 创建一个新的user
POST /users?count=4 - 批量创建user对象
② 删除:DELETE作为删除的方法
DELETE /users/12 - 删除id为12的user
DELETE /users [134 , 232 , 223 , 442] - 批量删除id为134 , 232 , 223 , 442的user
③ 更新:PUT、PATCH都是作为更新的HTTP方法,PUT表示更新USER对象,PATCH是对对象部分更新
PUT /users/12 - 更新id为12的user
PUT /users - 批量更新user
PATCH /users/12 - 对id为12的user进行部分更新
PATCH /users - 批量对user进行部分更新
④ 查询:GET一般作为查询的HTTP方法,如何优雅的满足复杂的接口,不是一件很值得探讨的事情。查询单个对象
GET /users/12 - 获取指定ID为12的user对象
查询多个对象
GET /users - 获取user列表
条件过滤与分页查询
GET /users?page=3&page_count=30:指定第几页,以及每页的记录数。
GET /users?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。
GET /users?role_id=1:指定筛选条件
查询多个对象时,一般返回对象的列表,当分页查询需要返回查询的总的数据,应当在响应头部里面加入X-Total-Count的参数,同时在头部加入X-Page和X-Page-Size参数。
X-Total-Count:1023
X-Page:3
X-Page-Size:30
复杂的查询条件当我们使用高级搜索的时候,GET方法的参数长度是没法满足查询的需求,这时候我们可以用POST方法提交参数实体来实现需求。
POST /users/search?page=3&page_count=30
{name : admin ,
phone : 124 ,
sex : 1}
过滤返回对象属性
GET /users/12?fields=id,name,phone - 设置返回对象的属性
3、返回结果设计
针对不同操作,服务器向用户返回的结果应该符合以下规范。
GET /collection:返回资源对象的列表(数组)
GET /collection/resource:返回单个资源对象
POST /collection:返回新生成的资源对象
POST /collection:(批量新增)返回新生成的资源对象数量
PUT /collection/resource:返回完整的资源对象
PUT /collection:(批量更新)返回完整的资源对象数量
PATCH /collection/resource:返回完整的资源对象
PATCH /collection:(批量更新)返回完整的资源对象数量
DELETE /collection/resource:返回一个空文档
DELETE /collection:(批量删除)返回完整的资源对象数量
状态码
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"
}
4、Hypermedia API
RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。
比如,当用户向api.github.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",
"authorizations_url": "https://api.github.com/authorizations",
// ...
}
从上面可以看到,如果想获取当前用户的信息,应该去访问api.github.com/user,然后就得到了下面结果。
{
"message": "Requires authentication",
"documentation_url": "https://developer.github.com/v3"
}
上面代码表示,服务器给出了提示信息,以及文档的网址。
原文地址:https://segmentfault.com/a/1190000011338151
RESTful API 设计总结的更多相关文章
- 从英文变形规则计算到Restful Api设计
➠更多技术干货请戳:听云博客 一天在研究Restful API设计,命名的时候我总是很纠结,我相信大多数人也有这种感觉,不是说想不出来某个单词怎么写的问题,像我这种没事背单词背到13000词量的人也要 ...
- RESTful API 设计指南 (转)
RESTful API 设计指南 2016-02-23 ImportNew (点击上方公号,可快速关注) 作者:阮一峰 链接:http://www.ruanyifeng.com/blog/2014/0 ...
- RESTFul API设计指南及使用说明
RESTFul API设计指南及使用说明 一. 协议 API与用户的通信协议,使用HTTP协议. 二. 域名 应尽量将API部署在专用域名之下(http://api.example.com) 也可以将 ...
- RESTful API 设计指南,RESTful API 设计最佳实践
RESTful API 设计指南,RESTful API 设计最佳实践 网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机.平板.桌面电脑.其他专用设备......). ...
- RESTful API设计概要
一.简介 1. 什么是REST REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移. 它首次出现在2000年Roy Fiel ...
- Rest Framework简介 和 RESTful API 设计指南
使用Django Rest Framework之前我们要先知道,它是什么,能干什么用? Django Rest Framework 是一个强大且灵活的工具包,用以构建Web API 为什么要使用Res ...
- 我是如何根据豆瓣api来理解Restful API设计的
1.什么是REST REST全称是Representational State Transfer,表述状态转移的意思.它是在Roy Fielding博士论文首次提出.REST本身没有创造新的技术.组件 ...
- 微服务指南走北(三):Restful API 设计简述
API的定义取决于选择的IPC通信方式,假设是消息机制(如 AMQP 或者 STOMP).API则由消息频道(channel)和消息类型.假设是使用HTTP机制,则是基于请求/响应(调用http的ur ...
- RESTful API设计方法
1.如果已经开始逐步的接触到了RESTful API设计方法的朋友,首先要对HTTP/HTTPS有一个大致的了解,虽然本身和RESTful API没有什么关系.但是对于增加网站的安全性还是十分重要的, ...
- RESTful API设计原则与规范
RESTful API设计原则与规范 一.背景与基础概念 2 二.RESTful API应遵循的原则 3 1.协议(Protocol) 3 2.域名(ROOT URL) 3 3.版本(Versioni ...
随机推荐
- Maven Waring : GroupId is duplicate of parent groupId 和 Version is duplicate of parent version
问题描述: 新项目在创建的时候,因为用到了分模块的,所以导致子模块的pom文件,报了 如下警告: 解决办法: 直接 Window --> Preferences --> Maven -- ...
- [BZOJ4804]欧拉心算:线性筛+莫比乌斯反演
分析 关于这道题套路到不能再套路了没什么好说的,其实发这篇博客的目的只是为了贴一个线性筛的模板. 代码 #include <bits/stdc++.h> #define rin(i,a,b ...
- Linux宝塔面板FTP无法连接的解决办法,跳坑实例
宝塔面板的ftp无法使用解决 先检查这些内容 1.注意内网IP和外网IP 2.检查ftp服务是否启动 (面板首页即可看到) 3.检查防火墙20端口 ftp 21端口及被动端口39000 - 40000 ...
- 突破css选择器的局限,实现一个css地址选择器?
首先看一个效果,注意地址栏的变化 然后思考一下,用css如何实现? css选择器的局限 选择器是css中的一大特色,用于选择需要添加样式的元素. 选择器的种类有很多,比如 元素选择器 p {color ...
- jieba(结巴)常用方法
python jieba库的基本使用 第一步:先安装jieba库 输入命令:pip install jieba jieba库常用函数: jieba库分词的三种模式: 1.精准模式:把文本精准地分开 ...
- NLP大赛冠军总结:300万知乎多标签文本分类任务(附深度学习源码)
NLP大赛冠军总结:300万知乎多标签文本分类任务(附深度学习源码) 七月,酷暑难耐,认识的几位同学参加知乎看山杯,均取得不错的排名.当时天池AI医疗大赛初赛结束,官方正在为复赛进行平台调 ...
- pdf.js浏览中文pdf乱码的问题解决
由于项目中需要支持移动设备在线浏览pdf,苹果还好,天生支持,但是安卓中就不行了,需要第三方组件的支持. 这里就找到了pdf.js,由于pdf数据太多,开始的时候没法一一测试,所以随便测试打开了几篇没 ...
- python - 标准库:subprocess模块
subprocess的目的就是启动一个新的进程并且与之通信. subprocess模块中只定义了一个类: Popen. subprocess.Popen(args, bufsize=0, execut ...
- 2018 icpc 沈阳
https://codeforces.com/gym/101955 J 签到 #include<iostream> #include<cstring> #include< ...
- 服务器控件调用JS函数
是服务器端控件,不能在JS里直接调用,但可以在aspx.cs 里写方法可以调用JS函数,比如JS方法名称是check(), function check() { alert(document.ge ...