在开发过程中,有时需要自定义 GraphQL 请求来实现更灵活的数据查询和操作。本文将介绍两种主要的自定义 GraphQL 请求方式:手写 GraphQL 请求和调用平台 API。
方式一:手写 GraphQL 请求
手写 GraphQL 请求是一种直接编写查询或变更语句的方式,适用于更复杂或特定的业务需求。以下分别是 query
和 mutation
请求的示例。
1. 手写 Query 请求
以下是一个自定义 query
请求的示例,用于查询某个资源的语言信息列表。
const customQuery = async () => {
const query = `{
resourceLangQuery {
queryListByEntity(query: {active: ACTIVE, installState: true}) {
id
name
active
installState
code
isoCode
}
}
}`;
const result = await http.query('resource', query);
this.list = result.data['resourceLangQuery']['queryListByEntity'];
};
说明:
query
语句定义了一个请求,查询resourceLangQuery
下的语言信息。- 查询的条件是
active
和installState
,只返回符合条件的结果。 - 查询结果包括 id、name、active、installState 等字段。
2. 手写 Mutation 请求
以下是一个 mutation
请求的示例,用于创建新的资源分类信息。
const customMutation = async () => {
const code = Date.now()
const name = `测试${code}`
const mutation = `mutation {
resourceTaxKindMutation {
create(data: {code: "${code}", name: "${name}"}) {
id
code
name
createDate
writeDate
createUid
writeUid
}
}
}`;
const res = await http.mutate('resource', mutation);
console.log(res);
};
说明:
mutation
语句用于创建一个新的资源分类。- create 操作的参数是一个对象,包含 code 和 name 字段。
- 返回值包括 id、createDate 等字段。
方式二:调用平台的 API
平台 API 提供了简化的 GraphQL 调用方法,可以通过封装的函数来发送 query 和 mutation 请求。这种方式减少了手写 GraphQL 语句的复杂性,更加简洁和易于维护。
1. 调用平台的 Mutation API
使用平台的 customMutation
方法可以简化 Mutation 请求。
/**
* 自定义请求方法
* @param modelModel 模型编码
* @param method 方法名或方法对象
* @param records 请求参数,可以是单体对象或者对象的列表
* @param requestFields 请求的字段配置,不传就是解析record内的所有字段
* @param responseFields 响应的字段配置,不传就是所有字段都返回
* @param variables 变量参数
* @param context 上下文,其中的maxDepth属性表示查询的最大深度
*/
const customMutation = async (
modelModel: string,
method: string | { name: string; argumentName: string },
records: ObjectValue | ListValue,
requestFields?: IModelField[],
responseFields?: IModelField[],
variables?: ObjectValue,
context: ObjectValue = {}
): Promise<any>
调用代码示例
// 1.customMutation 调用示例
const createTaxKind = async () => {
const response = await customMutation(
'模型编码',
'模型方法',
{ code: '003', name: '测试3' }
);
console.log(response);
};
const createTaxKind2 = async () => {
const response = await customMutation(
'模型编码',
{name: '方法名', argumentName: '参数名'},
{ code: '003', name: '测试3' }
);
console.log(response);
};
2. 调用平台的 Query API
普通查询数据方法customQuery
/**
* 自定义查询方法
* @param modelModel 模型编码
* @param method 方法名
* @param record 请求参数,可以是单体对象或者对象的列表
* @param requestFields 请求的字段配置,不传就是解析record内的所有字段
* @param responseFields 响应的字段配置,不传就是所有字段都返回
* @param variables 变量参数
* @param context 上下文,其中的maxDepth属性表示查询的最大深度
*/
const customQuery = async <T>(
modelModel: string,
method: string,
record: ObjectValue | ListValue | string = {},
requestFields?: IModelField[],
responseFields?: IModelField[],
variables?: ObjectValue,
context: ObjectValue = {}
): Promise<T>
调用代码示例
const fetchResourceLanguages = async () => {
const response = await customQuery(
'模型编码',
'模型方法',
{ active: true },
);
console.log(response);
};
自定义分页类型接口查询方法
/**
* 自定义分页类型接口查询方法
* @param modelModel 模型编码
* @param methodName 方法名
* @param option 查询条件
* @param requestFields 请求的字段配置,不传就是解析record内的所有字段
* @param responseFields 响应的字段配置,不传就是所有字段都返回
* @param variables 变量参数
* @param context 上下文,其中的maxDepth属性表示查询的最大深度
*/
const customQueryPage = async <T = Record<string, unknown>>(
modelModel: string,
methodName: string,
option: IQueryPageOption,
requestFields?: IModelField[],
responseFields?: IModelField[],
variables?: ObjectValue,
context: ObjectValue = {}
): Promise<IQueryPageResult<T>>
调用代码示例
// 存储字段的rsql查询条件
const rsql = `num > 1 and name =like='关键字'`;
// 查询条件对象
const condition = new Condition(rsql);
// 非存储字段的queryData查询条件
const queryData = { type: 'B2C' };
condition.setConditionBodyData(queryData)
const option = {
// 当前页码
currentPage: 1,
// 每页条数
pageSize: 20,
// 查询条件对象,也可以是rsql字符串
condition,
// 自定义排序
sort: [{sortField: 'id', direction: EDirection.ASC} as ISort]
} as IQueryPageOption;
const variables = {
// 当调用的接口有权限相关提示可以设置该属性
path: getSessionPath()
};
const page = await customQueryPage(
'demo.demoItem',
'queryPage',
option,
[],
undefined,
variables,
{ maxDepth: 1 }
);
标准分页接口查询方法
/**
* 标准分页接口查询方法
* @param modelModel 模型编码
* @param option 查询条件
* @param fields 请求和响应字段配置,不传就取当前模型内的所有字段
* @param variables 变量参数
* @param context 上下文,其中的maxDepth属性表示查询的最大深度
*/
const queryPage = async <T = Record<string, unknown>>(
modelModel: string,
option: IQueryPageOption,
fields?: IModelField[],
variables?: ObjectValue,
context: ObjectValue = {}
): Promise<IQueryPageResult<T>> => {
// 内部实际调用的也是customQueryPage
return customQueryPage(modelModel, 'queryPage', option, fields, fields, variables, context);
};
调用方法示例
参考customQueryPage
的调用示例
查询方法关键类型的定义
/**
* 分页查询条件
*/
interface IQueryPageOption {
pageSize?: number;
currentPage?: number;
sort?: ISort | ISort[];
condition?: Condition | string;
// condition 和 record 只能二选一
record?: ObjectValue | ListValue;
maxDepth?: number;
}
interface IQueryPageResult<T> {
content: T[];
totalElements: number;
size: number;
totalPages: number;
}
通用注意事项
默认情况下,平台 API 请求只会查询两层,如果要查询第三层,则需要传递往下查询深度的context.maxDepth
属性,maxDepth=1
为一共查询两层,maxDepth=2
为一共查询三层;在平台底层maxDepth
是从0开始的,0代表了第一层级,所以为1的时候,就是查两层。
/**
* 响应字段的配置,不配置会返回模型下所有字段,
* 建议按需求配置需要返回哪些字段,
* 下面的配置等同于手写gql的
* user {
* id
* name
* }
*/
const responseFields = [
{
name: 'user',
ttype: ModelFieldType.ManyToOne,
modelFields: [
{ name: 'id', ttype: ModelFieldType.Long },
{ name: 'name', ttype: ModelFieldType.String }
] as IModelField[]
}
] as IModelField[];
customMutation(
'模型编码',
'模型方法',
{ code: '003', name: '测试3' },
undefined,
responseFields,
undefined,
{
maxDepth: 2
}
)
customQuery(
'模型编码',
'模型方法',
{ active: true },
undefined,
responseFields,
undefined,
{
maxDepth: 2
}
)
对比
- 手写 GraphQL 请求适用于请求参数比较简单的请求
- 调用平台 API 适用于请求参数过于复杂、手动很难写
调用平台 API的弊端
调用平台 API会导致gql的请求体很大,因为底层会把当前模型所有的字段都作为响应体返回。如果请求的层级越深,那么gql请求体越大。
如果想通过手写Graphql的方法拼接复杂的请求参数,可以参考这边文章,里面有详细的讲解。
Oinone社区 作者:汤乾华原创文章,如若转载,请注明出处:https://doc.oinone.top/frontend/17638.html
访问Oinone官网:https://www.oinone.top获取数式Oinone低代码应用平台体验