Reatful

API概念 :

API : 应用程序编程接口, 是一些预先定义的函数, 或者指软件系统不同组成部分衔接的约定

目的 : 提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力, 而又无需访问源码, 或理解内部工作机制的细节

应用接口: 很多情况下,需要把系统的功能作为服务暴露给外部的其他应用使用,就需要把系统中的服务作为API接口暴露出去,一般分为公共接口(发短信,天气服务)和私用接口(公司内部使用的);

前后端分离与传统开发模式的比较

传统开发模式

前端写好静态的html页面交给后端开发,后端把html改成模板,然后使用模板引擎去套模板,比如jsp,freemarker等
后端人员在开发过程中如果发现页面有问题,要返回给前端修改,前端再交给后端,直至功能实现。

问题: 前后端严重耦合

  1. 前端需要修改bug ,调试的时候,需要在电脑安装一整套后端的开发工具,启动后端程序
  2. 要求后端人员会 html , js等前端语言
  3. 前端页面也会嵌入很多后端代码
  4. 一旦后端换了语言, 前端也要重新开发
  5. 沟通成本, 调试成本, 前后端开发进度相互影响, 从而大大降低开发效率

前后端分离模式

前后端分离并不只是开发模式,也是web应用的一种架构模式. 在开发阶段,前后端人员约定要数据交互的接口,即可并行开发与测试

前端开发完成可以独自进行mock测试, 后端也可以使用postman等接口测试工具进行测试,最后可以进行功能联调测试.

优点:

  1. 前后端责任清晰, 后端专注在数据上, 前端专注在视觉上.
  2. 无需等待对方的开发工作结束, 提高开发效率.
  3. 可应对复杂多变的前端需求.
  4. 增强代码可维护性.

前后端分离模式操作流程 :

rembg接口使用 reatful接口_服务器

Restful 风格接口约束要点:

1>请求路径: 要求是操作资源(实体对象:domain)名称复数 如 /employees

2>请求方式: 使用请求方式替换资源操作: POST–新增 GET–查询 DELETE–删除 PUT–更新

3>请求参数 : 根之前一样, 需求决定 : employee对象 角色id集合

4>请求响应值 : 跟之前一样. 需求决定 ,但是建议返回值都是 json 格式

rembg接口使用 reatful接口_服务器_02

员工列表查询与员工单个查询, 使用相同映射路径: /employees 和 相同请求方法:RequestMethod.GET 导致请求路径(路径+ 请求方法)一样 , 报错

restful 提供解决方案: 使用参数路径方法
参数路径: 将参数作为请求路径的一部分
比如:/employees/{id} 此处{id} 就是一个参数
    
页面/postman 发起请求时 使用:   http://localhost:8080/employees/22
其中22 就是id参数值,同时也是请求路径一部分
    另外,请求映射方法必须使用 
    需要在参数前 加入一个注解@pathVariable 进行参数继续
    
 注意: 如果路径参数标记与请求映射方法参数名不一致时怎么办?
     可以使用 @PathVariable("eid") value 属性指定

参数路径方式与传统方式对比 :

1>参数路径方式:
	优点: 可以隐藏参数, 避免暴露参数, 相对安全
    缺点: 如果参数较多 url 路径很长, 不建议使用
        
如何选用?
    参数少的时候 使用 参数路径方式
    参数多的时候 还是使用 传统路径

如果不是 SpringBoot 项目 需要再添加一个依赖

@GetMapping  等价于 @RequestMapping(method = RequestMethod.GET)
@PostMapping 等价于 @RequestMapping(method = RequestMethod.POST)
@DeleteMapping 等价于 @RequestMapping(method = RequestMethod.DELETE)
@PutMapping 等价于 @RequestMapping(method = RequestMethod.PUT)
@RestController 等价于 @Controller + @ResponseBody

@RequestMapping 注解的解析

params = "name" : 要求请求参数中必须携带名称的参数:name
params = "name=dafei" : 要求请求参数中必须携带名称的参数:name, 并且name = dafei
headers:限定要处理请求的请求头信息,只有匹配该请求头内容的请求,才会被该方法处理;
	@GetMapping(value = "/test", headers = "content-type=text/*")

RESTful 设计

使用同一接口 :

REST 要求 , 必须通过统一的接口来对资源执行各种操作.

HTTP 1.1 协议 :
7 个HTTP 方法 : GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS

GET (SELECT) : 从服务器取出资源(多项) 例如:http://localhost:8080/employees

GET (SELECT) : 从服务器取出资源(一项) 例如:http://localhost:8080/employees/1
在后端 Controller 中 使用 的 url = "/employees/{id}"

POST(CREATE) : 在服务器新建一个资源 例如:http://localhost:8080/employees?id=1&username=“dagu”&age=18

PUT(UPDATE) : 在服务器更新资源 , PUT 更新整个对象 例如: http://localhost:8080/employees/1?username=“dagu”&age=18

