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:
- Base URL: a
NEXT_PUBLIC_<NAME>_API_URLenv var in.env.local(+.example) andinfra/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. - API client: add the base URL to
lib/api/config.tsand export a client instance for it inlib/api/client.ts, then wrap the endpoints in alib/api/services/<name>.service.tswith types inlib/api/types.ts. - 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.