Apollo Integration

How to use the DataDome SDK with the Apollo Client for GraphQL

Version License Platform

If your api is a GraphQL api, the chances are that you are using Apollo SDK. If so, we have a dedicated framework called DataDomeApollo designed to ease the DataDome SDK integration.

To install the plugin, use the following Cocoapods instruction:

pod "DataDomeApollo"

We use the Interceptor pattern built in the Apollo SDK to make sure we intercept all requests and protect them. The following is the init of the DataDome Interceptor

import DataDomeApollo

let interceptor = DataDomeResponseInterceptor()

The interceptor could be used then in your pipeline. It will intercept all requests, catch requests blocked by DataDome, display the captcha and eventually retry the request automatically once the captcha is resolved.

Important
The order in defining the interceptors is important in Apollo. Make sure the DataDome response Interceptor is the first interceptor after the NetworkFetchInterceptor.

Alternatively, you can use the DataDomeInterceptorProvider which is a pre-built sequence of interceptors ready to be used by your app. This provider is providing the same interceptors as the Legacy Interceptor provider. You can customise the interceptors to be added in the provider or use the default set.

private(set) lazy var apollo: ApolloClient = {
        // Create your own store needed to init the DataDomeInterceptor provider
        let cache = InMemoryNormalizedCache()
        let store = ApolloStore(cache: cache)
        
        // Use DataDomeURLSessionClient to enable updating the user-agent
        let client = DataDomeURLSessionClient()
        
        // Create the DataDome Interceptor Provider
        let provider = DataDomeInterceptorProvider(store: store, client: client)
        
        // Create your GraphQL URL
        guard let url = URL(string: "YOUR_ENDPOINT") else {
            fatalError("Unable to create url")
        }
        
        let requestChainTransport = RequestChainNetworkTransport(interceptorProvider: provider,
                                                                 endpointURL: url)
        
        // Create the client with the request chain transport
        return ApolloClient(networkTransport: requestChainTransport,
                            store: store)
    }()

In the above exemple we used the default configuration of DataDomeInterceptorProvider. You can specify custom interceptors using the following init method

/// Creates an interceptor provider with a setup instance of DataDome
    /// - Parameters:
    ///   - store: The apollo store
    ///   - client: The URLSession client
    ///   - preFetchInterceptors: The list of interceptors to go before the fetch operation
    ///   - fetchInterceptor: The fetch operation
    ///   - postFetchInterceptors: The list of interceptors to go after the fetch operation
    public init(store: ApolloStore,
                client: URLSessionClient,
                preFetchInterceptors: [ApolloInterceptor] = [],
                fetchInterceptor: ApolloInterceptor? = nil,
                postFetchInterceptors: [ApolloInterceptor] = [])

preFetchInterceptors is a set of interceptors to be added before firing the request. By default we add:

  • CacheReadInterceptor

fetchInterceptor is the interceptor that will execute the request. By default, we use:

  • NetworkFetchInterceptor

The DataDomeResponseInterceptor is then added to the chain just after the fetch interceptor.

postFetchInterceptors is a set of interceptors to be added after the fetch interceptor. By default we add:

  • ResponseCodeInterceptor
  • JSONResponseParsingInterceptor
  • AutomaticPersistedQueryInterceptor
  • CacheWriteInterceptor