文章目录
前言
在前后端分离的应用模式里, 对于 API 的请求路径以及请求方式, 每个码农都有不同的风格, 造成了后期维护困难, 代码可读性差, 所以现在前后端分离项目, 约定俗成, 大家普遍采用 RESTful 风格来大统一, 网上专门讲解RESTful的视频教程很少,这是我认为讲的最好的视频,需要的朋友可以去看一下,网址:https://www.bilibili.com/video/BV1et411T7SS?p=1
一、RESTful风格是什么
一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
二、传统方式与RESTful风格对比分析
1.RESTful设计
一、资源查询路径设计
(1)传统方式
查询,GET------ http://127.0.0.1/item/queryItem.action?id=1
新增,POST ------http://127.0.0.1/item/saveItem.action
更新,POST------ http://127.0.0.1/item/updateItem.action
删除,GET或POST------http://127.0.0.1/item/deleteItem.action?id=1
(2)RESTful风格
查询,GET --------http://127.0.0.1/item/1
新增,POST -------http://127.0.0.1/item
更新,PUT --------http://127.0.0.1/item
删除,DELETE------http://127.0.0.1/item/1
(3)RESTful风格设计规则
1、设计资源的接口,uri选用的是名词,一般和数据库表名相同,并且使用复数
2、要求路径中使用的单词都是名词,最好不要出现动词
3、分页、排序等操作,不需要使用斜杠传参数,例如:例如:订单列表接口/boot/orders?page=1&sort=desc
@RestController
@RequestMapping("/restfulls")
public class Restfull {
//查询,GET
@GetMapping()
public String getEmployee(){
return "restfull查询成功";
}
// 新增,POST
@PostMapping()
public String getEmployee1(){
return "restfull新增成功";
}
//更新,PUT
@PutMapping()
public String getEmployee2(){
return "restfull更新成功";
}
// 删除,DELETE
@DeleteMapping()
public String getEmployee3(){
return "restfull删除成功";
}
}
补充:@RestController注解相当于下面两个注解的效果
@Controller
@ResponseBody
二、动作设计
(1)HTTP动作
GET ---------( SELECT) :从服务器取出资源(一项或多项)
POST ---------( CREATE) : 在服务器新建一个资源,即添加数据
PUT ----------( UPDATE) :在服务器更新资源(客户端提供改变后的完整资源),PUT更新整个对象
DELETE -------(DELETE) :从服务器删除资源
PATCH --------(UPDATE) : 在服务器更新资源(客户端提供改变的属性[补丁] ),PATCH更新个别属性
HEAD ----------获得一个资源的元数据.比如一个资源的hash值或者最修改日期:
OPTIONS -------获得客户端针对一个资源能多实施的操作: (获取该资源的api(能够对资源做什么操作的描述))
(2)动作示例
GET /zoos ---------------------列出所有动物园
POST /zoos --------------------新建一个动物园
GET /zoos/ID ------------------获取某个指定动物园的信息
PUT /zoos/ID ------------------更新某个指定动物园的信息(提供该动物园的全部信息)
PATCH /zoos/ID ----------------更新某个指定动物园的信息(提供该动物园的部分信息)
DELETE /zoos/ID ---------------删除某个动物园
GET /zoos/ID/animals ----------列出某个指定动物园的所有动物
GET /deparments/ID/employees---获取某个部门的所有员工
三、返回结果
(1)返回值类型(仅供参考)
GET /zoos ----------------------返回资源对象的列表(数组/集合)
GET /zoos/1 --------------------返回单个资源对象
POST /collection ---------------返回新生成的资源对象
PUT /collection/resource -------返回完整的资源对象
PATCH /collecion/resource ------返回完整的资源对象
DELETE /ollection/resource -----返回一个空文档,即不返回
(2)常见状态码
200 OK [GET]- 服务器成功返回用户请求的数据。
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-[*] :服务器发生错误,用户将无法判断发出的请求是否成功。
2.RESTful服务开发
一、增删改查案例
(1)查询所有员工
1、确定资源:emplayees
2、确定请求方式 GET
3、确定返回结果(类型、头信息、状态码) json 200
@GetMapping ( "employees" )
@ResponseBody
public List<Employee> list( ) [
ArrayList <Employee> list = new ArrayList<>() ;
list.add (new Employee( id: 1L, name: "aduin"});
list.add (new Employee( id: 2L, name: "小王"));
return list;
}
(2)根据id获取指定员工
1、确定资源:emplayees/{id}
2、确定请求方式 GET
3、确定返回结果(类型、头信息、状态码) json 201
@GetMapping ( "employees/{id}" )
@ResponseBody
public Employee getById(IntegerId id ) [
return new Employee(id,"admin");
}
(3)根据id删除指定员工
1、确定资源:emplayees/{id}
2、确定请求方式 DELETE
3、确定返回结果(类型、头信息、状态码) 空文档 204
@DeleteMapping ( "employees/{id}" )
@ResponseBody
public void deleteById(IntegerId id ) [
System.out.println("删除id为:"+id+"的员工");
}
(4)获取某个员工某个月的工资
1.确定资源/employees/{employeeId}/salaries/{month}
2.确定请求方式GET
3.确定返回结果(类型,头信息,状态码)薪资对象, content-type=application/json, 200
@GetMapping ( "employees/{employeeId}/salaries/{month}" )
@ResponseBody
public Salary getsalaryByEmployce (@PathVarlable Long employeeId, @PathVariable @DateTimeFormat(pattern = "yyyy-MM")Date month) {
return new salary( id: 1L, employeeId, BigDecimal.TEN,month) ;
}
@JsonFormat(pattern = "yyyy-MM",timezone = "GMT+8")
@DateTimeFormat:前台传日期参数到后台接收时候使用的注解
@JsonFormat:后台返回json数据给前台时使用的注解,中国在东八区,所以要+8
(5)给某个员工添加一条薪资记录
1.确定资源、/employees/{fempIoyeeId}/salaries
2.确定请求方式FOST
3.确定返回结果类型,头信息,状态码)
薪资对象,content-type-application/json, 201
@PostMapping ("employees/{fempIoyeeId}/salaries" )
@ResponseBody
public Salary save (Salary salary) {
return salary() ;
}
二、处理PUT或者PATCH请求方式的过滤器
<!-- 浏览器不支持put,delete等method,需要配置下面的过滤器才能转换对应的请求-->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
三、form表单put提交方式
<body>
<button id="delBtn">册除</ button>
<button id="editBtn">修改</button>
<form aotion="/eauployes/1" method="post">
//需要增加这个隐藏域,才能转为put,name的值必须为"_method"
<input type ="hidden" name="_method" value="put" />
<input name="name"/>
<button type="submit" >提交</ button>
</form>
</body>
四、在Aajx中发送post请求后,带_method参数,将其修改为PUT,或者DELETE请求
$.ajax({
url:"${APP_PATH}/RecordController/record",
type:"POST",
data:{id :id ,
_method:"PUT"},
success:function(result){
alert("update success");
}
});
三.RESTful缺点:
1.对后端开发人员要求高,业务逻辑有时难以被抽象为资源的增删改查。
2.对前端开发人员不友好,API粒度较粗,难以查询符合特殊要求的数据,同样的业务要比普通的API需要更多次HTTP请求。
总结
希望成为一个小胖子,没事摸摸小肚子。。。