Generated typed API client + TanStack Query hooks (packages/api-client) #182

Closed
opened 2026-06-20 15:44:17 +00:00 by james · 0 comments
Owner

Generate a TypeScript client and TanStack Query hooks from the OpenAPI spec, packaged as packages/api-client, consumed exclusively by the Expo app.

The client never imports from apps/api. The only seam between frontend and backend is the spec and what's generated from it.

Scope

  • Adopt openapi-typescript for type generation + openapi-fetch for the runtime (or orval if hooks generation is preferred — record the choice in ADR-0027 or this ticket).
  • Codegen entry point: packages/api-client/scripts/generate.ts reads apps/api/openapi.json and emits packages/api-client/src/generated/.
  • Hand-written TanStack Query hooks layered on top, one per resource (useSkills, useSkill, useCreateSkill, …). Keep them thin — the heavy lifting is the generated client.
  • TanStack Query onlineManager + focusManager wiring for RN (NetInfo + AppState) — gated behind a platform check so the web build doesn't drag in RN deps.
  • Persistence: @tanstack/query-async-storage-persister for offline cache.
  • CI step: regenerate against the committed spec and fail if the generated files drift from the committed ones.

Acceptance criteria

  • packages/api-client exports a typed client + a hook per existing list/detail/create/update/delete operation.
  • The package builds against both web and RN targets.
  • CI fails if the generated source isn't up to date with the spec.
  • At least one end-to-end smoke test exercises a real route through the generated client.

Out of scope

  • Using the client in screens (Expo scaffolding + screen-port tickets).
  • Authoring spec by hand — see OpenAPI spec generation ticket.

Composes with

OpenAPI spec generation, API contract hardening, Token-based auth, Expo client scaffolding.

Part of

#176

Generate a TypeScript client and TanStack Query hooks from the OpenAPI spec, packaged as `packages/api-client`, consumed exclusively by the Expo app. The client never imports from `apps/api`. The only seam between frontend and backend is the spec and what's generated from it. ## Scope - Adopt **`openapi-typescript`** for type generation + **`openapi-fetch`** for the runtime (or `orval` if hooks generation is preferred — record the choice in ADR-0027 or this ticket). - Codegen entry point: `packages/api-client/scripts/generate.ts` reads `apps/api/openapi.json` and emits `packages/api-client/src/generated/`. - Hand-written TanStack Query hooks layered on top, one per resource (`useSkills`, `useSkill`, `useCreateSkill`, …). Keep them thin — the heavy lifting is the generated client. - TanStack Query `onlineManager` + `focusManager` wiring for RN (NetInfo + AppState) — gated behind a platform check so the web build doesn't drag in RN deps. - Persistence: `@tanstack/query-async-storage-persister` for offline cache. - CI step: regenerate against the committed spec and fail if the generated files drift from the committed ones. ## Acceptance criteria - [ ] `packages/api-client` exports a typed client + a hook per existing list/detail/create/update/delete operation. - [ ] The package builds against both web and RN targets. - [ ] CI fails if the generated source isn't up to date with the spec. - [ ] At least one end-to-end smoke test exercises a real route through the generated client. ## Out of scope - Using the client in screens (Expo scaffolding + screen-port tickets). - Authoring spec by hand — see OpenAPI spec generation ticket. ## Composes with OpenAPI spec generation, API contract hardening, Token-based auth, Expo client scaffolding. ## Part of #176
james closed this issue 2026-06-21 04:26:16 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
james/carol#182
No description provided.