关于查询接口设计

此篇博客记录自己在设计模糊查询接口时候犯的错误,以及个人的一些浅略的思考。说明:此并非最优设计

前言

此模糊查询是项目的一个小接口,大致功能如下图所示。

产品的需求:

  1. 下拉框可以筛选状态,如选中已激活,则只展示已激活状态的学生名单。
  2. 搜索框中可以输入内容,进行姓名模糊查询。
  3. 可以根据创建时间进行排序,升序或者降序。
  4. 分页功能

第一次的接口设计(❌)

不知道从哪篇博客中看到这样一句话:GET操作不修改数据库,POST操作修改数据库(事实没这么绝对)。这不简单呀,5秒钟,Controller,Service...,前端对接,搞定。

GET /student/{studentName}/{state}?order=1&page=1&size=10
GET /student/{state}?order=1&page=1&size=10

order: -1:不排序,0:升序,1:降序
state: -1:全部,0:未激活,1:已激活

哦,这该死的天才,这么难的问题,轻易化解。

让我们对应需求,一一验证:

  1. 下拉框可以筛选状态,如选中已激活,则只展示已激活状态的学生名单。
    GET /student/1?order=-1&page=1&size=10
  2. 搜索框中可以输入内容,进行姓名模糊查询。
    GET /student/张三/-1?order=1&page=1&size=10
  3. 可以根据创建时间进行排序,升序或者降序。
    GET /student/-1?order=1&page=1&size=10 升序
  4. 分页功能
    GET /student/-1?order=1&page=1&size=10

前端,我的接口都能满足,要什么你自己组合去,很显然,目前为止功能正常。

测试登场,毫不犹豫扔给你一个缺陷,大意了没有闪。

为什么会出现404呢?哦因为你查询的内容导致接口变了。

第二次的接口设计(✔)(🟧待定) 2023-5-30 修改

  1. 为什么接口不能正常映射?
    因为特殊字符,浏览器没把它当成字符串,导致请求的接口不能被后端识别。
  2. 有什么感想?
    这种studentName未知的东西,尽量别放在PathParam,今天出来一个%,明天一个\,后天不知道出什么幺蛾子。
    像state,这种固定的东西,只能取-1,0,1,可以放进PathParam中。

苦思冥想,这GET操作,还能怎么设计呢?

POST优雅登场

POST /student/list
{
    "conditions":{
        "name":"huiu9123",
        "state":-1
    },
    "order":0,
    "page":1,--
    "size":10
}

通用Request

设计通用搜索请求体,conditions放自定义搜索条件,order、page、size这三个参数每个搜索都会用到,放在外边。

@Setter  
@Getter  
public class QueryRequest<T> {  
	/**
	 * 自定义搜索条件
	 * /
    T conditions;  
    /**  
     * 排序  
     */  
    Integer order;  
    /**  
     * 第几页  
     */  
    Integer page;  
    /**  
     * 每页数据量  
     */  
    Integer size;  
}

设计需求自定义搜索条件

@Setter  
@Getter  
@NoArgsConstructor  
@AllArgsConstructor  
public class StudentQueryCondition {  
    String name;  
    Integer state;  
}

设计搜索接口

@PostMapping(path = "/list")  
public String list(@RequestBody QueryRequest<StudentQueryCondition> request) {  
    CodeMessageEnum msg = CodeMessageEnum.OK;  
    .......省略处理逻辑......
    return ControllerUtil.wrap(msg, response).toString();  
}

第三次接口设计(🟢)

由于后面添加了Mybatis-Plus框架,可以使用动态sql

@GetMapping("/student")
Result<ListDTO<StudentDTO>> queryStudentList(@Validated StudentQueryParam studentQueryParam) {
    ListDTO<StudentDTO> result = subjectService.queryStudentList(studentListParam);
    return Result.success(result);
}
class StudentQueryParam{
    @Size(max = NAME_SIZE_MAX, message = NAME_SIZE_MESSAGE)
    String name;  
    Integer state; 
}
<select id="selectStudentPage" resultType="com.tao.entity.Student">
        SELECT *
        FROM demo_student ds
        WHERE is_deleted = false
        <if test="param.searchField!=null and param.searchField!='all' and param.searchVal != null and param.searchVal != ''">
            and ds.${param.searchField} ilike '%${param.searchVal}%'
        </if>
        order by ${param.sortField} ${param.sortRule},ds.id desc
    </select>

结尾

  1. 别人说的话不一定是对的。 别人说的有道理 (/(ㄒoㄒ)/~~)
  2. 踩过坑,才能长记性,这次因为我的错误,前端也要修改大量内容。
posted @   帅气的涛啊  阅读(294)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示

目录