# API Client Reference ## File Location `packages/api/src/clients/.ts` ## Standard CrudClient Pattern (Preferred) Use this when the resource has standard CRUD endpoints that exist in the OpenAPI schema. ```ts import { CrudClient } from "../infra/crud-client" import type { ApiClientOptions } from "../infra/client" import type { ApiPath, ApiRequestBody } from "../infra/types" export const _ROUTES = { INDEX: "/api/", BY_ID: "/api//{id}", // Add extra routes as needed: // EXPORT: "/api//export", // IMPORT: "/api//import", // RELATED: "/api/", } as const satisfies Record export class Client extends CrudClient< typeof _ROUTES.INDEX, typeof _ROUTES.BY_ID > { constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) { super(baseUrl, defaultOptions, _ROUTES.INDEX, _ROUTES.BY_ID) } // Add domain-specific methods: // async listCategories() { // return this.get(_ROUTES.RELATED) // } // // async export() { // return this.get(_ROUTES.EXPORT) // } } ``` ### CrudClient Gives You For Free | Method | HTTP | Description | |---|---|---| | `list(query?)` | `GET /api/` | Paginated list with query params | | `show(id)` | `GET /api//{id}` | Single item fetch | | `create(payload)` | `POST /api/` | Create new item | | `update(id, payload)` | `PUT /api//{id}` | Update existing item | | `destroy(id)` | `DELETE /api//{id}` | Delete item | ## Minimal CrudClient (No Custom Methods) For simple resources with only standard CRUD: ```ts import { CrudClient } from "../infra/crud-client" import type { ApiClientOptions } from "../infra/client" import type { ApiPath } from "../infra/types" export const _ROUTES = { INDEX: "/api/", BY_ID: "/api//{id}", } as const satisfies Record export class Client extends CrudClient< typeof _ROUTES.INDEX, typeof _ROUTES.BY_ID > { constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) { super(baseUrl, defaultOptions, _ROUTES.INDEX, _ROUTES.BY_ID) } } ``` ## Registration After creating the client, register it in two files: ### 1. `packages/api/src/clients/index.ts` ```ts export { Client, _ROUTES } from "./" ``` ### 2. `packages/api/src/api.ts` Add the import at the top: ```ts import { Client } from "./clients/" ``` Add to the `createApi()` return object: ```ts export function createApi(options?: ApiClientOptions) { return { // ...existing clients... : new Client(undefined, options), } } ``` ## Real Example: CustomersClient ```ts import { CrudClient } from "../infra/crud-client" import { ApiClient, type ApiClientOptions } from "../infra/client" import type { ApiPath, ApiRequestBody } from "../infra/types" export const CUSTOMER_ROUTES = { INDEX: "/api/customers", BY_ID: "/api/customers/{id}", EXPORT: "/api/customers/export", IMPORT: "/api/customers/import", CUSTOMER_TYPES: "/api/customer-types", } as const satisfies Record export class CustomersClient extends CrudClient< typeof CUSTOMER_ROUTES.INDEX, typeof CUSTOMER_ROUTES.BY_ID > { constructor(baseUrl?: string, defaultOptions?: ApiClientOptions) { super(baseUrl, defaultOptions, CUSTOMER_ROUTES.INDEX, CUSTOMER_ROUTES.BY_ID) } async listCustomerTypes() { return this.get(CUSTOMER_ROUTES.CUSTOMER_TYPES) } async export() { return this.get(CUSTOMER_ROUTES.EXPORT) } async import(payload: ApiRequestBody) { return this.post(CUSTOMER_ROUTES.IMPORT, payload) } } ```