# API 规范

# Query 参数

在数据访问和生成的CRUD查询接口中,我们会接触到QueryableQuery/QueryBaseQueryable的实现类)参数,这里统称为Query参数,该参数存储了生成查询SQL中所需要的所有基本属性,如SELECT内容、WHERE内容等。Fly制定了一系列规范,按照约定的语法编写表达式,可实现基本的数据查询需求。

  • 数据访问查询
Query query = Query.filters(Filters.parse("name eq 1")).build();

// SELECT id, name FROM news WHERE name = '1'
dao.createQuery(NewsEntity.class).execute(query);
dao.createQuery(NewsEntity.class).queryable(query).list();
  • CRUD查询接口

简单示例,filters参数可以在查询中进行数据过滤(WHERE),Controller实现CRUD的查询接口FlexibleCrudQuery

@RestController
@RequestMapping("/news")
@Crud(entityClass = NewsEntity.class)
public class NewsEntityController implements FlexibleCrudQuery {}

请求内容:

GET /news?filters=name eq '1 2'

注意若值含有空格,需要用'单引号括住。最终生成的查询SQL为:

SELECT id, name FROM news WHERE name = '1 2'

# 字段选择

属性参数名为select,用于选择只返回需要的字段,减少数据传输大小。

  • 多个字段使用英文逗号分隔;
  • 查询字段&表达式指定别名,使用空格连接别名。
GET /news?select=id,name n

# 数据过滤

属性参数名为filters,传入表达式,通过特定的语法实现WHERE过滤。

可使用的查询操作符:

操作符 SQL 说明 示例
eq = 等于 filters=name eq Tom
lt < 小于 filters=age lt 20
le <= 小于或等于 filters=age le 20
gt > 大于 filters=age gt 20
ge >= 大于或等于 filters=age ge 20
ne != 不等于 filters=age ne 20
like like 模糊查询 filters=name like T%
in in 在指定的值内查询 filters=name in (n1,n2)
not in not in 排除指定的值查询(Since 0.6.1-SNAPSHOT) filters=name not in (n1,n2)
is is 相当于sql关键字is filters=name is null
not is not 相当于sql关键字is not filters=name not null
and and 表示多条件间的且关系 filters=name like T% and age lt 20
or or 表示多条件间的或关系 filters=name like T% or age lt 20
() () 表达式组,可以用来改变表达式的优先级关系 filters=name like T% and ((age lt 20) or (name like %y))

注意参数、操作符和值之间的空格。

# 数据排序

属性参数名为orderBy,排序表达式,多个排序项用英文逗号分隔:

GET /news?orderBy=createdAt desc,name asc

# 关联查询

属性参数名为joins,关联表达式,通过特定的语法实现关联查询:

joins={relation} {alias}[,{relation} {alias}]

关联查询后的关系别名,可以应用于selectfilters等参数中,示例:

Member成员实体的userId字段关联User用户实体。

@Entity
public class User {
    
    @Id
    protected String id;
    
    @Column
    protected String name;
    
    // get/set
    
}
@Entity
public class Member {
    
    @Id
    protected String id;
    
    @ManyToOne(relation = "user", targetEntity = User.class)
    protected String userId;
    
    // get/set
    
}

Member成员实体创建查询接口:

@RestController
@RequestMapping("/memebr")
@Crud(entityClass = Member.class)
public class NewsEntityController implements FlexibleCrudQuery {}

根据成员的用户名称过滤并返回用户名称,请求为:

GET /member?select=u.name userName&filters=u.name eq 'system'&joins=user u

# 展开查询

属性参数名为expand,用于在一次请求中查询返回某实体的记录以及关联实体的记录。多个关系用英文逗号分隔:

GET /news?expand={relation}[,{relation}]

展开查询内容保存到与关系名同名的返回属性中,不同类型关系返回数据结构如下:

  • 多对一关系
{
    "id": "...",
    "name": "...",
    "{relation}": {
        "id": "..."
    }
}
  • 一对多关系
{
    "id": "...",
    "name": "...",
    "{relation}": [
        {
            "id": "..."
        }
    ]
}

# 指定展开查询的字段

如展开查询多对一关系user,关系实体有idnamecreatedAt等字段,在展开查询中只需要返回name

GET /news?expand=user(name)

请求返回内容:

{
    "id": "...",
    "name": "...",
    "user": {
        "name": "..."
    }
}

# 展开查询中设置参数

Since 0.8.1

如展开查询多对一关系user,关系实体有idnamecreatedAt等字段,展开查询只需要返回name,且添加filters过滤或orderby排序:

GET /news?expand=user(select:name)
GET /news?expand=user(filters:name eq demo)
GET /news?expand=user(orderby:name desc)

组合使用:

GET /news?expand=user(select:id,name,orderby:name desc)

# 数据分页

分页参数组合有:

  1. 分页
参数 类型 作用
page Integer 指定查询页码,从1开始
page_size Integer 指定查询页大小
GET /news?page=1&page_size=10
  1. 查询行&偏移量
参数 类型 作用
limit Integer 指定查询行,类似SQL中的limit
offset Integer 查询偏移量,表示偏移几行开始返回,与limit配合使用实现分页。从0开始
GET /news?limit=10
GET /news?limit=10&offset=20

# 异常处理

内置了几个常见场景的响应异常,在API执行中直接抛出该异常,返回的状态码为:

异常 状态码
BadRequestException 400
ConflictException 409
ForbiddenException 403
NotFoundException 404
NotImplementedException 501

异常依据Spring规范定义,使用了org.springframework.http.HttpStatus中的状态码,异常详细描述可以见https://tools.ietf.org/html/rfc7231 (opens new window)

顶部