Flutter GraphQL客户端插件brick_graphql的使用
Flutter GraphQL客户端插件brick_graphql的使用
Brisk GraphQL
Brick GraphQL 是用于与GraphQL服务器交互的核心逻辑库。
如何生成GraphQL数据
由于Brick与其他提供者(如SQLite)进行插值,必须有一个单一的数据生成点。该库选择从Dart生成代码(而不是像使用 Artemis 这样的GraphQL生成器),以便这些提供者的配置可以存在于相同的源文件中。
支持的Query配置
由于Dart是数据来源,它可能不会与GraphQL合同一一映射。Brick将智能地猜测要使用的操作并发送生成的变量。但是,可以通过 <code>Query(providerArgs)</code>
覆盖。
providerArgs
<code>'operation'</code>
(GraphqlOperation
) 应用此操作而不是从<code>graphqlOperationTransformer</code>
中获取的默认操作。文档子字段不会由模型填充。<code>'context'</code>
(Map<String, ContextEntry>
) 将此作为请求的上下文应用,而不是空对象。这对于后续消费者/Link
很有用。键应为<code>ContextEntry</code>
的运行时类型。
variablesNamespace
某些GraphQL系统可能利用单个变量属性来处理所有操作。默认情况下,Brick可以将所有请求中的所有变量包装在一个顶级键中:
// GraphqlProvider(variablesNamespace: 'vars')
query MyOperation($vars: MyInputClass!) {
myOperation(vars: $vars) {}
}
💡 <code>GraphqlProviderQuery#variables</code>
将永远不会被 <code>variablesNamespace</code>
包装。
where
传递给 <code>where:</code>
的值会被转换为查询和订阅时发送的变量。自动填充的 <code>Query(where:)</code>
变量会被 <code>providerArgs: {'operation'}.variables</code>
覆盖,而不是混合。
Query(where: [
Where('name').isExactly('Thomas')
])
// => {'name': 'Thomas'}
要扩展查询以包含自定义属性,可以使用 <code>GraphqlProvider#queryToVariables</code>
:
final query = Query.where('name', 'Thomas');
final variables = {
...graphqlProvider.queryToVariables(query),
'myCustomVariable': true,
};
⚠️ <code>Where</code>
中的关联值不会被转换为变量。
toJson和子字段
当字段类型的类具有返回 <code>Map</code>
的 <code>#toJson</code>
方法时,子字段会根据该字段类型的 <code>final</code>
实例字段自动生成到请求中。
class Hat {
final String fabric;
final int width;
Hat({this.fabric, this.width});
Map<String, dynamic> toJson() => {'fabric': fabric, 'width': width};
}
class Mounty {
final Hat hat;
final String horseName;
final String name;
}
这将在 <code>query</code>
或 <code>subscription</code>
中生成以下GraphQL文档:
query {
myQueryName {
hat {
fabric
width
}
horseName
name
}
}
模型
为了减少重复粘贴相同的GraphQL文档和变量,所有操作可以在一个地方设置,与模型配置一起。
-
创建一个扩展
<code>GraphqlQueryOperationTransformer</code>
的新类:class UserQueryOperationTransformer extends GraphqlQueryOperationTransformer {}
-
该类可以访问每个请求的
<code>query</code>
,以及<code>delete</code>
和<code>upsert</code>
的<code>instance</code>
。你可以使用这些属性告诉Brick使用哪个GraphQL操作。class UserQueryOperationTransformer extends GraphqlQueryOperationTransformer { GraphqlOperation get upsert { if (query.where != null) { return GraphqlOperation(document: r''' mutation UpdateUserName($name: String!) { updateUserName(input: $input) {} } '''); } return GraphqlOperation(document: r''' mutation CreateUser($input: UserInput!) { createUser(input: $input) {} } '''); } }
-
在复杂情况下,如果整个模型没有被传输,也可以提供
<code>variables</code>
。class UserQueryOperationTransformer extends GraphqlQueryOperationTransformer { GraphqlOperation get upsert { if (query.where != null) { return GraphqlOperation( document: r''' mutation UpdateUserName($name: String!) { updateUserName(input: $input) {} } ''', variables: {'name': Where.firstByField('name', query.where)}, ); } return null; } }
-
在
<code>GraphqlSerializable</code>
中使用该类:@GraphqlSerializable( queryOperationTransformer: UserQueryOperationTransformer.new )
💡 只需提供头部;节点可以用来覆盖模型请求的所有字段的默认行为。要使用由模型(与 <code>@Graphql</code>
配置相关)提供的自动填充节点,使用空节点选择(例如 <code>deleteUser(vars: $vars) {}</code>
)。
示例代码
import 'package:brick_core/core.dart';
import 'package:brick_graphql/brick_graphql.dart';
import 'package:gql_http_link/gql_http_link.dart';
class UserQueryOperationTransformer extends GraphqlQueryOperationTransformer {
GraphqlOperation get get => GraphqlOperation(document: '''
query AllUsers {
allUsers {}
}
''');
const UserQueryOperationTransformer(Query? query, GraphqlModel? instance)
: super(query, instance);
}
/// 此类和代码始终由域生成
/// 例如使用 brick_offline_first_with_graphql_build 包
class UserAdapter extends GraphqlAdapter<User> {
[@override](/user/override)
final queryOperationTransformer = UserQueryOperationTransformer.new;
[@override](/user/override)
Map<String, RuntimeGraphqlDefinition> get fieldsToGraphqlRuntimeDefinition => {
'name': const RuntimeGraphqlDefinition(
association: false,
documentNodeName: 'full_name',
iterable: false,
type: String,
),
};
[@override](/user/override)
Future<User> fromGraphql(data, {required provider, repository}) async {
return User(
name: data['name'],
);
}
[@override](/user/override)
Future<Map<String, dynamic>> toGraphql(instance, {required provider, repository}) async {
return {
'name': instance.name,
};
}
}
/// 此值始终由域生成
/// 例如使用 brick_offline_first_with_graphql_build 包
final dictionary = GraphqlModelDictionary({
User: UserAdapter(),
});
/// 模型是唯一的实现(例如一个Flutter应用)
class User extends GraphqlModel {
final String name;
User({
required this.name,
});
}
class MyRepository extends SingleProviderRepository<GraphqlModel> {
MyRepository(String baseApiUrl)
: super(
GraphqlProvider(
link: HttpLink(baseApiUrl),
modelDictionary: dictionary,
),
);
}
/// 运行在简单的Apollo GraphQL服务器上:
/*
const { ApolloServer } = require("apollo-server");
const typeDefs = gql`
type User {
name: String
}
type Query {
allUsers: [User]
}
`;
const user = { name: 'Thomas' };
const resolvers = {
Query: {
allUsers: () => [user],
}
}
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
*/
void main() async {
final repository = MyRepository('http://localhost:4000');
final users = await repository.get<User>();
print(users);
}
更多关于Flutter GraphQL客户端插件brick_graphql的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html