Skip to content

Browser → server: generated data-access client, not `fetch`

**Scope: browser → server** (client-to-server). Browser or mobile app calling your own `/api/...` — not server-to-vendor calls, not server-to-server between your domains. Hand-written fetch to your API — changes fail in the browser, not at compile time.

nestjs-testing-generated-client-not-fetch

Why it matters

Failure modes if this rule is ignored
StakeIf ignored
API drift
  • Hand-written fetch strings — backend renames compile fine and fail in the user's browser.
  • Types maintained twice — OpenAPI, hand types, and runtime behavior disagree within a sprint.
Agent gets lost
  • Response shape lives in someone's head — backend adds a field, frontend finds out in prod.

How to fix

Every domain with a backend produces a frontend data-access client (OpenAPI / tRPC / GraphQL codegen). UI and feature code import that client — they do not write fetch('/api/...') by hand. Server-to-vendor calls use a dedicated integration client. Server-to-internal domain calls use exported NestJS services, not HTTP between your own modules.

Examples

Bad
ts
// frontend component — calling your own backend, not an external vendor
const res = await fetch(`/api/sites/${id}`);
const data = await res.json() as any;
// what fields? who knows. backend change? runtime errors.
Good
ts
// libs/sites-management/data-access/src/lib/client.ts
// generated from OpenAPI / tRPC
export const sitesClient = createClient<SitesAPI>();

// in a consumer
const site = await sitesClient.sites.get({ id });
// site is fully typed. backend change? immediate compile error.

Contribute

Released under the MIT License.

esc