diff --git a/autogpt_platform/frontend/README.md b/autogpt_platform/frontend/README.md index 361cd81045..601187c968 100644 --- a/autogpt_platform/frontend/README.md +++ b/autogpt_platform/frontend/README.md @@ -63,9 +63,147 @@ Every time a new Front-end dependency is added by you or others, you will need t - `pnpm type-check` - Run TypeScript type checking - `pnpm test` - Run Playwright tests - `pnpm test-ui` - Run Playwright tests with UI +- `pnpm fetch:openapi` - Fetch OpenAPI spec from backend +- `pnpm generate:api-client` - Generate API client from OpenAPI spec +- `pnpm generate:api-all` - Fetch OpenAPI spec and generate API client This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. +## 🔄 Data Fetching Strategy + +This project uses an auto-generated API client powered by [**Orval**](https://orval.dev/), which creates type-safe API clients from OpenAPI specifications. + +### How It Works + +1. **Backend Requirements**: Each API endpoint needs a summary and tag in the OpenAPI spec +2. **Operation ID Generation**: FastAPI generates operation IDs using the pattern `{method}{tag}{summary}` +3. **Spec Fetching**: The OpenAPI spec is fetched from `http://localhost:8006/openapi.json` and saved to the frontend +4. **Spec Transformation**: The OpenAPI spec is cleaned up using a custom transformer (see `autogpt_platform/frontend/src/app/api/transformers`) +5. **Client Generation**: Auto-generated client includes TypeScript types, API endpoints, and Zod schemas, organized by tags + +### API Client Commands + +```bash +# Fetch OpenAPI spec from backend and generate client +pnpm generate:api-all + +# Only fetch the OpenAPI spec +pnpm fetch:openapi + +# Only generate the client (after spec is fetched) +pnpm generate:api-client +``` + +### Using the Generated Client + +The generated client provides React Query hooks for both queries and mutations: + +#### Queries (GET requests) + +```typescript +import { useGetV1GetNotificationPreferences } from "@/app/api/__generated__/endpoints/auth/auth"; + +const { data, isLoading, isError } = useGetV1GetNotificationPreferences({ + query: { + select: (res) => res.data, + // Other React Query options + }, +}); +``` + +#### Mutations (POST, PUT, DELETE requests) + +```typescript +import { useDeleteV2DeleteStoreSubmission } from "@/app/api/__generated__/endpoints/store/store"; +import { getGetV2ListMySubmissionsQueryKey } from "@/app/api/__generated__/endpoints/store/store"; +import { useQueryClient } from "@tanstack/react-query"; + +const queryClient = useQueryClient(); + +const { mutateAsync: deleteSubmission } = useDeleteV2DeleteStoreSubmission({ + mutation: { + onSuccess: () => { + // Invalidate related queries to refresh data + queryClient.invalidateQueries({ + queryKey: getGetV2ListMySubmissionsQueryKey(), + }); + }, + }, +}); + +// Usage +await deleteSubmission({ + submissionId: submission_id, +}); +``` + +#### Server Actions + +For server-side operations, you can also use the generated client functions directly: + +```typescript +import { postV1UpdateNotificationPreferences } from "@/app/api/__generated__/endpoints/auth/auth"; + +// In a server action +const preferences = { + email: "user@example.com", + preferences: { + AGENT_RUN: true, + ZERO_BALANCE: false, + // ... other preferences + }, + daily_limit: 0, +}; + +await postV1UpdateNotificationPreferences(preferences); +``` + +#### Server-Side Prefetching + +For server-side components, you can prefetch data on the server and hydrate it in the client cache. This allows immediate access to cached data when queries are called: + +```typescript +import { getQueryClient } from "@/lib/tanstack-query/getQueryClient"; +import { + prefetchGetV2ListStoreAgentsQuery, + prefetchGetV2ListStoreCreatorsQuery +} from "@/app/api/__generated__/endpoints/store/store"; +import { HydrationBoundary, dehydrate } from "@tanstack/react-query"; + +// In your server component +const queryClient = getQueryClient(); + +await Promise.all([ + prefetchGetV2ListStoreAgentsQuery(queryClient, { + featured: true, + }), + prefetchGetV2ListStoreAgentsQuery(queryClient, { + sorted_by: "runs", + }), + prefetchGetV2ListStoreCreatorsQuery(queryClient, { + featured: true, + sorted_by: "num_agents", + }), +]); + +return ( + + + +); +``` + +This pattern improves performance by serving pre-fetched data from the server while maintaining the benefits of client-side React Query features. + +### Configuration + +The Orval configuration is located in `autogpt_platform/frontend/orval.config.ts`. It generates two separate clients: + +1. **autogpt_api_client**: React Query hooks for client-side data fetching +2. **autogpt_zod_schema**: Zod schemas for validation + +For more details, see the [Orval documentation](https://orval.dev/) or check the configuration file. + ## 🚚 Deploy TODO