Flutter GraphQL服务端交互插件graphql_server的使用
Flutter GraphQL服务端交互插件graphql_server的使用
简介
graphql_server
是一个用于实现 GraphQL 服务器的基础包。它不依赖任何特定框架,因此可以在任何 Dart 项目中使用。
特点:
- 提供
GraphQL
类来处理查询。 - 支持订阅(Subscriptions)。
- 自动处理模式的反射(Introspection)。
- 可选支持
dart:mirrors
以简化字段解析。
安装
在 pubspec.yaml
文件中添加以下依赖:
dependencies:
graphql_server: ^x.x.x
然后运行 flutter pub get
。
基本用法
1. 查询功能
GraphQL
类的核心方法是 parseAndExecute
,它可以解析并执行 GraphQL 查询。
示例代码:
import 'package:graphql_schema/graphql_schema.dart';
import 'package:graphql_server/graphql_server.dart';
import 'package:test/test.dart';
void main() {
test('single element', () async {
// 定义一个 Todo 类型
var todoType = objectType('todo', fields: [
field(
'text',
graphQLString,
resolve: (obj, args) => obj.text,
),
field(
'completed',
graphQLBoolean,
resolve: (obj, args) => obj.completed,
),
]);
// 定义 Schema
var schema = graphQLSchema(
queryType: objectType('api', fields: [
field(
'todos',
listOf(todoType),
resolve: (_, __) => [
Todo(
text: 'Clean your room!',
completed: false,
)
],
),
]),
);
// 创建 GraphQL 实例
var graphql = GraphQL(schema);
// 执行查询
var result = await graphql.parseAndExecute('{ todos { text } }');
// 输出结果
print(result);
expect(result, {
'todos': [
{'text': 'Clean your room!'}
]
});
});
}
// 定义 Todo 类
class Todo {
final String text;
final bool completed;
Todo({this.text, this.completed});
}
解释:
objectType
定义了一个Todo
类型,包含两个字段:text
和completed
。schema
定义了查询类型api
,其中包含一个todos
字段,返回的是Todo
列表。parseAndExecute
方法执行了 GraphQL 查询{ todos { text } }
,并返回结果。
订阅功能
GraphQL 的订阅功能允许客户端监听实时数据更新。graphql_server
提供了基于 package:stream_channel
的实现。
示例代码
import 'package:graphql_schema/graphql_schema.dart';
import 'package:graphql_server/graphql_server.dart';
import 'package:stream_channel/stream_channel.dart';
import 'package:test/test.dart';
void main() {
test('subscription', () async {
// 定义 Todo 类型
var todoType = objectType('todo', fields: [
field(
'text',
graphQLString,
resolve: (obj, args) => obj.text,
),
field(
'completed',
graphQLBoolean,
resolve: (obj, args) => obj.completed,
),
]);
// 定义 Subscription 类型
var subscriptionType = objectType('subscription', fields: [
field(
'onTodo',
todoType,
resolve: (_, __) {
return Stream.fromIterable([
Todo(text: 'Task 1', completed: false),
Todo(text: 'Task 2', completed: true),
]);
},
),
]);
// 定义 Schema
var schema = graphQLSchema(
subscriptionType: subscriptionType,
);
// 创建 GraphQL 实例
var graphql = GraphQL(schema);
// 模拟 WebSocket 连接
var channel = StreamChannelController().server;
var client = stw.RemoteClient(channel.stream.cast<String>());
var server = _GraphQLWSServer(client, graphql, null, null, 0);
await server.done;
// 执行订阅查询
var subscriptionResult = await graphql.parseAndExecute('subscription { onTodo { text completed } }');
print(subscriptionResult);
expect(subscriptionResult, [
{'onTodo': {'text': 'Task 1', 'completed': false}},
{'onTodo': {'text': 'Task 2', 'completed': true}},
]);
});
}
解释:
subscriptionType
定义了一个onTodo
字段,返回的是Todo
对象的流。_GraphQLWSServer
处理 WebSocket 连接,并将订阅事件传递给客户端。parseAndExecute
方法执行订阅查询,返回实时更新的数据。
Introspection
Introspection 允许客户端查询服务器的模式信息。GraphQL
类会自动处理这一点,无需额外编写代码。
如果需要手动反射模式,可以使用 reflectSchema
方法。
示例代码:
import 'package:graphql_schema/graphql_schema.dart';
import 'package:graphql_server/graphql_server.dart';
void main() {
var schema = graphQLSchema(
queryType: objectType('Query', fields: [
field('hello', graphQLString, resolve: (_, __) => 'Hello World'),
]),
);
var introspectionResult = GraphQL.reflectSchema(schema);
print(introspectionResult);
}
解释:
reflectSchema
方法返回一个 JSON 表示的模式信息。- 这对于调试或生成客户端代码非常有用。
使用 dart:mirrors
简化字段解析
默认情况下,dart:mirrors
不是必需的,但可以选择启用以简化字段解析。
示例代码:
import 'package:graphql_server/graphql_server.dart';
void main() {
var schema = graphQLSchema(
queryType: objectType('Query', fields: [
field(
'user',
userType,
resolve: mirrorsFieldResolver, // 使用 mirrorsFieldResolver
),
]),
);
var graphql = GraphQL(schema);
var result = graphql.parseAndExecute('{ user { name age } }');
print(result);
}
更多关于Flutter GraphQL服务端交互插件graphql_server的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter GraphQL服务端交互插件graphql_server的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中,graphql_server
是一个用于与GraphQL服务端进行交互的插件。它允许你在Flutter应用中执行GraphQL查询、变更和订阅操作。以下是如何使用 graphql_server
插件的基本步骤:
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 graphql_server
插件的依赖:
dependencies:
flutter:
sdk: flutter
graphql_server: ^2.0.0
然后运行 flutter pub get
来安装依赖。
2. 创建GraphQL客户端
接下来,你需要创建一个GraphQL客户端来与服务端进行交互。通常,你需要指定GraphQL服务端的URL。
import 'package:graphql_server/graphql_server.dart';
final GraphQLClient client = GraphQLClient(
link: HttpLink('https://your-graphql-endpoint.com/graphql'),
cache: GraphQLCache(),
);
3. 执行查询
你可以使用 client.query
方法来执行GraphQL查询。以下是一个简单的查询示例:
import 'package:graphql_server/graphql_server.dart';
Future<void> fetchData() async {
const String query = '''
query {
users {
id
name
email
}
}
''';
final QueryOptions options = QueryOptions(
document: gql(query),
);
final QueryResult result = await client.query(options);
if (result.hasException) {
print('Error: ${result.exception}');
} else {
print('Data: ${result.data}');
}
}
4. 执行变更
你可以使用 client.mutate
方法来执行GraphQL变更操作。以下是一个简单的变更示例:
import 'package:graphql_server/graphql_server.dart';
Future<void> createUser(String name, String email) async {
const String mutation = '''
mutation CreateUser(\$name: String!, \$email: String!) {
createUser(name: \$name, email: \$email) {
id
name
email
}
}
''';
final MutationOptions options = MutationOptions(
document: gql(mutation),
variables: <String, dynamic>{
'name': name,
'email': email,
},
);
final QueryResult result = await client.mutate(options);
if (result.hasException) {
print('Error: ${result.exception}');
} else {
print('Data: ${result.data}');
}
}
5. 处理订阅
graphql_server
也支持GraphQL订阅。你可以使用 client.subscribe
方法来订阅实时数据。
import 'package:graphql_server/graphql_server.dart';
Stream<QueryResult> subscribeToMessages() {
const String subscription = '''
subscription {
messageAdded {
id
content
}
}
''';
final SubscriptionOptions options = SubscriptionOptions(
document: gql(subscription),
);
return client.subscribe(options);
}
6. 处理错误
在执行查询、变更或订阅时,可能会遇到错误。你可以通过检查 QueryResult
的 hasException
属性来处理错误。
if (result.hasException) {
print('Error: ${result.exception}');
} else {
print('Data: ${result.data}');
}
7. 使用缓存
graphql_server
提供了缓存机制,你可以通过 GraphQLCache
来管理缓存。默认情况下,查询结果会被缓存,你可以通过 fetchPolicy
来控制缓存行为。
final QueryOptions options = QueryOptions(
document: gql(query),
fetchPolicy: FetchPolicy.networkOnly, // 忽略缓存,直接从网络获取
);
8. 使用链接中间件
graphql_server
支持链接中间件,你可以在请求链中添加自定义逻辑。例如,你可以添加一个认证中间件来在每个请求中添加认证头。
import 'package:graphql_server/graphql_server.dart';
final AuthLink authLink = AuthLink(
getToken: () async => 'Bearer your-auth-token',
);
final Link link = authLink.concat(HttpLink('https://your-graphql-endpoint.com/graphql'));
final GraphQLClient client = GraphQLClient(
link: link,
cache: GraphQLCache(),
);
9. 使用Fragment
GraphQL片段(Fragment)可以帮助你重用查询逻辑。你可以在查询中使用片段来减少重复代码。
const String userFragment = '''
fragment UserFields on User {
id
name
email
}
''';
const String query = '''
$userFragment
query {
users {
...UserFields
}
}
''';
10. 使用变量
GraphQL查询和变更可以接受变量。你可以通过 variables
参数传递变量。
final QueryOptions options = QueryOptions(
document: gql(query),
variables: <String, dynamic>{
'userId': 123,
},
);