Build an API Client
Learn how to create and use a type-safe, scalable API client for your applications with TanStack Query integration.
This guide explains how to build an API client. If you want to skip the tutorial and view the example directly, you can check it out here
Why Build a Dedicated API Client?
In real-world applications, you often have multiple apps (web, mobile, desktop) that need to communicate with the same backend API. By creating a shared API client library, you can:
- Share code across different applications
- Ensure type safety across your entire stack
- Centralize API logic and business rules
API client Structure
Our API client is organized as a separate library in packages/lib/src/api
:
- Organize API methods by domain (users, posts, orders, etc.)
- Keep types close to their implementations
Creating API Modules
Basic Module Structure
Each API module is a class that encapsulates related API calls. Here's an example:
Registering Your Module
Add your new module to the main API class:
Using the API Client
Initialization
Initialize your API client within your application:
Using in Components
Query vs Mutation: When to Use What?
Using queryOptions or mutationOptions helps us easily reuse queryKeys or queryFunctions. For example, there will be cases where you need to get data from a specific queryKey.
So when should you use query and when should you use mutation?
query
: typically used for getting data (read operations)mutation
: typically used for mutating data (create, update, delete operations).
There are some exceptions, such as when a user clicks an export data button - in this case, the user isn't actually mutating data, but we should still use mutation. To know when you're dealing with an exception, you can base it on user behavior: if getting data depends on a click event or submit action, use mutation.