> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pylon.mortgage/llms.txt
> Use this file to discover all available pages before exploring further.

# Using GraphQL clients

> Learn how to use GraphQL client libraries with the Pylon API

GraphQL client libraries make it easier to work with the Pylon GraphQL API. They handle request formatting, error handling, caching, and more.

## Popular GraphQL clients

### Apollo Client

Apollo Client is a popular GraphQL client for React, Vue, Angular, and vanilla JavaScript.

**Installation:**

```bash theme={null}
npm install @apollo/client graphql
```

**Setup:**

```javascript theme={null}
import { ApolloClient, InMemoryCache, createHttpLink } from "@apollo/client";
import { setContext } from "@apollo/client/link/context";

const httpLink = createHttpLink({
  uri: "https://pylon.mortgage/graphql",
});

const authLink = setContext((_, { headers }) => {
  const token = getAccessToken(); // Your function to get the token
  return {
    headers: {
      ...headers,
      authorization: token ? `Bearer ${token}` : "",
    },
  };
});

const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache(),
});
```

**Using with React:**

```javascript theme={null}
import { useQuery, useMutation } from "@apollo/client";
import { gql } from "@apollo/client";

const GET_DEAL = gql`
  query GetDeal($id: ID!) {
    deal(id: $id) {
      id
      friendlyId
      borrowers {
        edges {
          node {
            id
            personalInformation {
              firstName
              lastName
            }
          }
        }
      }
    }
  }
`;

function DealComponent({ dealId }) {
  const { loading, error, data } = useQuery(GET_DEAL, {
    variables: { id: dealId },
  });

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <div>
      <h1>Deal {data.deal.id}</h1>
      <p>Reference: {data.deal.friendlyId}</p>
    </div>
  );
}
```

### graphql-request

A minimal GraphQL client that works in any JavaScript environment.

**Installation:**

```bash theme={null}
npm install graphql-request graphql
```

**Usage:**

```javascript theme={null}
import { GraphQLClient } from "graphql-request";

const client = new GraphQLClient("https://pylon.mortgage/graphql", {
  headers: {
    authorization: `Bearer ${accessToken}`,
  },
});

const query = `
  query GetDeal($id: ID!) {
    deal(id: $id) {
      id
      friendlyId
    }
  }
`;

const variables = { id: "123" };

const data = await client.request(query, variables);
```

### Relay

Relay is Facebook's GraphQL client, optimized for React.

**Installation:**

```bash theme={null}
npm install react-relay relay-runtime
```

Relay requires a more complex setup with a compiler. See the [Relay documentation](https://relay.dev/) for details.

## Authentication

All clients need to include the authorization header. Here are patterns for different clients:

### Apollo Client

```javascript theme={null}
const authLink = setContext((_, { headers }) => {
  const token = getAccessToken();
  return {
    headers: {
      ...headers,
      authorization: token ? `Bearer ${token}` : "",
    },
  };
});
```

### graphql-request

```javascript theme={null}
const client = new GraphQLClient("https://pylon.mortgage/graphql", {
  headers: {
    authorization: `Bearer ${accessToken}`,
  },
});
```

### Custom fetch wrapper

```javascript theme={null}
async function graphqlRequest(query, variables) {
  const response = await fetch("https://pylon.mortgage/graphql", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${getAccessToken()}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ query, variables }),
  });

  const result = await response.json();

  if (result.errors) {
    throw new Error(result.errors[0].message);
  }

  return result.data;
}
```

## Error handling

All clients should handle GraphQL errors:

```javascript theme={null}
try {
  const data = await client.request(query, variables);
  // Use data
} catch (error) {
  if (error.response) {
    // GraphQL errors
    error.response.errors.forEach((err) => {
      console.error("GraphQL Error:", err.message);
    });
  } else {
    // Network or other errors
    console.error("Request Error:", error.message);
  }
}
```

## Caching

Most GraphQL clients provide caching:

### Apollo Client

Apollo Client automatically caches queries:

```javascript theme={null}
const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache({
    typePolicies: {
      Deal: {
        fields: {
          borrowers: {
            merge(existing, incoming) {
              return incoming;
            },
          },
        },
      },
    },
  }),
});
```

### Manual caching

```javascript theme={null}
const cache = new Map();

async function cachedRequest(query, variables) {
  const key = JSON.stringify({ query, variables });

  if (cache.has(key)) {
    return cache.get(key);
  }

  const data = await graphqlRequest(query, variables);
  cache.set(key, data);
  return data;
}
```

## TypeScript support

Most clients support TypeScript. Generate types from your schema:

### Using GraphQL code generator

```bash theme={null}
npm install -D @graphql-codegen/cli @graphql-codegen/typescript
```

**codegen.yml:**

```yaml theme={null}
schema: https://pylon.mortgage/graphql
documents: "src/**/*.graphql"
generates:
  src/generated/graphql.ts:
    plugins:
      - typescript
      - typescript-operations
```

## Best practices

1. **Use a client library** - Don't manually construct requests
2. **Handle errors** - Always check for GraphQL errors
3. **Use TypeScript** - Generate types from your schema
4. **Implement caching** - Reduce unnecessary requests
5. **Refresh tokens** - Handle token expiration gracefully
6. **Use variables** - Never hardcode values in queries

## Next steps

* Explore the [GraphQL API Reference](/playground/api-reference) to view the complete schema
* Learn about [pagination](/playground/pagination) for large datasets
* Review [error handling](/playground/error-handling) patterns
