面试题:你平时是怎么设计接口的?
基于RESTful风格设计接口,RESTful风格主要体现在资源上,每一个资源都有唯一的URL标识。对于不同的行为,使用对应的http-method操作。对于相同的URL,如果http-method不同,那么获取的资源也就不同。
RESTful风格中,不允许出现动词,应该使用资源的名词。结构很清晰明了,并且安全性更高(比如以前删除用户的URL是这样写的:http://localhost/xxx/deleteUserById/id,别人一看到这个URL就知道你是要删除某个用户了,然后就可以推测出内部实现来进行非法操作;而在RESTful中URL是这样写的:http://localhost/xxx/user/id,看到这个URL就蒙圈了,因为从这个URL中我们根本就看不出是删除、修改还是查询操作)
RESTful(REpresentational State Transfer)"资源"表现性状态转移。在RESTful风格中,一切都被认为是资源,每个资源都有对应的URI标识。处理资源时使用GET、POST、PUT、DELETE等http方法来实现新增、查询、修改、删除的操作。
RESTful是一种设计风格而不是标准(并不是所有API都要求这样设计),只是提供了一组设计原则和约束条件。
RESTful规则:
每个资源都有唯一的URL标识
对于不同的行为,使用对应的http-method
URL中不允许出现动词,需使用名词(因为RESTful中URL代表的是一个资源,虽然使用动词不会出错,但不符合RESTful的设计规范)
RESTful风格中,把所有东西都看成是资源,一张图片是资源、一段音频是资源
只返回数据(JSON / XML),不包含任何展现(典型的前后端分离,适合各种客户端开发(PC、Android、iPhone))
常用http-method:
GET 查询
POST 新增
PUT 更新
DELETE 删除
请求方式标识意图GEThttp://caidong4356.top/xxx/users查询所有用户POSThttp://caidong4356.top/xxx/users新增一个用户PUThttp://caidong4356.top/xxx/users修改一个用户DELETEhttp://caidong4356.top/xxx/users/1删除用户1GEThttp://caidong4356.top/xxx/users/1查询用户1GEThttp://caidong4356.top/xxx/users/1/orders查询用户1的所有订单GEThttp://caidong4356.top/xxx/users/1/order给用户1新增一个订单案例
public class User { private Integer userId; private String username; private String password; @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") private Date birthday; public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } } @RestController @RequestMapping("/user") public class UserController { @GetMapping("/users") public List<User> getUsers(){ List list = new ArrayList(); User u1 = new User(); u1.setUserId(1); u1.setUsername("Jack"); u1.setBirthday(new Date()); list.add(u1); User u2 = new User(); u2.setUserId(2); u2.setUsername("Lily"); u2.setBirthday(new Date()); list.add(u2); return list; } @GetMapping("/{id}") public User getUserById(@PathVariable("id")Integer userId){ User u = new User(); if(userId == 1){ u.setUserId(1); u.setUsername("Jack"); u.setBirthday(new Date()); }else { u.setUserId(2); u.setUsername("Lily"); u.setBirthday(new Date()); } return u; } @GetMapping("/name/{name}") public User getUserByName(@PathVariable("name")String username){ User u = new User(); if(username.equals("Jack")){ u.setUserId(1); u.setUsername("Jack"); u.setBirthday(new Date()); }else if(username.equals("Lily")){ u.setUserId(2); u.setUsername("Lily"); u.setBirthday(new Date()); } return u; } @PostMapping("") public String addUser(){ return "{\"message\" : \"数据添加成功\"}"; } @PutMapping("/{id}") public Map<String,Object> updateUserById(@PathVariable("id")Integer userId) { Map map = new HashMap(); map.put("message","数据修改成功"); map.put("userId", userId); return map; } @DeleteMapping("/{id}") public Map<String,Object> deleteUserById(@PathVariable("id")Integer userId) { Map map = new HashMap(); map.put("message","数据删除成功"); map.put("userId", userId); return map; } } <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>RESTful风格</title> <script src="../js/jquery-3.4.1.min.js"></script> <script type="text/javascript"> $(function () { $("#getBtn").click(function () { $.ajax({ url: "/user/users", type: "get", dataType: "json", success: function (data) { var temp = ""; $("tbody").empty(); if(data.length > 0){ $("table").show(); data.map(function (item, index) { temp += "<tr>" + "<td>" + item.userId + "</td>" + "<td>" + item.username + "</td>" + "<td>" + item.birthday + "</td>" + "<tr>"; }); $("tbody").append(temp); } } }) }); $("#getByIdBtn").click(function () { $.ajax({ url: "/user/2", type: "get", dataType: "json", success: function (data) { $("tbody").empty(); $("table").show(); var temp = ""; temp += "<tr>" + "<td>" + data.userId + "</td>" + "<td>" + data.username + "</td>" + "<td>" + data.birthday + "</td>" + "<tr>"; $("tbody").append(temp); } }) }); $("#getByNameBtn").click(function () { $.ajax({ url: "/user/name/Jack", type: "get", dataType: "json", success: function (data) { $("tbody").empty(); $("table").show(); var temp = ""; temp += "<tr>" + "<td>" + data.userId + "</td>" + "<td>" + data.username + "</td>" + "<td>" + data.birthday + "</td>" + "<tr>"; $("tbody").append(temp); } }) }); $("#postBtn").click(function () { $.ajax({ url: "/user", type: "post", dataType: "json", success: function (data) { $("#message").text(data.message); } }) }); $("#putBtn").click(function () { $.ajax({ url: "/user/1", type: "put", dataType: "json", success: function (data) { $("#message").text(data.userId +":"+ data.message); } }) }); $("#deleteBtn").click(function () { $.ajax({ url: "/user/2", type: "delete", dataType: "json", success: function (data) { $("#message").text(data.userId +":"+ data.message); } }) }); }) </script> </head> <body> <div> <input type="button" id="postBtn" value="postBtn"> <input type="button" id="putBtn" value="putBtn"> <input type="button" id="deleteBtn" value="deleteBtn"> </div> <div id="message"></div> <br> <div> <input type="button" id="getByIdBtn" value="getByIdBtn"> <input type="button" id="getByNameBtn" value="getByNameBtn"> <input type="button" id="getBtn" value="getBtn"> <table border="1" cellspacing="0" bordercolor="gray" style="display: none"> <thead> <tr> <th>id</th> <th>姓名</th> <th>生日</th> </tr> </thead> <tbody> </tbody> </table> </div> </body> </html>URL = 域名 + URI
Spring4特性注解: @RestController = @Controller + @ResponseBody
标注该注解的Controller类,其方法返回值为JSON类型
路径变量:放在URI中的变量被称为路径变量