知海

Flutter/Dart:Ferry(GraphQL 客户端)

graphql-github-io-zh-Hans生态项目与库

Flutter/Dart:Ferry(GraphQL 客户端)

所属分类:生态项目与库

项目简介

Ferry 是一个为 Flutter 和 Dart 设计的简单、强大的 GraphQL 客户端。它基于 gql-dart 生态构建,提供了类型安全、响应式的 GraphQL 数据交互能力,适用于移动端、桌面端及服务端 Dart 应用。

核心特性

  • 类型安全:通过 gql_code_builderbuild_runner.graphql 文件自动生成类型安全的操作代码(请求、响应、片段等)。
  • 响应式流式设计:基于 rxdart,所有请求和缓存数据均以流(Stream)的形式暴露,轻松实现 UI 的实时更新和乐观响应。
  • 缓存机制:内置规范化缓存(Normalized Cache),支持持久化,帮助管理本地数据状态。
  • 灵活的链接(Link)体系:借鉴 Apollo 的链接模式,可组合 HTTP、WebSocket、重试、日志等中间件,满足复杂场景。
  • 纯净的 GraphQL 实现:仅依赖标准 GraphQL 规范,可与标准服务器无缝集成,也支持自定义链接扩展。

安装

在项目的 pubspec.yaml 中添加如下依赖:

yaml 复制代码
dependencies:
  ferry: ^0.16.0
  gql_http_link: ^1.0.0  # HTTP 场景

然后运行:

bash 复制代码
flutter pub get

如需启用代码生成,还需要在 dev_dependencies 中添加:

yaml 复制代码
dev_dependencies:
  build_runner: ^2.0.0
  ferry_generator: ^0.10.0

基本用法

1. 定义 GraphQL 操作

在项目中创建 .graphql 文件(例如 queries.graphql):

graphql 复制代码
query GetUser($id: ID!) {
  user(id: $id) {
    id
    name
    email
  }
}

2. 生成类型安全代码

在项目根目录运行:

bash 复制代码
flutter pub run build_runner build

该命令会生成与你的操作对应的 Dart 类,例如 GetUser

3. 创建客户端

dart 复制代码
import 'package:ferry/ferry.dart';
import 'package:gql_http_link/gql_http_link.dart';

final link = HttpLink('https://api.example.com/graphql');

final client = Client(
  link: link,
);

4. 发起查询

dart 复制代码
import 'package:graphql_queries.graphql.dart' as operations;

final request = GRequest(
  operation: operations.GetUser(
    (b) => b..vars.id = 'user-1',
  ),
);

// 使用 Stream 获取响应
final response = await client.request(request).first;

if (response.hasErrors) {
  print('发生错误:${response.errors}');
} else {
  final user = response.data?.user;
  print('用户:${user?.name}');
}

5. 发起变更

dart 复制代码
final mutationRequest = GRequest(
  operation: operations.UpdateUserName(
    (b) => b
      ..vars.id = 'user-1'
      ..vars.name = 'New Name',
  ),
);

final response = await client.request(mutationRequest).first;

6. 订阅响应式更新

由于 Ferry 基于流构建,你可以直接监听数据变化:

dart 复制代码
final userStream = client.request(request);

userStream.listen((response) {
  // 每当数据变化时自动触发
  buildUi(response);
});

相关链接

帮助我们改进文档

发现翻译问题或内容错误?请告诉我们。