Skip to main content

Item Service API

The ItemsService class is the primary interface for interacting with the backend item resources. Located in frontend/src/client/sdk.gen.ts, this service is automatically generated from the OpenAPI specification and provides a type-safe, promise-based API for performing CRUD (Create, Read, Update, Delete) operations on items.

Core CRUD Operations

The ItemsService consists of static methods that map directly to the /api/v1/items/ endpoints. Each method returns a CancelablePromise, allowing the frontend to manage request lifecycles effectively.

Reading Items

The service provides two ways to retrieve item data: fetching a paginated list or retrieving a specific item by its unique identifier.

  • readItems(data): Fetches a list of items. It accepts optional skip and limit parameters for pagination.
  • readItem(data): Fetches a single item. It requires an id (UUID string).
// Example: Fetching a list of items with pagination
const response = await ItemsService.readItems({ skip: 0, limit: 100 });

Creating and Updating Items

For operations that modify data, the service uses a consistent requestBody pattern. This ensures that the payload structure matches the expected backend schema (e.g., ItemCreate or ItemUpdate).

  • createItem(data): Sends a POST request to create a new item.
  • updateItem(data): Sends a PUT request to update an existing item, requiring both the item id and the requestBody.
// Example: Creating a new item
const newItem = await ItemsService.createItem({
requestBody: {
title: "New Item",
description: "Item description"
}
});

Deleting Items

  • deleteItem(data): Sends a DELETE request for a specific item id. It returns a success message upon completion.

Integration with TanStack Query

In this project, ItemsService is integrated with TanStack Query to handle caching, loading states, and automatic re-fetching. This is the standard way to consume the service within React components.

Data Fetching with useSuspenseQuery

The project uses useSuspenseQuery in route components like frontend/src/routes/_layout/items.tsx to fetch item lists. This pattern centralizes the query logic into a helper function:

// frontend/src/routes/_layout/items.tsx

function getItemsQueryOptions() {
return {
queryFn: () => ItemsService.readItems({ skip: 0, limit: 100 }),
queryKey: ["items"],
}
}

// Inside the component
const { data: items } = useSuspenseQuery(getItemsQueryOptions())

Mutations with useMutation

For actions like creating or deleting items, the project uses the useMutation hook. This allows for side effects like showing success toasts and invalidating queries to refresh the UI.

As seen in frontend/src/components/Items/AddItem.tsx:

const mutation = useMutation({
mutationFn: (data: ItemCreate) =>
ItemsService.createItem({ requestBody: data }),
onSuccess: () => {
showSuccessToast("Item created successfully")
form.reset()
setIsOpen(false)
},
onSettled: () => {
// Refresh the items list after a successful creation
queryClient.invalidateQueries({ queryKey: ["items"] })
},
})

Configuration and Authentication

The ItemsService relies on the global OpenAPI configuration object defined in frontend/src/client/core/OpenAPI.ts. This configuration manages the base URL and authentication tokens for every request.

  • OpenAPI.BASE: The base URL for the API, typically configured in main.tsx from environment variables.
  • OpenAPI.TOKEN: A string or function that provides the Bearer token. In this codebase, it is typically retrieved from localStorage.

When a method in ItemsService is called, it invokes the internal __request utility, which automatically injects these configuration values into the outgoing HTTP request.

Error Handling

The service methods are designed to throw an ApiError if the backend returns a non-success status code (e.g., 422 Validation Error). In the UI components, these errors are typically caught and handled using a centralized handleError utility, which displays the error message to the user via a toast notification.

// Common error handling pattern in mutations
onError: handleError.bind(showErrorToast)