一、什么是 restful api?
rest(representational state transfer)是一种 面向资源 的架构风格,核心思想:
用 url 定位资源,用 http 动词描述操作
面向资源怎么理解呢?:
restful api 就是符合 rest 约束的接口,特点:
- ✅ 无状态(每次请求自带上下文)
- ✅ 统一接口(get/post/put/delete)
- ✅ 资源导向(url 是名词,不是动词)
二、设计规范
2.1 controller接口设计规范
restful api的requestmapping的方式有4种,以图书为例,每一种的应用场景如下:
| 动作 | 资源集合 /books | 单个资源 /books/{id} |
| get | 查询集合 | 查询单个 |
| post | 新增集合 | ❌ |
| put | 批量更新 | 更新单个 |
| delete | 批量删除 | 删除单个 |
2.2 返回结构设计规范
| 字段 | 类型 | 说明 |
| code | int | http 状态码(200/400/404/500) |
| message | string | 用户可读提示信息 |
| data | 泛型t | 业务数据(含分页) |
三、restful与非restful风格对比
3.1查询图书
非 restful 代码:
@getmapping("/getbook")
public list<book> getbooks(@requestparam int page,@requestparam int size) {
return bookservice.list(page,size); // 直接 list
}restful 代码:
@getmapping("/book")
public apiresponse<pagevo<book>> list(@requestparam(defaultvalue = "1") int page,@requestparam(defaultvalue = "10") int size) {
return apiresponse.success(pagevo.of(bookservice.list(page,size)));
}对比表格:
| 纬度 | 非 restful | restful |
| url | /getbook.php?page=1&size=20 | /book?page=1&size=20 |
| http | get | get |
| 返回 | list<book> | apiresponse<pagevo<book>> |
| 状态码 | 200(包一切) | 200(正常) |
| 示例返回 | [{...}, {...}] | {code:200,data:{records:[...],total:90}} |
3.2 新增图书
非 restful 代码:
@postmapping("/addbook")
public book addbook(@requestbody book book) {
return bookservice.create(book); // 直接实体
}restful 代码:
@postmapping("/book")
@responsestatus(httpstatus.created)
public apiresponse<book> create(@valid @requestbody book book) {
return apiresponse.success(bookservice.create(book));
}对比表格:
| 纬度 | 非 restful | restful |
| url | /addbook.php | /book |
| http | post | post |
| 返回 | book | apiresponse<book> |
| 状态码 | 200(包一切) | 201(created) |
| 示例返回 | {...} | {code:200,data:{}} |
3.3 修改图书
非 restful 代码:
@postmapping("/updatebook")
public book update(@valid @requestbody book book) {
//处理修改逻辑
return book;
}
restful 代码:
@putmapping("/book")
public apiresponse<book> update(@valid @requestbody book book) {
//处理修改逻辑
return apiresponse.success(book);
}对比表格:
| 纬度 | 非 restful | restful |
| url | /updatebook.php | /book |
| http | post | put |
| 返回 | book | apiresponse<book> |
| 示例返回 | {...} | {code:200,data:{}} |
3.4 删除图书
非 restful 代码:
@getmapping("/deletebook")
public string deletebook(@requestparam long id) {
bookservice.delete(id);
return "删除成功"; // 字符串
}restful 代码:
@deletemapping("/book/{id}")
@responsestatus(httpstatus.no_content)
public apiresponse<string> delete(@pathvariable long id) {
bookservice.deletebyid(id);
return apiresponse.success("删除成功");
}对比表格:
| 纬度 | 非 restful | restful |
| url | /deletebook.php?id=1 | /book/1 |
| http | get(❌) | delete |
| 返回 | string("删除成功") | apiresponse<string> |
从上述可以看出,使用restful风格,增删查改接口的url可以命名相同/book,因为是根据不同的方式(get、post、put、delete)来区分的。
四、springboot 实战
4.1 前提准备实体类
@data
@builder
@noargsconstructor
@allargsconstructor
public class book {
private long id;
private string name;
private bigdecimal price;
}4.2 restful返回规范
@data
public class apiresponse<t> {
private int code;
private string message;
private t data;
public static <t> apiresponse<t> success(t data) {
apiresponse<t> resp = new apiresponse<>();
resp.code = 200;
resp.message = "success";
resp.data = data;
return resp;
}
}4.3 controller类(restful 核心)
@restcontroller
@requestmapping("/books")
@validated
public class bookcontroller {
private final map<long, book> repo = new concurrenthashmap<>();
// 查询集合
@getmapping
public apiresponse<list<book>> list(@requestparam(required = false) string name) {
list<book> list = repo.values().stream()
.filter(b -> name == null || b.getname().contains(name))
.collect(collectors.tolist());
return apiresponse.success(list);
}
// 查询单个
@getmapping("/{id}")
public apiresponse<book> get(@pathvariable long id) {
book book = optional.ofnullable(repo.get(id))
.orelsethrow(() -> new responsestatusexception(httpstatus.not_found));
return apiresponse.success(book );
}
// 新增
@postmapping
public apiresponse<book>create(@valid @requestbody book book) {
book.setid(system.currenttimemillis());
repo.put(book.getid(), book);
return apiresponse.success(list);
}
// 全量更新
@putmapping("/{id}")
public apiresponse<book> update(@pathvariable long id, @valid @requestbody book book) {
//自定义更新逻辑
return apiresponse.success(list);
}
// 删除
@deletemapping("/{id}")
@responsestatus(httpstatus.no_content)
public apiresponse<?> delete(@pathvariable long id) {
return apiresponse.success(repo.remove(id));
}
}4.4 请求示例
get /books → 查询图书列表
get /books/1 → 查询 id=1 的图书
post /books → 新增图书
put /books/1 → 全量更新 id=1 的图书
delete /books/1 → 删除 id=1 的图书
以上就是基于springboot打造restful api实战指南的详细内容,更多关于springboot打造restful api的资料请关注代码网其它相关文章!
发表评论