如何在Flutter中使用GraphQL

什么是GraphQL

这篇文章主要是看一下如何在Flutter项目中使用GraphQL,如果不清楚GraphQL是什么,建议先看下官网对其介绍:

https://graphql.org/
https://www.howtographql.com

GraphQL体验

先介绍一个免费操作GraphQL语法的网站:

https://countries.trevorblades.com/

打开此链接,默认显示如下页面:

从图中也能看出,网站分3部分

  1. 左边方格中可以输入GraphQL的query语句

  2. 当点击屏幕中间的运行按钮后,右边方格中会显示查询的结果

  3. 网站最右方是一个DOCS按钮,可以点击查看具体的参数文档

先点击DOCS,看下具体可以查询那些参数如下

可以看出,在这个GraphQL Server中,我们可以查询 continentscontinent 、Countries 、Country 等多个不同的model。

我用查询Countries为例, 使用的查询语句为:

query Countries {
  // 查询Countries model
  countries {
    // 并要求server返回带code、name、currency、emoji这4个参数的结果
    code
    name
    currency
    emoji
}

具体查询结果显示如下:

解释一下:因为我只在 query 语句中传入了 code、name、currency、emoji这四个参数,所以Server端只返回给我这4个参数的结果result。你可以试着传入一些其它参数,看一下返回结果是否会有变化。

Flutter中使用GraphQL

最后我们看下这篇文章的主题,如如何在Flutter中使用GraphQL。要在Flutter项目中使用GraphQL,我们需要使用一个库:graphql_flutter

具体实现步骤如下:

1 先在pubspec.yaml中添加依赖

2 构建HttpLink以及ValueNotifier

void main() => runApp(MyApp());


class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // HttpLink表示是往哪一个GraphQL Server发送query语句
    final HttpLink httpLink =
    HttpLink(uri: 'https://countries.trevorblades.com/');
    // 创建ValueNotifier,并传入HttpLink。在ValueNotifier中还可以自定义网络请求缓存策略
    final ValueNotifier<GraphQLClient> client = ValueNotifier<GraphQLClient>(
      GraphQLClient(
        link: httpLink as Link,
        cache: OptimisticCache(
          dataIdFromObject: typenameDataIdFromObject,
        ),
      ),
    );
    。。。
  }
}

3 创建GraphQLProvider

创建好 ValueNotifier 之后,我们就可以创建 GraphQLProvider 这一个widget了。需要在 GraphQLProvider 中传入刚才创建的notifier,以及需要展示的child widget。

完整代码如下:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    /// HttpLink - A system of modular components for GraphQL networking.
    final HttpLink httpLink =
    HttpLink(uri: 'https://countries.trevorblades.com/');


    final ValueNotifier<GraphQLClient> client = ValueNotifier<GraphQLClient>(
      GraphQLClient(
        link: httpLink as Link,
        cache: OptimisticCache(
          dataIdFromObject: typenameDataIdFromObject,
        ),
      ),
    );


    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: GraphQLProvider(
        child: CountryListView(),
        client: client,
      ),
    );
  }
}

可以看出,我们最后展示的是CountryListView这一个widget。而在CountryListView这个widget中,我们会调用graphql_flutter提供的 Query widget来发送GraphQL请求,并根据返回结果构建一个ListView组件,具体代码如下:

country_list.dart

import 'package:flutter/material.dart';
import 'package:graphql_flutter/graphql_flutter.dart';


class CountryListView extends StatelessWidget {
  final String query = '''
                      query Countries {
                          countries {
                            code
                            name
                            currency
                            emoji
                          }
                      }
                  ''';


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('List of Countries'),
      ),
      body: Query(
        options: QueryOptions(document: query),
        builder: (QueryResult result, {VoidCallback refetch, FetchMore fetchMore }) {
          if (result.loading) {
            return Center(child: CircularProgressIndicator());
          }


          if (result.data == null) {
            return Center(child: Text('Countries not found.'));
          }


          return _countriesView(result);
        },
      ),
    );
  }


  ListView _countriesView(QueryResult result) {
    final countryList = result.data['countries'];
    return ListView.separated(
      itemCount: countryList.length,
      itemBuilder: (context, index) {
        return ListTile(
          title: Text(countryList[index]['name']),
          subtitle: Text('Currency: ${countryList[index]['currency']}'),
          leading: Text(countryList[index]['emoji']),
          onTap: () {
            final snackBar = SnackBar(
                content:
                Text('Selected Country: ${countryList[index]['name']}'));
            Scaffold.of(context).showSnackBar(snackBar);
          },
        );
      },
      separatorBuilder: (context, index) {
        return Divider();
      },
    );
  }
}

其中,上面例子中的 query 字符串,就是我们在网站演示所使用的查询语句。最后运行效果如下:

总结

这篇文章介绍了如何在Flutter项目中简单快速的使用GraphQL。并实现了一个简单的Demo。但是上面显示Countries List的Demo有一个比较明显的问题,就是UI和数据严重绑定在一起,导致代码耦合性很高。

在实际的公司项目中,我们一般会将数据和UI进行分离,而常用的做法就是将GraphQL的 ValueNotifier<GraphQLClient> client 封装到Bloc中,然后在Widget中直接跟Bloc进行交互操作。网络上已经有大量介绍Bloc的文章,这里就不再赘述了。

最后安利一个Flutter交流群

为了屏蔽各种广告,目前微信群只开放了邀请加入的方式:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值