Skip to content
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

feat(android): add Apollo 4 docs #12729

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
209 changes: 209 additions & 0 deletions docs/platforms/android/integrations/apollo4/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
---
title: Apollo 4
caseStyle: camelCase
supportLevel: production
sdk: sentry.java.apollo-4
description: "Learn more about the Sentry Apollo 4 integration for the Android SDK."
categories:
- mobile
---

<Alert>

To be able to capture transactions, you'll need to first <PlatformLink to="/tracing/">set up tracing</PlatformLink>.

</Alert>

Sentry's Apollo 4 integration provides both the `SentryApollo4Interceptor` and the `SentryApollo4HttpInterceptor`, which create a span for each outgoing HTTP request executed with an [Apollo Kotlin](https://github.com/apollographql/apollo-kotlin) GraphQL client. The integration also provides extension functions on the `ApolloClient.Builder`.

## Install

Install the Apollo 4 integration:

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

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

## Configure With Extension

Add `Interceptors` to `ApolloClient.Builder` using `SentryApolloBuilderExtensions`:

```java
import com.apollographql.ApolloClient;
import io.sentry.apollo4.SentryApolloBuilderExtensionsKt;

ApolloClient apollo = SentryApolloBuilderExtensionsKt
.sentryTracing(new ApolloClient.Builder())
.serverUrl("https://your-api-host/")
.build();
```

```kotlin
import com.apollographql.ApolloClient
import io.sentry.apollo4.sentryTracing

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

## Manual Configuration

Because `HttpInterceptors` need to be added to the `NetworkTransport`, the `SentryInterceptors` need to be added manually if you're using a custom `NetworkTransport`:

```java
import com.apollographql.ApolloClient;
import com.apollographql.network.http.HttpNetworkTransport;
import io.sentry.apollo4.SentryApollo4HttpInterceptor;
import io.sentry.apollo4.SentryApollo4Interceptor;

ApolloClient apollo = new ApolloClient.Builder()
.networkTransport(
new HttpNetworkTransport.Builder()
.serverUrl("https://your-api-host/")
.addInterceptor(new SentryApollo4HttpInterceptor())
.build())
.addInterceptor(new SentryApollo4Interceptor())
.build();
```

```kotlin
import com.apollographql.ApolloClient
import io.sentry.apollo4.SentryApollo4HttpInterceptor
import io.sentry.apollo4.SentryApollo4Interceptor
import com.apollographql.network.http.HttpNetworkTransport

val apollo = ApolloClient.builder()
.networkTransport(
HttpNetworkTransport.Builder()
.serverUrl("https://apollo-fullstack-tutorial.herokuapp.com/graphql")
.addInterceptor(SentryApollo4HttpInterceptor())
.build()
)
.addInterceptor(SentryApollo4Interceptor())
.build()
```

## Modify or Drop Spans

Spans created around requests can be modified or dropped using `SentryApollo4HttpInterceptor.BeforeSpanCallback` passed to `SentryApollo4HttpInterceptor` or the `sentryTracing` extension function:

```java
import com.apollographql.ApolloClient;
import io.sentry.apollo4.SentryApolloBuilderExtensionsKt;

ApolloClient apollo = SentryApolloBuilderExtensionsKt.sentryTracing(
new ApolloClient.Builder(),
(span, request, response) -> {
if ("LaunchDetails".equals(span.getOperation())) {
span.setTag("tag-name", "tag-value");
}
return span;
})
.serverUrl("https://your-api-host/")
.build();
```

```kotlin
import com.apollographql.ApolloClient
import io.sentry.apollo4.sentryTracing

