Skip to main content
Version: 0.58.0-rc.42

GraphQL Development

This guide covers working with Lana's GraphQL APIs during local development.

API Endpoints

APILocal URLDirect Port
Admin APIhttp://admin.lana-bank.localhost:1355/graphql5253
Customer APIhttp://app.lana-bank.localhost:1355/graphql5254
warning

GraphQL requests must include a Keycloak access token. The Rust servers validate Keycloak JWTs directly against the configured realm JWKS.

Apollo Client Setup

Both frontend apps use Apollo Client for GraphQL communication.

Installation

npm install @apollo/client graphql

Configuration

import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';

const httpLink = createHttpLink({
uri: 'http://admin.lana-bank.localhost:1355/graphql',
});

const authLink = setContext((_, { headers }) => {
const token = localStorage.getItem('token');
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : '',
},
};
});

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

Code Generation

After modifying GraphQL schemas in Rust, regenerate the SDL and client types:

1. Regenerate GraphQL SDL

make sdl

This must be run after any changes to async-graphql resolvers in Rust.

2. Generate TypeScript Types

# codegen.yml
schema:
- http://admin.lana-bank.localhost:1355/graphql:
headers:
Authorization: Bearer ${TOKEN}

documents:
- 'src/**/*.graphql'

generates:
src/generated/graphql.ts:
plugins:
- typescript
- typescript-operations
- typescript-react-apollo
pnpm codegen

Common Patterns

Queries with Cursor Pagination

Lana APIs use Relay-style cursor-based pagination:

query GetCustomers($first: Int!, $after: String) {
customers(first: $first, after: $after) {
edges {
cursor
node {
id
email
status
}
}
pageInfo {
hasNextPage
endCursor
}
}
}

Mutations

mutation CreateCustomer($input: CustomerCreateInput!) {
customerCreate(input: $input) {
customer {
id
email
status
}
}
}

React Hooks Usage

import { useGetCustomersQuery, useCreateCustomerMutation } from './generated/graphql';

function CustomerList() {
const { data, loading, error } = useGetCustomersQuery({
variables: { first: 10 },
});

const [createCustomer] = useCreateCustomerMutation();

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

return (
<ul>
{data?.customers?.edges?.map((edge) => (
<li key={edge.node.id}>{edge.node.email}</li>
))}
</ul>
);
}

Error Handling

import { onError } from '@apollo/client/link/error';

const errorLink = onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors) {
graphQLErrors.forEach(({ message }) => {
console.error(`GraphQL error: ${message}`);
});
}
if (networkError) {
console.error(`Network error: ${networkError}`);
}
});

API References