RestFul的认识

前言

在这里插入图片描述

RESTful 是 Representational State Transfer 的缩写,是一种软件架构风格,用于在网络上构建和整合应用程序。它基于 HTTP 协议,并定义了一组约束和规范,用于规范客户端和服务器之间的通信。

RESTful API 是遵循 REST 架构规范的 API,它允许客户端以标准化的方式与服务器进行交互。RESTful API 通常用于构建 Web 服务,并已被广泛应用于各种领域,包括电子商务、社交媒体、物联网等。

Rest API设计风格原则

1.使用名词而不是动词

  • 不要使用:
    如:
    /getAllUsers get /users get /users/002
    /createNewUser post /users
    /deleteAllUser delete /users/001

2.Get方法和查询参数不应该涉及状态改变

  • 使用PUT, POST 和DELETE 方法 而不是 GET 方法来改变状态,不要使用GET 进行状态改变。

3.使用复数名词

  • 不要混淆名词单数和复数,为了保持简单,只对所有资源使用复数。
    如:
    /cars 而不是 /car
    /users 而不是 /user
    /products 而不是 /product
    /settings 而不是 /setting
    /orders 而不是 /order

4. 使用子资源表达关系

  • 如果一个资源与另外一个资源有关系,使用子资源:
    如:
    GET /cars/711/drivers/ 返回 car 711的所有司机
    GET /cars/711/drivers/4 返回 car 711的4号司机
    GET /users/11/pets 返回 user 11的所有宠物
    GET /users/11/pets/2 返回 user 11的2号宠物

5.使用Http头声明序列化格式

  • 在客户端和服务端,双方都要知道通讯的格式,格式在HTTP-Header中指定
    如:
    Content-Type 定义请求格式
    Accept 定义系列可接受的响应格式

6.为集合提供过滤 排序 选择和分页等功能

  • Filtering过滤:使用唯一的查询参数进行
    GET /cars?color=red 返回红色的cars
    GET /cars?seats<=2 返回小于两座位的cars集合

  • Sorting排序:允许针对多个字段排序
    GET /cars?sort=-manufactorer,+model
    这是返回根据生产者降序和模型升序排列的car集合

  • Field selection
    移动端能够显示其中一些字段,它们其实不需要一个资源的所有字段,给API消费者一个选择字段的能力,这会降低网络流量,提高API可用性。
    GET /cars?fields=manufacturer,model,id,color

  • Paging分页
    使用 limit 和offset.实现分页,缺省limit=20 和offset=0;
    GET /cars?offset=10&limit=5
    为了将总数发给客户端,使用订制的HTTP头: X-Total-Count.
    链接到下一页或上一页可以在HTTP头的link规定,遵循Link规定:
    Link: https://blog.mwaysolutions.com/sample/api/v1/cars?offset=15&limit=5; rel=“next”,https://blog.mwaysolutions.com/sample/api/v1/cars?offset=50&limit=3; rel=“last”,https://blog.mwaysolutions.com/sample/api/v1/cars?offset=0&limit=5; rel=“first”,https://blog.mwaysolutions.com/sample/api/v1/cars?offset=5&limit=5; rel=“prev”,

7.版本化你的API 支付宝 v1 v2 v3

  • 使得API版本变得强制性,不要发布无版本的API,使用简单数字,避免小数点如2.5.
    一般在Url后面使用?v
    /blog/api/v1

8. 使用Http状态码处理错误

  • 如果你的API没有错误处理是很难的,只是返回500和出错堆栈不一定有用
  • Http状态码提供70个出错,我们只要使用10个左右:
    200 – OK – 一切正常
    201 – OK – 新的资源已经成功创建
    204 – OK – 资源已经成功删除
    304 – Not Modified – 客户端使用缓存数据
    400 – Bad Request – 请求无效,需要附加细节解释如 “JSON无效”
    401 – Unauthorized – 请求需要用户验证
    403 – Forbidden – 服务器已经理解了请求,但是拒绝服务或这种请求的访问是不允许的。
    404 – Not found – 没有发现该资源
    422 – Unprocessable Entity – 只有服务器不能处理实体时使用,比如图像不能被格式化,或者重要字段丢失。
    500 – Internal Server Error – API开发者应该避免这种错误。
    使用详细的错误包装错误: 状态码 数据 header头信息
    {
    “errors”: [
    {
    “userMessage”: “Sorry, the requested resource does not exist”,
    “internalMessage”: “No car found in the database”,
    “code”: 34,
    “more info”: “http://dev.mwaysolutions.com/blog/api/v1/errors/12345”
    }
    ]
    }

