从10月8日至10日加入我们,在纽约市学习关于GraphQL联盟和API平台工程的最新技巧、趋势和新闻。加入我们,参加2024年纽约市GraphQL峰会
文档
免费开始
您正在查看此软件的早期版本文档。 切换到最新稳定版本。

11. 编写第一个订阅


在本节中,您将使用订阅来接收有关有人预订航班的通知 🚀订阅 允许您在服务器上的事件发生时实时接收通知。下面是关于全栈后端和它的支持的详细描述...全栈后端 支持基于 WebSockets 的订阅。

编写您的订阅

打开您的 沙盒,点击左下角的模式标签。除了 查询变更,您还会看到第三种操作类型 订阅。单击 订阅 可以看到 tripsBooked

The definition of tripsBooked in the schema

订阅不需要任何 ,并返回一个名为 tripsBooked 的单值。由于您可以一次性预订多个行程, tripsBooked 是一个 Int。它将包含一次预订的行程数,或者如果行程已取消,则为 -1。

单击 tripsBooked 左侧的播放按钮来在浏览器中打开 订阅。打开一个新标签,然后检查 tripsBooked 按钮以将 订阅 添加:

The initial definition of the TripsBooked subscription

再次,重命名您的订阅以便更容易找到:

The subscription after rename

点击提交按钮,您的订阅将开始监听事件。您可以通过底部左边的面板弹出了解其是否正在运行,那里将接收订阅数据:

The UI showing that it's listening for subscription updates

测试您的订阅

在资源管理器中打开一个新的标签页。在这个新的标签页中,添加类似于第9步的预订旅行代码,但是使用硬编码的ID:

mutation BookTrip {
bookTrips(launchIds: ["93"]){
message
}
}

不要忘记包含身份验证头。在添加操作的下方的沙箱资源管理器面板中,有一个Headers部分:

Adding a login token to explorer

点击提交操作按钮。如果一切顺利,那么您已经预订了旅行!在右边面板的顶部,您将看到您BookTrip的成功JSON,下面是其更新后的JSONTripsBooked订阅:

Subscription success in Explorer

继续预订和/或取消旅行,您将在实时看到的订阅面板中收到事件。经过一段时间后,服务器可能会关闭连接,您需要重新启动订阅来继续接收事件。

将订阅添加到项目中

现在您的订阅已工作,将其添加到项目中。在schema.graphqls和您的其他文件旁边创建名为TripsBooked.graphql的文件,并将订阅的内容粘贴进去。这个过程与您进行的查询和突变操作类似:

app/src/main/graphql/TripsBooked.graphql
subscription TripsBooked {
tripsBooked
}

配置ApolloClient以使用订阅

本教程使用 subscriptions-transport-ws 协议进行订阅。关于更多选项,如最新的 graphql-ws 或 Appsync,请参见 GraphQL over WebSocket protocols

Apollo.kt 中,为您的 ApolloClient 配置 webSocketServerUrl

Apollo.kt
val apolloClient = ApolloClient.Builder()
.serverUrl("https://apollo-fullstack-tutorial.herokuapp.com/graphql")
.webSocketServerUrl("wss://apollo-fullstack-tutorial.herokuapp.com/graphql")
.okHttpClient(...)
.build()

wss:// 是 WebSocket 协议。

在预订/取消行程时显示 SnackBar

MainActivity 中,注册您的订阅并保留返回的协程 Flow 的引用。

使用 collectAsState 获取 Flow 的最新值作为状态。当 Flow 发射值时,它将被存储在 tripBookedResponse 中,并触发 UI 的重新 ,因为 LaunchedEffect 依赖于它。

MainActivity.kt
RocketReserverTheme {
val tripBookedFlow = remember { apolloClient.subscription(TripsBookedSubscription()).toFlow() }
val tripBookedResponse: ApolloResponse<TripsBookedSubscription.Data>? by tripBookedFlow.collectAsState(initial = null)
LaunchedEffect(tripBookedResponse) {
if (tripBookedResponse == null) return@LaunchedEffect
val message = when (tripBookedResponse!!.data?.tripsBooked) {
null -> "Subscription error"
-1 -> "Trip cancelled"
else -> "Trip booked! 🚀"
}
// TODO use the message
}

现在让我们在一个 Material SnackBar 中显示消息。

为此,您需要创建一个 SnackbarHostState 并调用它的 showSnackbar。别忘了将其传递给下面的 Scaffold

MainActivity.kt
val snackbarHostState = remember { SnackbarHostState() }
val tripBookedFlow = (...)
(...)
val message = (...)
snackbarHostState.showSnackbar(
message = message,
duration = SnackbarDuration.Short
)
}
Scaffold(
topBar = { TopAppBar({ Text(stringResource(R.string.app_name)) }) },
snackbarHost = { SnackbarHost(snackbarHostState) },
) { paddingValues ->

处理错误

与查询和mutations类似,当连接丢失或发生任何其他协议错误时,订阅将抛出错误。要处理这些情况,您可以配置客户端使用 webSocketReopenWhen 函数重试订阅。返回 true 进行重试,false 停止。为了避免过于频繁的重试,您可以使用 attempt 参数延迟重试:

Apollo.kt
val apolloClient = ApolloClient.Builder()
(...)
.webSocketReopenWhen { throwable, attempt ->
Log.d("Apollo", "WebSocket got disconnected, reopening after a delay", throwable)
delay(attempt * 1000)
true
}

测试您的代码

构建并运行您的应用,然后返回到沙箱资源管理器,并选择设置 BookTrip 变异的标签页。在应用打开时预订新行程,您应该会看到一个 🚀 快速回复栏

A trip has been booked

教程结束,恭喜! 🎉

更多资源

使用本文档的其余部分了解更多高级主题,如 缓存Gradle 配置

请通过以下方式提问:在我们的 GitHub 仓库中创建一个问题加入社区在 KotlinLang Slack 的频道上停留(在此获取邀请)。

如果您想更深入地了解并查看 GraphQL 在实际应用中的使用,可以查看这些使用 的开源项目:

上一页
10. 验证您的操作
下一页
文件类型
评分文章评分在GitHub上编辑编辑论坛Discord

©2024Apollo Graph Inc.,以Apollo GraphQL的名义。

隐私政策

公司