Skip to content

Commit 86ca1e3

Browse files
Add documentation react-tools relationship handling
1 parent f1d9cbb commit 86ca1e3

1 file changed

Lines changed: 90 additions & 0 deletions

File tree

docs/docs/integrations/react-tools.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,96 @@ JsonApiToolkit supports rich querying via URL parameters. `jsonapi-react-tools`
135135

136136
The query builder supports all standard JSON:API operators (`eq`, `ne`, `gt`, `ge`, `lt`, `le`, `like`, `in`, `nin`, `isnull`, `isnotnull`) and logical groupings (`and`, `or`, `not`).
137137

138+
### Working with Relationships (Included Resources)
139+
140+
When your API response includes related resources (using the `include` query parameter), `jsonapi-react-tools` provides type safety for the `included` array. This requires defining a central registry of all your resource types.
141+
142+
1. **Define Attribute Types for All Resources:** Ensure you have attribute types defined not only for your primary resource (e.g., `CompanyAttributes`) but also for any resources that might appear in the `included` array (e.g., `LocationAttributes`).
143+
144+
```ts
145+
// types/Company.ts
146+
export type CompanyAttributes = {
147+
companyName: string;
148+
companyCode: string;
149+
// ... other fields
150+
};
151+
152+
// types/Location.ts
153+
export type LocationAttributes = {
154+
address: string;
155+
city: string;
156+
// ... other fields
157+
};
158+
```
159+
160+
2. **Create Your Application's Type Registry:** Implement the `JsonApiTypeRegistry` interface, mapping the exact `type` string returned by your API to the corresponding attribute interface.
161+
162+
```ts
163+
// types/Registry.ts
164+
import { JsonApiTypeRegistry } from "@intility/jsonapi-react-tools";
165+
import { CompanyAttributes } from "./Company";
166+
import { LocationAttributes } from "./Location";
167+
168+
// Add all resource types that can appear in 'data' or 'included'
169+
export interface AppTypeRegistry extends JsonApiTypeRegistry {
170+
companies: CompanyAttributes; // 'companies' is the type string from the API
171+
locations: LocationAttributes; // 'locations' is the type string from the API
172+
}
173+
```
174+
175+
3. **Use the Registry in Your Data Fetching:** Pass your `AppTypeRegistry` as the second generic argument to `JsonApiCollectionDocument` or `JsonApiDocument`.
176+
177+
```tsx
178+
import { useQuery } from "@tanstack/react-query";
179+
import {
180+
JsonApiCollectionDocument,
181+
isResourceType, // Import the type predicate
182+
buildJsonApiQueryString,
183+
JsonApiQueryOptions,
184+
} from "@intility/jsonapi-react-tools";
185+
import { CompanyAttributes } from "~/types/Company.ts";
186+
import { AppTypeRegistry } from "~/types/Registry.ts"; // Import your registry
187+
188+
const queryOptions: JsonApiQueryOptions<CompanyAttributes> = {
189+
include: ["locations"], // Request related locations
190+
};
191+
const queryString = buildJsonApiQueryString(queryOptions);
192+
193+
export const CompanyListWithLocations = () => {
194+
// Use the registry in the useQuery type definition
195+
const { data: response, error, isLoading } = useQuery<
196+
JsonApiCollectionDocument<CompanyAttributes, AppTypeRegistry> // <--- Pass registry here
197+
>({ queryKey: ["api", "companies", queryString] });
198+
199+
if (isLoading) return <div>Loading...</div>;
200+
if (error || !response) return <div>Error</div>;
201+
202+
// Process included data safely
203+
response.included?.forEach((resource) => {
204+
// Use the type predicate to check the type and narrow it down
205+
if (isResourceType(resource, "locations")) {
206+
// TypeScript now knows resource.attributes is LocationAttributes
207+
console.log("Included Location City:", resource.attributes.city);
208+
}
209+
// Add checks for other included types if necessary
210+
});
211+
212+
return (
213+
<ul>
214+
{response.data.map((company) => (
215+
<li key={company.id}>
216+
{company.attributes.companyName}
217+
{/* You can now safely look up and display related data */}
218+
</li>
219+
))}
220+
</ul>
221+
);
222+
};
223+
```
224+
225+
By defining the `AppTypeRegistry` and using the `isResourceType` type predicate, you gain full type safety when working with related resources included in your API responses.
226+
227+
138228
### Further Information
139229

140230
For more details on the package itself, visit the repository:

0 commit comments

Comments
 (0)