Rest API案例

没有使用RestFul的规范之前的设计

@Controller
@RequestMapping("user")
public class DemoController {private static final Logger log = LoggerFactory.getLogger(DemoController.class);//查询一个@RequestMapping("findUserById")public String findUserById(Integer id){log.info("查询用户id为:{}",id);//存储到作用域return "showOne";}//查询所有@RequestMapping("findAll")public String findAll(){log.info("查询所有");List<User>  userList =new ArrayList<User>();userList.add(new User(21,"xiaochen",2300,new Date()));//存储到作用域return "showAll";}//保存@RequestMapping("saveUser")public String save(User user){log.info("user: {}",user);return "redirect:/user/findAll";}//修改@RequestMapping("updateUser")public String update(User user){log.info("user: {}",user);return "redirect:/user/findAll";}@RequestMapping("deleteUser")public String delete(User user){log.info("user: {}",user);return "redirect:/user/findAll";}}

这里我们就完全没有按照我们前面所说的RestFul的架构去规范我们的API,下面我们将采用RestFul的设计去规范。

使用了RestFul的设计

@RestController
@RequestMapping("/v1/users") //符合使用复数名词
public class UserController {private static final Logger log = LoggerFactory.getLogger(UserController.class);// ResponeEntity: springmvc 封装一个专用于restful 响应类   这个类在响应时可以提供响应的状态码,同时还可以自定义响应头信息// HttpStatus:   springmvc 封住一个枚举类型类 这个类中都是网络中状态码/*** 查询某个用户详细* @param id* @return*///@RequestMapping(value = "/{id}",method = RequestMethod.GET)@GetMapping("/{id}")  //@RequestMapping:子类注解 使用GETMapping代表只能使用GET方式访问到当前请求//注解: PathVariable:代表在路径中获取请求参数//@ResponseBody //将控制器方法返回值转为jsonpublic ResponseEntity<User> user(@PathVariable("id") Integer id){log.info("本次id: {}",id);User user = null;try {user = new User(id, "小陈", 2300.23, new Date());} catch (Exception e) {e.printStackTrace();return new ResponseEntity<User>(user,HttpStatus.INTERNAL_SERVER_ERROR);}return new ResponseEntity<>(user,HttpStatus.OK);}/*** 用户列表* @return*/@GetMapping//@ResponseBodypublic ResponseEntity<List<User>> users(){ArrayList<User> users = new ArrayList<>();users.add(new User(21,"小王",2300.23,new Date()));users.add(new User(24,"小金豆",3400.23,new Date()));return  new ResponseEntity<>(users,HttpStatus.OK);}/*** 添加用户*/@PostMapping//@ResponseBody  //@ResponseBody 将方法返回值转为json格式数据 并响应请求   @RequestBody: 接收请求json格式数据 将json格式数据转为对象public ResponseEntity<Void> save(@RequestBody  User user){log.info("name:{} salary:{} bir:{}",user.getName(),user.getSalary(),user.getBir());//调用业务方法return new ResponseEntity<>(HttpStatus.NO_CONTENT);//没有内容}/*** 更新用户* @param user*/@PutMapping("/{id}")//@ResponseBodypublic ResponseEntity<Void> update(@PathVariable("id") Integer id,@RequestBody  User user){log.info("id:{} ",id);log.info("name:{} salary:{} bir:{}",user.getName(),user.getSalary(),user.getBir());//调用业务方法return new ResponseEntity<>(HttpStatus.NO_CONTENT);//没有内容}/*** 删除用户信息* @param id*/@DeleteMapping("/{id}")//@ResponseBodypublic ResponseEntity<Void> delete(@PathVariable("id") Integer id){log.info("本次id: {}",id);return new ResponseEntity<>(HttpStatus.NO_CONTENT);//没有内容}/*** 获取这个人所有宠物*/@GetMapping("/{id}/pets")public ResponseEntity<List<Pet>> pets(@PathVariable("id") Integer id){log.info("查询那个人id: {}",id);List<Pet> pets = Arrays.asList(new Pet(21, "小红帽", 23), new Pet(22, "小猪", 22));return new ResponseEntity<>(pets, HttpStatus.OK);}/*** 获取这个人某个宠物*/@GetMapping("/{id}/pets/{pid}")public ResponseEntity<Pet> pet(@PathVariable("id") Integer id,@PathVariable("pid") Integer petId){log.info("查询那个人id: {}",id);Pet pet = new Pet(21, "小红帽", 23);return new ResponseEntity<>(pet, HttpStatus.OK);}}

上述方法就

代码示例的设计特点总结

