npm package: @grund/gql-apollo-client
Description: The purpose of this package is to be able to use the `@apollo/client` library in a `@grund` context, which includes adding some basic extra functionality.
Latest version: 0.0.85

# @grund/gql-apollo-client

The purpose of this package is to be able to use the `@apollo/client` library in a `@grund` context, which includes adding some basic extra functionality.

## Usage

What any project using `@apollo/client` want is to create a `client` object that can perform different graphql requests.

```ts
import { initApolloGqlClient } from '@grund/gql-apollo-client';

const { simpleClient, authClient } = initApolloGqlClient({
	uri: 'http://locahost:5001',
});
```

That's it! The initiation is also very customizable with options you can see further down.

## Simple vs Auth

The init function returns two clients; `simpleClient` and `authClient`. The `simpleClient` is more or less just a pure ApolloClient. The `authClient` on the other hand adds support for auth handling. It performs the following extra steps:

1. Calls the `refreshTokenHook` function is it exists.
2. Fetches a token via the `@grund/auth-client` package.
3. Add the token to the request header with the key `authorization`.

That's it. Now the server will receive the token on each request.

## Extra functionality

By using `initApolloGqlClient` you add a few basic functionalities:

1. Adds some reasonable ApolloLinks - e.g. set default headers, handle errors, auth, etc
2. Adds some default cache (InMemoryCache)
3. Adds two new functions to your toolbox: `$query` and `$mutation` which you can read more about in the next section.

### Error handling - $query and $mutation

A pain point that have been experienced is that sometimes you want to be able to call the `query` or the `mutation` function and receive the data if successful, and a distinct error if something went wrong.

The usual way of solving this is receive an `ApolloError` that contains `graphQLErrors` and `networkError`. To find out what went wrong we now have to search through them and parse the code that was received in the error message. Further, most often there is only one error present.

Wouldn't it be nice if we could receive one JavaScript `Error` object with what went wrong. Even more, wouldn't it be nice if we could utilize the errors in `@grund/errors` and receive one of those? Even even more, wouldn't it be nice if we could throw and error on the server, and receive the same one on the client?

This is why we added the helper functions `$query` and `$mutate`. They function the same way as the normal ones, but also takes a second argument with the following interface:

```ts
export interface Config {
	shouldParseErrors?: boolean;
	shouldThrowSingleError?: boolean;

	shouldLogNetworkError?: boolean;
	shouldLogUnknownErrors?: boolean;
}
```

What they do is quite simply that they catch any errors that occurs in the normal functions, and depending on the config throws a single error instead.

The reason for why we added these function instead of augumenting the normal ones is:

1. Better to add additional functionalities than to change another library.
2. shouldThrowSingleError is true by default when using $query/$mutation. We likely don't what that behavior in e.g. `useQuery`.

## API

The `initApolloGqlClient` takes in one argument with the following interface:

```ts
interface InitApolloClientOpts {
	uri: string;
	headers?: Record<string, any>;

	links?: ApolloLink[];
	defaultOptions?: DefaultOptions;

	apolloClientOpts?: Partial<AnyApolloClientOptions>;
	httpLinkOpts?: any;

	inMemoryCacheOpts?: any;
	defaultKeyFields?: string[];

	resolvers?: Record<string, any>;
	hooks?: {
		refreshToken: Function;
	};
}
```