Skip to content

Java: document Apollo Android integration #4202

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Oct 4, 2021
Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
---
title: Apollo Integration
sidebar_order: 20
description: "Learn how to capture the performance of Apollo GraphQL client."
---

<Note>

Capturing transactions requires that you first <PlatformLink to="/performance/">set up performance monitoring</PlatformLink> if you haven't already.

</Note>

Sentry Apollo integration provides the `SentryApolloInterceptor`, which creates a span for each outgoing HTTP request executed with an [Apollo Android](https://github.com/apollographql/apollo-android) GraphQL client.

## Install

```groovy {tabTitle:Gradle}
implementation 'io.sentry:sentry-apollo:{{ packages.version('sentry.java.apollo', '5.2.0') }}'
```

For other dependency managers, see the [central Maven repository](https://search.maven.org/artifact/io.sentry/sentry-apollo).

## Configure

Add `SentryApolloInterceptor` to Apollo builder:

```java
import com.apollographql.apollo.ApolloClient;
import io.sentry.apollo.SentryApolloInterceptor;

ApolloClient apollo = ApolloClient.builder()
.serverUrl("https://your-api-host/")
.addApplicationInterceptor(new SentryApolloInterceptor())
.build();
```

```kotlin
import com.apollographql.apollo.ApolloClient
import io.sentry.apollo.SentryApolloInterceptor

val apollo = ApolloClient.builder()
.serverUrl("https://your-api-host/")
.addApplicationInterceptor(SentryApolloInterceptor())
.build()
```

## Modify or Drop Spans

Spans created around requests can be modified or dropped using `SentryApolloInterceptor.BeforeSpanCallback` passed to `SentryApolloInterceptor`:

```java
import com.apollographql.apollo.ApolloClient;
import io.sentry.apollo.SentryApolloInterceptor;

ApolloClient apollo = ApolloClient.builder()
.serverUrl("https://your-api-host/")
.addApplicationInterceptor(new SentryApolloInterceptor(
(span, request, response) -> {
if ("aQuery".equals(request.operation.name().name())) {
span.setTag("tag-name", "tag-value");
}
return span;
}
))
.build();
```

```kotlin
import com.apollographql.apollo.ApolloClient
import com.apollographql.apollo.interceptor.ApolloInterceptor.InterceptorRequest
import com.apollographql.apollo.interceptor.ApolloInterceptor.InterceptorResponse
import io.sentry.ISpan
import io.sentry.apollo.SentryApolloInterceptor
import io.sentry.apollo.SentryApolloInterceptor.BeforeSpanCallback

val apollo = ApolloClient.builder()
.serverUrl("https://your-api-host/")
.addApplicationInterceptor(
SentryApolloInterceptor(object : BeforeSpanCallback {
override fun execute(span: ISpan, request: InterceptorRequest, response: InterceptorResponse?): ISpan {
if ("aQuery" == request.operation.name().name()) {
span.setTag("tag-key", "tag-value")
}
return span
}
})
)
.build()
```
138 changes: 138 additions & 0 deletions src/platforms/java/performance/instrumentation/apollo.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
---
title: Apollo Integration
sidebar_order: 20
description: "Learn how to capture the performance of Apollo GraphQL client."
---

<Note>

Capturing transactions requires that you first <PlatformLink to="/performance/">set up performance monitoring</PlatformLink> if you haven't already.

</Note>

Sentry Apollo integration provides the `SentryApolloInterceptor`, which creates a span for each outgoing HTTP request executed with an [Apollo Android](https://github.com/apollographql/apollo-android) GraphQL client.

## Install

```xml {tabTitle:Maven}
<dependency>
<groupId>io.sentry</groupId>
<artifactId>sentry-apollo</artifactId>
<version>{{ packages.version('sentry.java.apollo', '5.2.0') }}</version>
</dependency>
```

```groovy {tabTitle:Gradle}
implementation 'io.sentry:sentry-apollo:{{ packages.version('sentry.java.apollo', '5.2.0') }}'
```

```scala {tabTitle: SBT}
libraryDependencies += "io.sentry" % "sentry-apollo" % "{{ packages.version('sentry.java.apollo', '5.2.0') }}"
```

For other dependency managers, see the [central Maven repository](https://search.maven.org/artifact/io.sentry/sentry-apollo).

## Configure

Add `SentryApolloInterceptor` to Apollo builder:

```java
import com.apollographql.apollo.ApolloClient;
import io.sentry.apollo.SentryApolloInterceptor;

ApolloClient apollo = ApolloClient.builder()
.serverUrl("https://your-api-host/")
.addApplicationInterceptor(new SentryApolloInterceptor())
.build();
```

```kotlin
import com.apollographql.apollo.ApolloClient
import io.sentry.apollo.SentryApolloInterceptor

val apollo = ApolloClient.builder()
.serverUrl("https://your-api-host/")
.addApplicationInterceptor(SentryApolloInterceptor())
.build()
```

Apollo Android is built with Kotlin coroutines. This means that `SentryApolloInterceptor` can be used with Java using only Global Hub Mode (single Hub used by all threads), with Kotlin using single Hub mode, or with <PlatformLink to="/enriching-events/scopes/#kotlin-coroutines">Sentry's coroutines support</PlatformLink>.

## Using With Java

Configure Global Hub Mode:

```java
import io.sentry.Sentry;

Sentry.init(options -> {
..
}, true)
```

<Note>
In Global Hub Mode, all threads use the same Hub.
</Note>

## Using With Kotlin Coroutines

To make sure that a coroutine has access to the correct Sentry context, an instance of `SentryContext` must be provided when launching a coroutine.

```kotlin
import io.sentry.kotlin.SentryContext
import com.apollographql.apollo.exception.ApolloException
import kotlinx.coroutines.launch

launch(SentryContext()) {
val response = try {
apollo.query(..).toDeferred().await()
} catch (e: ApolloException) {
// handle protocol errors
return@launch
}
}
```

## Modify or Drop Spans

Spans created around requests can be modified or dropped using `SentryApolloInterceptor.BeforeSpanCallback` passed to `SentryApolloInterceptor`:

```java
import com.apollographql.apollo.ApolloClient;
import io.sentry.apollo.SentryApolloInterceptor;

ApolloClient apollo = ApolloClient.builder()
.serverUrl("https://your-api-host/")
.addApplicationInterceptor(new SentryApolloInterceptor(
(span, request, response) -> {
if ("aQuery".equals(request.operation.name().name())) {
span.setTag("tag-name", "tag-value");
}
return span;
}
))
.build();
```

```kotlin
import com.apollographql.apollo.ApolloClient
import com.apollographql.apollo.interceptor.ApolloInterceptor.InterceptorRequest
import com.apollographql.apollo.interceptor.ApolloInterceptor.InterceptorResponse
import io.sentry.ISpan
import io.sentry.apollo.SentryApolloInterceptor
import io.sentry.apollo.SentryApolloInterceptor.BeforeSpanCallback

val apollo = ApolloClient.builder()
.serverUrl("https://your-api-host/")
.addApplicationInterceptor(
SentryApolloInterceptor(object : BeforeSpanCallback {
override fun execute(span: ISpan, request: InterceptorRequest, response: InterceptorResponse?): ISpan {
if ("aQuery" == request.operation.name().name()) {
span.setTag("tag-key", "tag-value")
}
return span
}
})
)
.build()
```