  1. 使用了 @RestController 注解
    @RestController 注解表示该类是一个 RESTful 控制器,它可以将方法返回值自动转换为 JSON 格式数据并响应请求。

  2. 使用了标准的 HTTP 方法
    @GetMapping:用于处理 GET 请求
    @PostMapping:用于处理 POST 请求
    @PutMapping:用于处理 PUT 请求
    @DeleteMapping:用于处理 DELETE 请求

  3. 使用了 @PathVariable 注解
    @PathVariable 注解用于获取路径中的参数。

  4. 使用了 @RequestBody 注解
    @RequestBody 注解用于接收请求中的 JSON 格式数据并将其转换为对象。

  5. 使用了 ResponseEntity 类
    ResponseEntity 类用于封装响应数据,包括响应状态码和响应体。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【每日一题】牛客网——链表分割

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ &#x1f64f;小杨水平有…

2024-02-08 Unity 编辑器开发之编辑器拓展1 —— 自定义菜单栏

文章目录 1 特殊文件夹 Editor2 在 Unity 菜单栏中添加自定义页签3 在 Hierarchy 窗口中添加自定义页签4 在 Project 窗口中添加自定义页签5 在菜单栏的 Component 菜单添加脚本6 在 Inspector 为脚本右键添加菜单7 加入快捷键8 小结 1 特殊文件夹 Editor ​ Editor 文件夹是 …

IT行业含金量高的证书-软考

软考全称计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试&#xff0c;软考既是职业资格考试&#xff0c;又是职称资格考试。2021年12月2号发布新版的国家职业资格目录&#xff0c;软考是在计算机技术领域中的唯一的国家职业资格。 一、好处 软考是一个神奇又特…

最全面的Docker安装部署,配置镜像加速

安装Docker 卸载旧版 首先如果系统中已经存在旧的Docker&#xff0c;则先卸载&#xff1a; yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine 配置Docker的yum仓库 首先…

每日一个shell脚本之计算器

每日一个shell脚本之计算器 源码 read -p "请输入需要计算的数字公式:" numnumsecho "$num" | bc -lecho "${num}${nums} "使用 复制粘贴进一个.sh结尾的文件,sh 文件名.sh即可运行

Linux第47步_安装支持linux的第三方库和mkimage工具

安装支持linux的第三方库和mkimage工具&#xff0c;做好移植前的准备工作。 编译linux内核之前&#xff0c;需要先在 ubuntu上安装“lzop库”和“libssl-dev库”&#xff0c;否则内核编译会失败。 mkimage工具会在zImage镜像文件的前面添加0x40个字节的头部信息,就可以得到uI…

Rust - 元组结构体和单元结构体

元组结构体 除了定义常规的结构体之外&#xff0c;也可以定义与元组类似的结构体&#xff0c;称为 元组结构体&#xff08;tuple structs&#xff09;&#xff0c;元组结构体的主要特征是没有字段名&#xff0c;只有字段类型&#xff0c;当我们想给整个元组取一个名字&#xf…

锐捷(二十一)全局地址绑定

vlan划分和vlanif接口配置略&#xff0c;注意vlanif接口里要no shutdown配置如下&#xff1a; Address-bind 192.168.1.1 AAAA.BBBB.CCCCAddress-bind uplink g0/0Address-bind binding-filter loggingAddress-bind install 此时&#xff0c;IP为192.168.1.1 mac地址为AAAA.B…

20240212请问如何将B站下载的软字幕转换成为SRT格式?

20240212请问如何将B站下载的软字幕转换成为SRT格式&#xff1f; 2024/2/12 12:47 百度搜索&#xff1a;字幕 json 转 srt json srt https://blog.csdn.net/a_wh_white/article/details/120687363?share_token2640663e-f468-4737-9b55-73c808f5dcf0 https://blog.csdn.net/a_w…

Microsoft Excel 加载数据分析工具

Microsoft Excel 加载数据分析工具 1. 打开 Excel&#xff0c;文件 -> 选项2. 加载项 -> 转到…3. 分析工具库、分析工具库 - VBA4. 打开 Excel&#xff0c;数据 -> 数据分析References 1. 打开 Excel&#xff0c;文件 -> 选项 2. 加载项 -> 转到… ​​​ 3…

蓝桥杯-X图形

问题描述 给定一个字母矩阵。一个 X 图形由中心点和由中心点向四个 45度斜线方向引出的直线段组成&#xff0c;四条线段的长度相同&#xff0c;而且四条线段上的字母和中心点的字母相同。 一个 X 图形可以使用三个整数 r,c,L 来描述&#xff0c;其中 r,c 表示中心点位于第 r 行…

Linux network namespace 访问外网以及多命名空间通信(经典容器组网 veth pair + bridge 模式认知)

写在前面 整理K8s网络相关笔记博文内容涉及 Linux network namespace 访问外网方案 Demo实际上也就是 经典容器组网 veth pair bridge 模式理解不足小伙伴帮忙指正 不必太纠结于当下&#xff0c;也不必太忧虑未来&#xff0c;当你经历过一些事情的时候&#xff0c;眼前的风景已…

【后端高频面试题--Nginx篇】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;后端高频面试题 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 后端高频面试题--Nginx篇 什么是Nginx&#xff1f;为什么要用Nginx&#xff1f;为什么Nginx性能…

基于Locust实现MQTT协议服务的压测脚本

一、背景简介 业务背景大概介绍一下&#xff0c;就是按照国标规定&#xff0c;车辆需要上传一些指定的数据到ZF的指定平台&#xff0c;同时车辆也会把数据传到企业云端服务上&#xff0c;于是乎就产生了一些性能需求。 目前我们只是先简单的进行了一个性能场景的测试&#xf…

没更新的日子也在努力呀,布局2024!

文章目录 ⭐ 没更新的日子也在努力呀⭐ 近期的一个状态 - 已圆满⭐ 又到了2024的许愿时间了⭐ 开发者要如何去 "创富" ⭐ 没更新的日子也在努力呀 感觉很久没有更新视频了&#xff0c;好吧&#xff0c;其实真的很久没有更新短视频了。最近的一两个月真的太忙了&#…

MATLAB Coder从入门到放弃

一、MATLAB Coder入门 1 MATLAB Coder是什么 从 MATLAB 代码生成 C 和 C 代码 MATLAB Coder™ 可从 MATLAB 代码生成适用于各种硬件平台&#xff08;从桌面计算机系统到嵌入式硬件&#xff09;的 C 和 C 代码。它支持大多数 MATLAB 语言和广泛的工具箱。您可以将生成的代码作…

SHA-512在Go中的实战应用: 性能优化和安全最佳实践

SHA-512在Go中的实战应用: 性能优化和安全最佳实践 简介深入理解SHA-512算法SHA-512的工作原理安全性分析SHA-512与SHA-256的比较结论 实际案例分析数据完整性验证用户密码存储数字签名总结 性能优化技巧1. 利用并发处理2. 避免不必要的内存分配3. 适当的数据块大小总结 与其他…

【玩转408数据结构】线性表——线性表的顺序表示(顺序表)

知识回顾 通过前文&#xff0c;我们了解到线性表是具有相同数据类型的有限个数据元素序列&#xff1b;并且&#xff0c;线性表只是一种逻辑结构&#xff0c;其不同存储形式所展现出的也略有不同&#xff0c;那么今天我们来了解一下线性表的顺序存储——顺序表。 顺序表的定义 …

上个月刚跟男朋友一起买了个三百万的房子,准备明年结婚,这个月他突然被裁了...

职场变动&#xff0c;尤其是裁员&#xff0c;已经成为我们无法忽视的现实。不管你是互联网大佬&#xff0c;还是刚入行的新人&#xff0c;这个问题都可能突如其来&#xff0c;影响到你的生活和计划。 想象一下&#xff0c;你和你的另一半刚刚为了将来的幸福生活&#xff0c;拼尽…

使用 Windows 11/10 上的最佳 PDF 转 Word 转换器释放 PDF 的潜力

毫无疑问&#xff0c;PDF 是最好的文档格式之一&#xff0c;但就像其他格式一样&#xff0c;有时它们确实会带来一些限制。例如&#xff0c;在某些情况下&#xff0c;您可能想要将 PDF 转换为 Word。在这种情况下&#xff0c;您始终可以借助 PDF 到 Word 转换器的帮助。 为了说…
最新文章