Connect SDK

The sdk/connect library provides an idiomatic approach to interfacing with the HxDR GraphQL API. It simplifies the complexities involved in error handling, managing streaming responses for @live-queries, subscriptions, and integrates seamlessly with authentication. Additionally, it supports automatic retries and facilitates GraphQL introspection, ensuring a robust and efficient connection strategy.

It acts as a wrapper on top of apollo/client which will be provisioned and can be directly accessed for optional, advanced usage.

Installation

To install this package, you need to have access to the private @sdk npm scope.

Begin by installing the sdk/connect package using your preferred package manager:

npm install @sdk/connect

Setup

Vanilla JavaScript/TypeScript

To integrate sdk/connect into your project, configure the client as shown below:

import { ConnectClient } from '@sdk/connect';
 
const myClient = new ConnectClient({
  linkOptions: {
    endpoint: 'https://hxdr.app',
    clientName: 'my-application',
    clientVersion: '1.0.0',
    errorHandler: error => {
      // Handle errors globally
      console.error(error);
    },
  },
});

This setup utilizes Apollo’s InMemoryCache for caching strategies, enhancing performance and user experience.

React Integration

npm install @sdk/connect-react react react-dom

To provide global access to the sdk/connect service within a React application, wrap your app with the ConnectProvider and utilize the useConnect hook for easy access:

import { ConnectProvider, useConnect } from '@sdk/connect-react';
import { myClient } from './client'; // Assuming myClient is exported from another file
 
function Root() {
  return (
    <ConnectProvider client={myClient}>
      <App />
    </ConnectProvider>
  );
}
import { useConnect } from '@sdk/connect-react';
 
function App() {
  const { connectClient } = useConnect();
 
  const result = connectClient.getApolloClient().query(/* ... */);
 
  return; // ...
}

Error Handling

The sdk/connect client allows for global error handling through the provided error handler during client setup. This feature is invaluable for implementing user notifications or session management based on API responses:

const myClient = new ConnectClient({
  linkOptions: {
    // ...Other link options
    errorHandler: async error => {
      // Example error handling
      if (error.code === 'UNAUTHENTICATED') {
        // Redirect to login or refresh token
      } else if (error.code === 'OFFLINE') {
        // Notify user of connectivity issues
      } else if (error.code === 'SERVER') {
        // General error handling
      }
    },
  },
});

The common error codes include:

  • UNAUTHENTICATED: Indicates an invalid or missing session token for secured API calls.
  • OFFLINE: Triggered when a connection to the API cannot be established.
  • SERVER: Represents a generic server error, typically a 500 response.

Authentication

Authenticated Users

To dynamically handle Bearer token inclusion in request headers, provide a token resolver function during client initialization:

import { Option } from '@sdk/core';
 
const myClient = new ConnectClient({
  linkOptions: {
    // Other link options
    authenticationTokenResolver: async () => {
      const token = await authService.getCurrentSessionToken();
      return Option.unwrapOr(token);
    },
  },
});

This approach ensures that each request uses the most recent session token, maintaining secure and authenticated connections.

Anonymous Users

For operations involving anonymous users, a signed token may be required. Pass this token via the GraphQL context for applicable queries or mutations:

myClient.getApolloClient().query({
  query: MY_QUERY,
  context: {
    anonymousUserToken: 'my-anonymous-signature',
  },
});

This mechanism supports scenarios where anonymous users interact with the API under limited permissions.

Cache Configuration (Advanced)

In order to configure the cache Type Policies, pass your custom policies at client creation.

const myClient = new ConnectClient({
  cacheTypePolicies: {
    /* ... */
  },
  linkOptions: {
    // Other link options
  },
});