我在Android上尝试使用GitHub GraphQL API v4
Apollo GraphQL 客户端适用于安卓设备
Apollo-Android是一个符合GraphQL标准的客户端,它可以根据标准的GraphQL查询生成Java模型。
毋需开场白,直接开始。它会从GraphQL生成Java代码。通过使用这个库,我将介绍如何使用GitHub API v4的步骤。
开始之前
创建一个合适的Android项目,并导入所需的权限和库。
<uses-permission android:name="android.permission.INTERNET" />
在项目的build.gradle文件的dependencies中添加以下内容。
dependencies {
...
classpath 'com.apollographql.apollo:gradle-plugin:0.4.0'
}
在模块的 build.gradle 中添加以下内容(请确保 apollo 插件在 android 插件之下)。
apply plugin: 'com.android.application'
apply plugin: 'com.apollographql.android'
还增加了一个库,使得可以选择使用 RxJava2。
dependencies {
...
compile "io.reactivex.rxjava2:rxjava:2.1.1"
compile "io.reactivex.rxjava2:rxandroid:2.0.1"
compile "com.apollographql.apollo:apollo-rx2-support:0.4.0"
}
阿波羅利用的基本步驟
-
- 安装apollo-codegen
-
- 下载schema.json
-
- 使用GraphQL创建查询
-
- 生成Java代码
-
- 使用生成的代码
使用OkHttp进行身份验证
创建ApolloClient
调用方法
安装apollo-codegen
安装将GraphQL生成为Java的工具。此步骤仅在第一次需要执行。
npm install -g apollo-codegen
请务必使用”-g”命令进行安装。如果不进行全局安装,Android 项目将无法访问,因此无法生成代码。
如果没有安装npm,请安装Node.js。
2. 下载 schema.json 文件
在Apollo中生成代码需要包含详细的API描述的schema.json和定义实际查询的~.graphql文件。首先从GitHub下载schema.json。访问GitHub API的终端节点需要访问令牌,所以请按照以下步骤先获取访问令牌。
点击GitHub上的个人资料图片打开设置。选择左下角的个人访问令牌,会出现”生成新令牌”按钮,通过点击该按钮可以生成访问令牌。在这个示例中,使用的范围是用户和存储库,将用于获取用户数据和更新存储库的问题。
※这是限定个人使用的令牌,请注意使用方式。如果您在应用程序中实际使用,可通过OAuth轻松获取访问令牌。
当准备好访问令牌后,使用apollo-codegen下载schema.json。
apollo-codegen download-schema https://api.github.com/graphql --output schema.json --header "Authorization: Bearer <access-token>"
1MB 大小的 schema.json 文件会下载到执行命令的目录中(稍后将用于生成 Java 代码)。
3. 利用 GraphQL 创建查询
我现在要创建一个简单的查询,只是提取用户信息。这个查询是基于打开 GitHub 的 GraphiQL 时出现的示例查询,并添加了一些项目。Apollo不支持省略操作和查询名称的GraphQL格式,因此需要提供操作名称和适当的查询名称。由于这是一个查询操作,所以需要使用`query`关键字,并给它命名为`Viewer`。生成的代码的类名将是查询名称+操作名称,所以将是`ViewerQuery`。
query Viewer {
viewer {
login
bio
avatarUrl
company
location
}
}
为了确认一下,可以在 GraphiQL 中尝试执行查询,结果如下。
请将此查询保存在名为 API.graphql 的文件中,以普通文本格式保存(文件名中的 API 部分可以是任何名称,但必须将扩展名设置为 .graphql)。
4. 生成代碼
从上一步创建的schema.json和API.graphql中生成Java代码。在预先创建的项目的src/main目录下创建一个名为graphql的文件夹。在其中创建与应用程序包名称对应的目录结构,并将schema.json和API.graphql放置其中。生成的类将以此目录结构为基础生成包名。在这里,我们将在应用程序的根包中添加一个名为api的包结构。将Android Studio的视图切换为Project Files并展开,就会呈现如下的样子。
在这个状态下进行应用程序的构建,Apollo插件会为您生成代码。生成的代码位于build/generated目录下。
使用生成的代码
您可以通过ApolloClient调用生成的代码。与下载schema.json时相同,ApolloClient需要提供身份验证处理,因为它需要一个bearer token。由于ApolloClient可以将OkHttp用作HTTP客户端,因此您可以使用OkHttp的Authenticator(或Interceptor)来进行身份验证。
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.authenticator(new Authenticator() {
@Override
public Request authenticate(Route route, okhttp3.Response response) throws IOException {
return response.request().newBuilder()
.addHeader("Authorization", "Bearer <access-token>")
.build();
}
}).build();
创建 ApolloClient。将先前创建的 okHttpClient 和 API 的终点传递给它。
ApolloClient apolloClient = ApolloClient.builder()
.okHttpClient(okHttpClient)
.serverUrl("https://api.github.com/graphql")
.build();
用之前生成的代码向 GitHub 发送请求。
Rx2Apollo.from(apolloClient.query(new ViewerQuery()).watcher())
.subscribeOn(Schedulers.io())
.subscribe(new DisposableObserver<Response<ViewerQuery.Data>>() {
@Override
public void onNext(Response<ViewerQuery.Data> dataResponse) {
android.util.Log.d("graphql", "" + dataResponse.data());
}
@Override
public void onError(Throwable e) {
android.util.Log.d("graphql", "" + e);
}
@Override
public void onComplete() {
// no-op
}
});
当成功时,会返回类似以下响应(实际响应为JSON文本,它尚未包装在生成的代码之前)。
D/graphql: Data{viewer=Viewer{__typename=User, login=mightyfrog, name=, company=, avatarUrl=https://avatars0.githubusercontent.com/u/208494?v=4, bio=Android developer @DeNA, createdAt=2010-02-22T16:04:03Z}}
试着创建一个接受参数的查询
我试图通过指定用户名来获取用户数据。查询的形式如下。
{
user(login: "mightyfrog") {
id
login
bio
avatarUrl
company
createdAt
}
}
将这个转换为变量可用的格式。
query User($login: String!) {
user(login: $login) {
id
login
bio
avatarUrl
company
createdAt
}
}
在 GraphiQL 中进行测试。变量的值会写在 QUERY VARIABLES 中发送。
{
"login": "mightyfrog"
}
将经过修改以使用变量的查询添加到之前创建的 API.graphql 中。
query Viewer {
viewer {
login
name
company
avatarUrl
bio
createdAt
}
}
query User($login: String!) {
user(login: $login) {
id
login
bio
avatarUrl
company
createdAt
}
}
当项目进行构建时,将生成一个新的UserQuery类,因此我们将尝试使用它。构造函数现在接受参数。
Rx2Apollo.from(apolloClient.query(new UserQuery("mightyfrog")).watcher())
.subscribeOn(Schedulers.io())
.subscribe(new DisposableObserver<Response<UserQuery.Data>>() {
@Override
public void onNext(Response<UserQuery.Data> dataResponse) {
android.util.Log.d("graphql", "" + dataResponse.data());
}
@Override
public void onError(Throwable e) {
android.util.Log.d("graphql", "" + e);
}
@Override
public void onComplete() {
// no-op
}
});
会返回这样的结果。
D/graphql: Data{user=User1{__typename=User, id=MDQ6VXNlcjIwODQ5NA==, login=mightyfrog, bio=Android developer @DeNA, avatarUrl=https://avatars0.githubusercontent.com/u/208494?v=4, company=, createdAt=2010-02-22T16:04:03Z}}
试着更新数据
我們將在 GitHub 上 The Octocat 帳戶的 Hello-World 倉庫的 issue349 上添加表情符號反應。我們將在 API.graphql 中添加以下內容並生成程式碼。
mutation AddReactionToIssue($subjectId: ID!, $content: ReactionContent!) {
addReaction(input:{subjectId: $subjectId,content: $content}) {
reaction {
content
}
subject {
id
}
}
}
在GraphiQL中尝试时会是这样的感觉。
使用以下的查询可以获取到问题号,在您自己的代码库中也可以尝试一下。
query FindIssueID {
repository(owner: "octocat", name: "Hello-World") {
issue(number: 349) {
id
}
}
}
使用构建生成的代码进行执行。
Rx2Apollo.from(apolloClient.mutate(new AddReactionToIssueMutation("MDU6SXNzdWUyMzEzOTE1NTE=", ReactionContent.HEART)))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new DisposableObserver<Response<AddReactionToIssueMutation.Data>>() {
@Override
public void onNext(Response<AddReactionToIssueMutation.Data> dataResponse) {
mTextView.setText("" + dataResponse.data());
android.util.Log.d("graphql", "" + dataResponse.data());
}
@Override
public void onError(Throwable e) {
android.util.Log.d("graphql", "" + e);
}
@Override
public void onComplete() {
// no-op
}
});
回应如下所示。
D/graphql: Data{addReaction=AddReaction{__typename=AddReactionPayload, reaction=Reaction{__typename=Reaction, content=HEART}, subject=Subject{__typename=Issue, id=MDU6SXNzdWUyMzEzOTE1NTE=}}}
更新也包括 issue349 的反应。
它結束了
Apollo GraphQL Client for Android是一个还只发布了大约三个月的库,可以说处理起来有些麻烦,性能方面也不明确,但可以完成类似这个演示的任务。尽管本次没有使用,但它也支持使用别名、片段和指令等更复杂的查询。还有提供Kotlin插件,并且未来还计划支持Proguard和Auto-Value,使这个库更加值得期待。
如果你已经读到这里,那么你一定对GraphQL本身也产生了兴趣。如果你想了解更多关于GraphQL方面的知识,我推荐你参考GitHub的GraphQL概述和graphql.org的GraphQL简介。
以下是我們原本打算在 shibuya.apk #17 上使用的示範 GraphQL API 伺服器:
https://github.com/mightyfrog/Simple-GraphQL-API-Server
请参考以下资料
请参考提供的参考资料
以下资料可供参考
请参考以下资料选项
请参考下列资料
-
- http://graphql.org/
-
- https://developer.github.com/v4/
-
- https://github.com/apollographql
-
- https://github.com/chentsulin/awesome-graphql
-
- https://code.facebook.com/posts/1691455094417024
-
- https://facebook.github.io/react/blog/2015/05/01/graphql-introduction.html
- https://githubengineering.com/the-github-graphql-api/