val apollo = ApolloClient.builder()
.serverUrl("https://apollo-fullstack-tutorial.herokuapp.com/graphql")
.sentryTracing { span, request, response ->
if ("LaunchDetails" == span.operation) {
span.setTag("tag-name", "tag-value")
}
span
}
.build()
```

## GraphQL Client Errors

This feature automatically captures GraphQL client errors (like bad operations and response codes) as error events and reports them to Sentry. The error event will contain the `request` and `response` data, including the `url`, `status_code`, and `data` (stringified `query`).

Sentry will group GraphQL client errors by the `operationName`, `operationType`, and `statusCode`, so that you can easily see the number of errors that happened for each.

Starting with SDK version `7.0.0`, GraphQL client error capturing is enabled by default. For prior versions of the SDK, this feature is opt-in and can be enabled by setting the `captureFailedRequests` option to `true`:

```kotlin
import com.apollographql.ApolloClient
import io.sentry.apollo4.sentryTracing

val apollo = ApolloClient.builder()
.serverUrl("https://your-api-host/")
.sentryTracing(captureFailedRequests = true)
.build()
```

By default, only GraphQL client errors with a response that includes the [errors](https://spec.graphql.org/October2021/#sec-Errors) array will be captured as error events.

GraphQL client errors from every target (`.*` regular expression) are automatically captured, but you can change this behavior by setting the `failedRequestTargets` option with either a regular expression or a plain `String`. A plain string must contain at least one of the items from the list. Plain strings don't have to be full matches, meaning the URL of a request is matched when it contains a string provided through the option.

```kotlin
import com.apollographql.ApolloClient
import io.sentry.apollo4.sentryTracing

val apollo = ApolloClient.builder()
.serverUrl("https://your-api-host/")
.sentryTracing(captureFailedRequests = true, failedRequestTargets = listOf("myapi.com"))
.build()
```

By default, error events won't contain `Headers` or `Cookies`, but you can change this behavior by setting the `sendDefaultPii` option to `true`:

```xml {filename:AndroidManifest.xml}
<application>
<meta-data android:name="io.sentry.send-default-pii" android:value="true" />
</application>
```

Error events will contain the raw bodies of GraphQL requests and responses, which may include sensitive data. To avoid this, parameterize your queries using the [variables](https://spec.graphql.org/October2021/#sec-Language.Variables) field. [Relay](/product/relay) will then run [PII Data Scrubbing](/product/relay/#pii-data-scrubbing), automatically transforming values into `[Filtered]`.

Alternatively, you can customize the event and scrub the data yourself.

### Customize or Drop the Error Event

To customize or drop the error event, you'll need to do a [manual initialization](/platforms/android/configuration/manual-init/#manual-initialization) of the Sentry Android SDK. The captured error event can then be customized or dropped with a `BeforeSendCallback`:

```kotlin
import io.sentry.android.core.SentryAndroid
import io.sentry.SentryOptions.BeforeSendCallback
import com.apollographql.api.http.HttpRequest
import com.apollographql.api.http.HttpResponse
import io.sentry.TypeCheckHint.APOLLO_REQUEST
import io.sentry.TypeCheckHint.APOLLO_RESPONSE

SentryAndroid.init(this) { options ->
// Add a callback that will be used before the event is sent to Sentry.
// With this callback, you can modify the event or, when returning null, also discard the event.
options.beforeSend = BeforeSendCallback { event, hint ->
val request = hint.getAs(APOLLO_REQUEST, HttpRequest::class.java)
val response = hint.getAs(APOLLO_RESPONSE, HttpResponse::class.java)

// customize or drop the event
event
}
}
```

### Automatically and Manually Captured GraphQL Client Errors

When `captureFailedRequests` is enabled, some GraphQL client libraries will throw unchecked exceptions, such as the `ApolloException` and its implementations. This means the error event will be captured by both the GraphQL client library and the Sentry Android SDK. To avoid this, we recommend identifying these errors and using the `Sentry.captureException` method instead of capturing them manually:

```kotlin
import io.sentry.Sentry
import com.apollographql.exception.ApolloException

try {
// If this API call returns the `errors` array, it will be captured as an error event by the `SentryApollo4HttpInterceptor`.
return apolloClient.query(LaunchDetailsQuery(launchId)).execute()
} catch (e: ApolloException) {
// Do not manually capture this exception to avoid duplicated error events.
// Sentry.captureException(e)
}
```
Loading