加入我们,于10月8日至10日在纽约市,了解最新的GraphQL联邦和API平台工程提示、趋势和新闻。加入我们参加2024年纽约市的GraphQL峰会
文档
免费开始

10. 认证您的操作


在本节中,您将预订一次航班 🚀!预订航班需要向服务器进行认证,以便正确的人被送往太空!为此,因为Apollo Kotlin正在使用OkHttp 用于处理HTTP请求,你将使用一个OkHttp 拦截器 向你的 请求中添加头部。

添加拦截器

Apollo.kt 中,添加 AuthorizationInterceptor 类:

app/src/main/kotlin/com/example/rocketreserver/Apollo.kt
private class AuthorizationInterceptor() : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request().newBuilder()
.apply {
TokenRepository.getToken()?.let { token ->
addHeader("Authorization", token)
}
}
.build()
return chain.proceed(request)
}
}

此拦截器会向请求中添加一个 "Authorization: $token" HTTP头部,如果token非空。

使用拦截器

创建一个自定义 OkHttpClient,它将使用此拦截器并将其传递给 ApolloClient

app/src/main/kotlin/com/example/rocketreserver/Apollo.kt
val apolloClient = ApolloClient.Builder()
.serverUrl("https://apollo-fullstack-tutorial.herokuapp.com/graphql")
.okHttpClient(
OkHttpClient.Builder()
.addInterceptor(AuthorizationInterceptor())
.build()
)
.build()

添加“预订行程”和“取消行程”的变化

schema.graphqls 旁边添加一个 BookTrip.graphql 文件:

app/src/main/graphql/BookTrip.graphql
mutation BookTrip($id:ID!) {
bookTrips(launchIds: [$id]) {
success
message
}
}

注意,bookTrips字段接受一个列表,但此本身只接受一个

还要添加CancelTrip.graphql文件。此突变不使用列表:

app/src/main/graphql/CancelTrip.graphql
mutation CancelTrip($id:ID!) {
cancelTrip(launchId: $id) {
success
message
}
}

将突变连接到您的UI

返回LaunchDetails.kt,并将TODO替换为onBookButtonClick执行适当的突变,根据发射是否预定:

app/src/main/java/com/example/rocketreserver/LaunchDetails.kt
private suspend fun onBookButtonClick(launchId: String, isBooked: Boolean, navigateToLogin: () -> Unit): Boolean {
if (TokenRepository.getToken() == null) {
navigateToLogin()
return false
}
val mutation = if (isBooked) {
CancelTripMutation(id = launchId)
} else {
BookTripMutation(id = launchId)
}
val response = apolloClient.mutation(mutation).execute()
return when {
response.exception != null -> {
Log.w("LaunchDetails", "Failed to book/cancel trip", response.exception)
false
}
response.hasErrors() -> {
Log.w("LaunchDetails", "Failed to book/cancel trip: ${response.errors?.get(0)?.message}")
false
}
else -> true
}
}

现在回到LaunchDetails函数,声明一个协程作用域,以便调用onBookButtonClick。同时,让我们记住isBooked并相应地更改按钮的文本:

app/src/main/java/com/example/rocketreserver/LaunchDetails.kt
// Book button
val scope = rememberCoroutineScope()
var isBooked by remember { mutableStateOf(data.launch?.isBooked == true) }
Button(
modifier = Modifier
.padding(top = 32.dp)
.fillMaxWidth(),
onClick = {
scope.launch {
val ok = onBookButtonClick(
launchId = data.launch?.id ?: "",
isBooked = isBooked,
navigateToLogin = navigateToLogin
)
if (ok) {
isBooked = !isBooked
}
}
}
) {
Text(text = if (!isBooked) "Book now" else "Cancel booking")
}

我们还添加了一个加载指示器,并且在突变运行时防止按钮被点击:

app/src/main/java/com/example/rocketreserver/LaunchDetails.kt
// Book button
var loading by remember { mutableStateOf(false) }
val scope = rememberCoroutineScope()
var isBooked by remember { mutableStateOf(data.launch?.isBooked == true) }
Button(
modifier = Modifier
.padding(top = 32.dp)
.fillMaxWidth(),
enabled = !loading,
onClick = {
loading = true
scope.launch {
val ok = onBookButtonClick(
launchId = data.launch?.id ?: "",
isBooked = isBooked,
navigateToLogin = navigateToLogin
)
if (ok) {
isBooked = !isBooked
}
loading = false
}
}
) {
if (loading) {
SmallLoading()
} else {
Text(text = if (!isBooked) "Book now" else "Cancel booking")
}
}

预订您的旅行!

编译并运行您的应用程序。您现在可以预订和取消旅行!按钮将根据旅行是否已预订而更改。

在下一节中,您将编写您的第一个订阅并在有人预订航班时实时收到通知。

上一页
9. 编写您的第一个突变
下一页
11. 编写您的第一个订阅
评价文章评价在GitHub上编辑编辑论坛Discord

©2024Apollo Graph Inc.,即Apollo GraphQL。

隐私政策

公司