作为一名后端在做Web后端业务开发时,都应该遵循以下规则
在使用RESTFUL API风格开发时,几乎所有方法为 GET
的 列表或详情 接口
都不可避免的需要用到 分页
、查询筛选条件
、自定义排序
的功能
假如我们为每个接口去分别开发以上三种功能,将会耗费大量时间
很多后端都会将 查询筛选条件
、 自定义排序
做成参数查询
但是 查询筛选条件
则要一个个写接收请求参数并且去调用 where/orwhere/like/where in… 等方法去挨个处理
那要如何把选择权和控制权交给前端同事呢?
我们可以给所有接口获取列表的封装个方法
在这里使用的是 Gin
+Gorm
的例子,其他框架也可以使用类似操作解决这样的问题
自定义分页
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| func Paging(c *gin.Context, db *gorm.DB) (db *gorm.DB, err error) { limitStr := c.Request.FormValue("limit") pageStr := c.Request.FormValue("page") if limitStr == "" || pageStr == "" { return db, nil } limit, err := strconv.Atoi(limitStr) if err != nil { return db, nil } page, err := strconv.Atoi(pageStr) if err != nil { return db, nil } db = db.Offset((page - 1) * limit).Limit(limit) return db, nil }
|
自定义排序
1 2 3 4 5 6 7 8 9 10 11 12 13
| func Sort(c *gin.Context, db *gorm.DB) *gorm.DB { orderBy := c.Request.FormValue("order_by") if orderBy == "" { return db } order := c.Request.FormValue("order") if order != "" { db = db.Order(orderBy + " " + order) } else { db = db.Order(orderBy + " DESC") } return db }
|
自定义查询筛选条件
分页和自定义排序功能就不做解释了,做过web后端基本都了解了
按照field_查询操作符_字段名的格式前端请求的query参数中提取并添加查询条件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| func ConditionSupport(c *gin.Context, db *gorm.DB) (*gorm.DB, error) { query, err := url.ParseQuery(c.Request.URL.RawQuery) if err != nil { return nil, errors.New("请求参数不正确,请联系管理员进行处理") } for name, value := range query { if !strings.HasPrfix(name, "field") || len(name) <= 9 { return db,nil } fieldName := "`" + name[9:] + "`" fieldName = strings.Replace(fieldName,".","`.`",-1) opt := name[6:8] switch opt { case "eq": if len(value) == 1 { db = db.Where(fieldName+"=?", value[0]) } else { db = db.Where(fieldName+" IN (?)", value) } case "ne": db = db.Where(fieldName+"<>?", value[0]) case "lt": db = db.Where(fieldName+"<?", value[0]) case "le": db = db.Where(fieldName+"<=?", value[0]) case "gt": db = db.Where(fieldName+">?", value[0]) case "ge": db = db.Where(fieldName+">=?", value[0]) case "lk": db = db.Where(fieldName+" LIKE ?", "%"+value[0]+"%") case "re": db = db.Where(fieldName+" REGEXP ?", value[0]) default: return nil, errors.New("不支持的条件查询操作") } } return db, nil }
|
结合三种方法一起使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| func Find(c *gin.Context, db *gorm.DB, result *interface{}) (int64, error) { var count int64 err := c.Request.ParseForm() if err != nil { return 0, errors.New("参数不正确") } db, err = ConditionSupport(c, db) if err != nil { return 0, errors.New("查询条件有误") } db, err = Paging(c, db) if err != nil { return 0, errors.New("分页参数不正确") } err = db.Count(&count).Error if err != nil { return 0, errors.New("数据库记录统计失败,请稍后再试") } err = Sort(c, db).Find(result).Error return count, errors.New("数据库记录查询失败,请稍后再试") }
|
最后我们只需要给每个需要 分页
、查询筛选条件
、自定义排序
的地方使用Find函数便可以将操作权交给前端了