DELETE(DELETE) : 在服务器删除资源 例如:http://localhost:8080/employees

返回值根据需求决定

Accept 与 Content-Type的区别 :

rembg接口使用 reatful接口_restful_03

Accept与Content-Type的区别
1.Accept属于请求头, Content-Type属于实体头。
Http报头分为通用报头,请求报头,响应报头和实体报头。
请求方的http报头结构:通用报头|请求报头|实体报头
响应方的http报头结构:通用报头|响应报头|实体报头

2**.Accept**代表发送端(客户端)希望接受的数据类型。
比如:Accept:application/json;
代表客户端希望接受的数据类型是json类型,后台返回json数据

3.Content-Type代表发送端(客户端|服务器)发送的实体数据的数据类型。
比如:Content-Type:application/json;
代表发送端发送的数据格式是json, 后台就要以这种格式来接收前端发过来的数据。

SpringMVC开发RESTful 接口

@Controller
public class EmployeeController_back {
    /**
     * 需求: 获取所有employee数据
     */
    @RequestMapping(value = "/employees", method = RequestMethod.GET)
    @ResponseBody
    public List<Employee> list() {
        List<Employee> employees = Arrays.asList(new Employee(1L,"dagu",123),new Employee(2L,"xiaogu",123));
        return employees;
    }
    /**
     * 需求: 获取id=? 的 employee数据
     */
    @RequestMapping(value = "/employees/{id}", method = RequestMethod.GET)
    @ResponseBody
    public Employee get(@PathVariable Long id) {
        return new Employee(id,"xiaohao",233);
    }
    /**
     * 需求: 员工新增
     */
    @RequestMapping(value = "/employees", method = RequestMethod.POST)
    @ResponseBody
    public Employee save(Employee employee) {
        employee.setId(1L);
        return employee;
    }
    /**
     * 需求: 根据id 删除数据
     */
    @RequestMapping(value = "/employees", method = RequestMethod.DELETE)
    @ResponseBody
    public JsonResult delete(Long id) {
        return new JsonResult();
    }
    /**
     * 需求: 根据id 更新数据
     */
    @RequestMapping(value = "/employees", method = RequestMethod.PUT)
    @ResponseBody
    public JsonResult update(Long id) {
        return new JsonResult();
    }
}

精简化

@RestController  // @RestController = @Controller + @ResponseBody
@RequestMapping("employees")
public class EmployeeController {

    @GetMapping // @GetMapping = @RequestMapping(method = RequestMethod.GET)
    public List<Employee> list() {
        List<Employee> employees = Arrays.asList(new Employee(1L,"dagu",123),new Employee(2L,"xiaogu",123));
        return employees;
    }
    @GetMapping("/{id}")    // @GetMapping = @RequestMapping(method = RequestMethod.GET)
    public Employee get(@PathVariable Long id) {
        return new Employee(id,"xiaohao",233);
    }
    @PostMapping    // @PostMapping = @RequestMapping(method = RequestMethod.POST)
    public Employee save(Employee employee) {
        employee.setId(1L);
        return employee;
    }
    @DeleteMapping  // @DeleteMapping = @RequestMapping(method = RequestMethod.DELETE)
    public JsonResult delete(Long id) {
        return new JsonResult();
    }
    @PutMapping // @PutMapping = @RequestMapping(method = RequestMethod.PUT)
    public JsonResult update(Long id) {
        return new JsonResult();
    }
}

使用Ajax来发送各种请求方法的请求

<script>
        $(function () {
            $("#but1").click(function () {	// 查多个
                $.get("/employees",function (data) {
                    console.log(data);
                });
            });

            $("#but2").click(function () { // 查一个
                $.get("/employees/22",function (data) {
                    console.log(data);
                });
            });

            $("#but3").click(function () { // 新增
                $.ajax({
                    url:"/employees",
                    type:"POST",
                    data:{id:1,username:"xiaohao",age:21},
                    success:function (data) {
                        console.log(data);
                    }
                })
            });

            $("#but4").click(function () {	// 修改
                $.ajax({
                    url:"/employees",
                    type:"PUT",
                    data:{id:1,username:"xiaohao",age:21},
                    success:function (data) {
                        console.log(data);
                    }
                })
            });

            $("#but5").click(function () {	// 删除
                $.ajax({
                    url:"/employees",
                    type:"DELETE",
                    data:{id:1},
                    success:function (data) {
                        console.log(data);
                    }
                })
            });
        });
    </script>
<body>
CRUD: <br/>
<button id="but1">查多个</button>
<button id="but2">查一个</button>
<button id="but3">新增</button>
<button id="but4">修改</button>
<button id="but5">删除</button>
</body>

在前端中 , 如何用 jQuery 编写 ajax请求

rembg接口使用 reatful接口_ajax_04