[译] Hello Apollo: 创建一个使用 GraphQL 的 Android App

4,273 阅读5分钟

如果你是一个移动应用开发人员,你一定明白更快的API和更快的应用程序的重要性。特别是在数据流量比较贵的国家,只获取所需的数据变得尤为重要。

但是,API是为多种客户端设计的,每种客户端都有不同的要求,大多数情况下你会发现这些API都没有针对移动应用进行优化。这就是像GraphQL这样的新技术可以提供帮助的地方。

GraphQL是一种针对API的查询语言,它能让客户端精确地获得他们需要的数据。如果你还不了解GraphQL,可以通过以下链接查看更多内容。graphql.org/.

GraphQL on Android

让我们来看看如何在安卓平台上使用GraphQL API。尽管网上有很多网络请求的第三方库,但是目前为止安卓平台上只有一个GraphQL库:Apollo.

Apollo Android是一个很棒的GraphQL库,可以让使用GraphQL API变得更容易。它有两个主要的组件:

  • Apollo代码生成(Apollo Codegen)。这个组件是一个能像ButterKnife一样生成代码的gradle插件,apollo codegen在编译时从标准graphql查询生成Java model。
  • 网络和缓存(Networking/Caching)。Apollo Android的另一个组件是网络和缓存部分,它负责与你的GraphQL API进行所有的网络通信,将返回的数据解析成正确的model,使你能够将动态数据传递给你的GraphQL查询和响应缓存。

Hello World

现在我们知道什么是GraphQL,以及Apollo Android的工作原理。接下来让我们看看如何将Apollo集成到我们的安卓应用里面吧。

如果你还没有现成的项目就先创建一个空的安卓项目。在项目级的build.gradle文件里添加这一行:

classpath 'com.apollographql.apollo:gradle-plugin:0.3.2'

这一行应该放在com.android.tools.之后。现在打开应用程序的build.gradle文件,并在上面添加这一行

apply plugin: 'com.apollographql.android'

这一行应该在com.android.application下面。如果你想在你的Kotlin项目中使用Apollo,请将 Apollo 插件添加在 Kotlin 插件之前。有了这两个依赖,我们就将 Apollo 添加到我们的项目里了。

代码生成(Codegen)

Apollo 接收你的GraphQL请求和schema文件,并从中生成Java类。让我们研究一下它是如何工作的。

  • src/main下创建一个与你的java/res文件夹相同级别的文件夹。你可以给这个文件夹取任意名字,我把它命名为graphql

  • 在这个文件夹下添加 schema.json 文件。Schema.json 是用来描述你的 GraphQL API、所有字段和输入参数等信息的文件。这里有一个示例 schema 文件。

  • 在同一个文件夹里添加扩展名为 .graphql 的 GraphQL 查询(query)文件,这些查询会被 Apollo codegen 用来生成返回数据的数据结构。这里有一个示例 GraphQL 文件。

添加完 schema 文件和 .graphql 文件之后,重新build一下项目。Apollo 会解析这些查询(query)和模式(schema)并为你生成代码。当build完成之后,你可以去 app/build/generated/source/apollo 文件夹下查看生成的文件。

连线

现在我们已经添加了 Apollo 依赖关系,而且生成了代码, 接下来让我们连起一切,创建我们的第一个 GraphQL 网络请求。

在这个示例应用里,我们将使用 GitHub 的一个示例 GraphQL API :githunt-api.herokuapp.com/graphql

Apollo使用OkHTTP作为网络客户端,如果你已经熟悉了OkHttp,你就知道我们可以使用OkHttp 添加任何headers 和 interceptors

添加需要的请求头信息

  OkHttpClient okHttpClient = new OkHttpClient.Builder()
      .addInterceptor(logging)
      .build();

如果你想启用缓存,apollo 支持3级缓存,可以通过这个链接了解更多关于缓存的信息:github.com/apollograph…。如果你决定使用缓存,你还需要添加以下依赖关系。

compile "com.apollographql.apollo:apollo-android-support:0.3.2"

现在我们有了OkHttp Client和Cache,我们可以创建Apollo client对象了。

apolloClient = ApolloClient.*builder*()
        .serverUrl(*BASE_URL*)
        .okHttpClient(okHttpClient)
        .normalizedCache(normalizedCacheFactory, cacheKeyResolver)
        .build();

缓存的部分是可选的,一旦创建了Apollo client,你所有的网络请求都可以使用同一个 client。

第一个 GraphQL 请求

在我们的示例APP里面,Apollo 从我们的示例 .graphql 文件生成FeedQuery 类。我们使用这个类进行网络调用,使用我们新创建的apolloClient对象。

创建请求并传递所有参数

FeedQuery feedQuery = FeedQuery.*builder*()
        .limit(*FEED_SIZE*)
        .type(FeedType.*HOT*)
        .build();

Limit 和 Type是我们graphQL 查询中的动态参数,Apollo自动为这些参数创建setters方法,让我们能够从java代码里面传递这些参数。

创建 ApolloCall

ApolloCall<FeedQuery.Data> githuntFeedCall = apolloClient
                                             .query(feedQuery);

Apollo支持普通的回调RxJava。示例程序里面有两个API,一个通过普通回调来使用,一个是通过RxJava。这篇文章里面,我们看看回调方式是如何工作的。

githuntFeedCall.enqueue(new ApolloCall.Callback<FeedQuery.Data>() {
    @Override
    public void onResponse(@Nonnull Response<FeedQuery.Data> response) {
        FeedQuery.Data data = response.data();
    }

    @Override
    public void onFailure(@Nonnull ApolloException e) {

    }
});

使用普通的回调方法,你所需要做的就是在调用enqueue函数的时候传入ApolloCall.Callback回调,类似于Retrofit的风格。

现在你已经成功地在你的安卓应用里使用了第一个GraphQL API。

GraphQL功能强大,而且可以很好的替代基于REST的API。如果你正在处理复杂的API,而且它支持GraphQL的话,你可以通过切换到GraphQL 来简化你的应用。

这里有一个完整的示例程序github.com/apollograph…。但是Apollo的示例APP添加了所有项目级别的依赖关系,而且不能很好的工作。

所以我修改了示例app,并且删除了所有项目级别的依赖关系,你可以从以下链接找到这个使用Apollo和GraphQL 的完整有效的APP。github.com/pranayairan…