User Service API Reference
The UsersService class, located in frontend/src/client/sdk.gen.ts, serves as the primary interface for interacting with the backend user management API. It encapsulates all logic for user CRUD operations, profile management, and registration, providing a type-safe bridge between the frontend and the FastAPI backend.
Core Concepts
The UsersService is implemented as a static class, meaning its methods are called directly on the class itself without instantiation. Every method returns a CancelablePromise, which integrates seamlessly with the project's asynchronous state management.
The service distinguishes between three primary scopes of operation:
- Current User ("Me"): Methods targeting the authenticated user's own profile (e.g.,
readUserMe,updatePasswordMe). - Administrative: Methods requiring superuser privileges to manage other users (e.g.,
readUsers,updateUser). - Public: Methods accessible without authentication (e.g.,
registerUser).
Integration with TanStack Query
In this codebase, UsersService is rarely called in isolation. Instead, it is used as the data-fetching layer for TanStack Query hooks (useQuery and useMutation).
Data Fetching with useQuery
For retrieving data, the service methods are passed as the queryFn. For example, the useAuth hook uses readUserMe to maintain the global user state:
// frontend/src/hooks/useAuth.ts
const { data: user } = useQuery<UserPublic | null, Error>({
queryKey: ["currentUser"],
queryFn: UsersService.readUserMe,
enabled: isLoggedIn(),
})
Data Mutation with useMutation
For actions that modify data, such as creating a user, the service methods are wrapped in a mutationFn. This allows the application to handle loading states, success toasts, and cache invalidation:
// frontend/src/components/Admin/AddUser.tsx
const mutation = useMutation({
mutationFn: (data: UserCreate) =>
UsersService.createUser({ requestBody: data }),
onSuccess: () => {
showSuccessToast("User created successfully")
form.reset()
setIsOpen(false)
},
onSettled: () => {
queryClient.invalidateQueries({ queryKey: ["users"] })
},
})
Authentication and Configuration
The UsersService relies on the global OpenAPI configuration defined in frontend/src/client/core/OpenAPI.ts. This configuration is initialized in frontend/src/main.tsx to handle base URLs and authentication tokens.
Base URL and Token Resolution
The service automatically attaches the authentication token to requests by resolving the OpenAPI.TOKEN property:
// frontend/src/main.tsx
OpenAPI.BASE = import.meta.env.VITE_API_URL
OpenAPI.TOKEN = async () => {
return localStorage.getItem("access_token") || ""
}
Error Handling
Errors returned by UsersService (instances of ApiError) are handled globally in main.tsx. If a service call returns a 401 or 403 status, the application clears the local token and redirects the user to the login page:
const handleApiError = (error: Error) => {
if (error instanceof ApiError && [401, 403].includes(error.status)) {
localStorage.removeItem("access_token")
window.location.href = "/login"
}
}
API Reference Summary
Current User Management
These methods interact with the /api/v1/users/me endpoints and are used in components like UserInformation.tsx and ChangePassword.tsx.
readUserMe(): Retrieves the current authenticated user's profile.updateUserMe({ requestBody }): Updates the current user's basic information.updatePasswordMe({ requestBody }): Specifically handles password changes for the current user.deleteUserMe(): Allows a user to delete their own account.
Administrative Operations
These methods target specific users by ID and typically require the is_superuser flag to be true on the requesting user. They are primarily used in the Admin.tsx route and associated components.
readUsers({ skip, limit }): Retrieves a paginated list of all users.createUser({ requestBody }): Creates a new user (Admin-only creation).readUserById({ userId }): Fetches details for a specific user.updateUser({ userId, requestBody }): Updates any user's profile.deleteUser({ userId }): Removes a user from the system.
Public Operations
registerUser({ requestBody }): Hits the/api/v1/users/signupendpoint. This is used for open registration and does not require anAuthorizationheader.