Calling Backend Services

The frontend reaches every backend service through a path prefix on its own origin (Caddy routes /svc1/* to service-1 and /svc2/* to service-2), with one API-client instance per service:

  1. Base URL: a NEXT_PUBLIC_<NAME>_API_URL env var in .env.local (+ .example) and infra/env/public-page.env.prod (+ .example). NEXT_PUBLIC_* values are baked in at build time: restart the dev container / rebuild the prod image to pick them up.
  2. API client: add the base URL to lib/api/config.ts and export a client instance for it in lib/api/client.ts, then wrap the endpoints in a lib/api/services/<name>.service.ts with types in lib/api/types.ts.
  3. UI: fetch through the service module. Any user-facing text needs keys in all locale catalogues under messages/.

Because the routing is same-origin, the auth cookies ride along automatically and no CORS setup is needed for the app's own calls.

The Tasks page (backed by the second example service) is the worked example of all the steps: service2ApiClient in lib/api/client.ts, tasks.service.ts in lib/api/services/, and app/dashboard/tasks/page.tsx.

Next: Writing Docs.