面试题:你平时是怎么设计接口的?
基于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 删除
请求方式 | 标识 | 意图 |
---|---|---|
GET | http://caidong4356.top/xxx/users | 查询所有用户 |
POST | http://caidong4356.top/xxx/users | 新增一个用户 |
PUT | http://caidong4356.top/xxx/users | 修改一个用户 |
DELETE | http://caidong4356.top/xxx/users/1 | 删除用户1 |
GET | http://caidong4356.top/xxx/users/1 | 查询用户1 |
GET | http://caidong4356.top/xxx/users/1/orders | 查询用户1的所有订单 |
GET | http://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中的变量被称为路径变量