|
Download src/api/README.md from SaylorTwift/openhands: direct link, hf CLI and curl.
- Browser
- Download file 3.37 kB
-
https://huggingface.co/SaylorTwift/openhands/resolve/main/src/api/README.md
- Command line
-
hf download hf://SaylorTwift/openhands/src/api/README.md
-
curl -L -o README.md https://huggingface.co/SaylorTwift/openhands/resolve/main/src/api/README.md
3.37 kB
| # API Services Guide | |
| ## Overview | |
| Services are the abstraction layer between frontend components and backend APIs. Local agent-server API access should use `@openhands/typescript-client` classes directly, with shared connection options from `src/api/agent-server-client-options.ts` for the active local backend host, session API key, and workspace defaults. | |
| Cloud-specific APIs should use the cloud service modules/proxy helpers instead of local agent-server clients. | |
| Each service is a plain object with async methods. | |
| ## Structure | |
| Each service lives in its own directory: | |
| ``` | |
| src/api/ | |
| βββ feature-service/ | |
| βββ feature-service.api.ts # Service methods | |
| βββ feature.types.ts # Types and interfaces | |
| ``` | |
| ## Creating a Service | |
| Use an object literal with named export. Use object destructuring for parameters to make calls self-documenting. Prefer typed `@openhands/typescript-client` classes over generic HTTP calls. If a needed endpoint is missing, add it to `@openhands/typescript-client` first. | |
| ```typescript | |
| // feature-service/feature-service.api.ts | |
| import { FeatureClient } from "@openhands/typescript-client/clients"; | |
| import { getAgentServerClientOptions } from "../agent-server-client-options"; | |
| import { Feature, CreateFeatureParams } from "./feature.types"; | |
| export const featureService = { | |
| getFeature: async ({ id }: { id: string }): Promise<Feature> => { | |
| return new FeatureClient(getAgentServerClientOptions()).getFeature(id); | |
| }, | |
| createFeature: async (params: CreateFeatureParams): Promise<Feature> => { | |
| return new FeatureClient(getAgentServerClientOptions()).createFeature(params); | |
| }, | |
| }; | |
| ``` | |
| ### Types | |
| Define app-specific types in a separate file within the same directory when the TypeScript client models are not sufficient: | |
| ```typescript | |
| // feature-service/feature.types.ts | |
| export interface Feature { | |
| id: string; | |
| name: string; | |
| description: string; | |
| } | |
| export interface CreateFeatureParams { | |
| name: string; | |
| description: string; | |
| } | |
| ``` | |
| ## Usage | |
| > [!IMPORTANT] | |
| > **Don't call services directly in components.** Wrap them in TanStack Query hooks. | |
| > | |
| > Why? TanStack Query provides: | |
| > | |
| > - **Caching** - Avoid redundant network requests | |
| > - **Deduplication** - Multiple components requesting the same data share one request | |
| > - **Loading/error states** - Built-in `isLoading`, `isError`, `data` states | |
| > - **Background refetching** - Data stays fresh automatically | |
| > | |
| > Hooks location: | |
| > | |
| > - `src/hooks/query/` for data fetching (`useQuery`) | |
| > - `src/hooks/mutation/` for writes/updates (`useMutation`) | |
| ```typescript | |
| // src/hooks/query/use-feature.ts | |
| import { useQuery } from "@tanstack/react-query"; | |
| import { featureService } from "#/api/feature-service/feature-service.api"; | |
| export const useFeature = (id: string) => { | |
| return useQuery({ | |
| queryKey: ["feature", id], | |
| queryFn: () => featureService.getFeature({ id }), | |
| }); | |
| }; | |
| ``` | |
| ## Naming Conventions | |
| | Item | Convention | Example | | |
| | ------------ | ------------------------ | ------------------------ | | |
| | Directory | `feature-service/` | `secrets-service/` | | |
| | Service file | `feature-service.api.ts` | `secrets-service.api.ts` | | |
| | Types file | `feature.types.ts` | `secrets.types.ts` | | |
| | Export name | `featureService` | `secretsService` | | |