92 lines
4.9 KiB
Markdown
92 lines
4.9 KiB
Markdown
# Installing product HTTP API versions
|
|
|
|
The product executable selects supported implementations in
|
|
`backend/product/app/profile/runtime.go`. Each entry maps a version name to an
|
|
`api.Installer`; v1 composes the existing authentication and second-factor
|
|
contracts. Adding an implementation requires a package and a registry entry,
|
|
without changing runtime installation code.
|
|
|
|
Select installations in the product YAML:
|
|
|
|
```yaml
|
|
api:
|
|
versions:
|
|
- version: v1
|
|
path: /api/v1
|
|
# Existing middleware, storage and notification configuration follows.
|
|
```
|
|
|
|
Only v1 ships today. Once a v2 implementation is registered, a second entry with
|
|
`version: v2` and `path: /api/v2` serves both versions in the same process. Each
|
|
version can be selected once. Unknown/unavailable versions, duplicate versions,
|
|
overlapping mounts, noncanonical paths and mounts occupying operational endpoints
|
|
fail startup. Paths must be absolute, non-root, without trailing slashes, URL
|
|
escapes, queries, fragments or router pattern syntax. Mounts use ASCII letters,
|
|
digits, slashes, hyphens, underscores, periods and tildes.
|
|
|
|
Omitting `versions` retains compatibility: v1 mounts at the path in the environment
|
|
variable named by `api.middleware.api_endpoint_env` (normally
|
|
`SXCHNGE_API_ENDPOINT=/api/v1`). An explicit `versions: []` installs no application
|
|
routes; process infrastructure and operational endpoints remain available.
|
|
|
|
The endpoint environment variable continues to locate the process health and
|
|
metrics compatibility endpoints, including when explicit application mounts are
|
|
used. With `/api/v1`, these are `/api/v1/health`, `/api/v1/metrics` and `/metrics`.
|
|
Keep this value unchanged when adding a version. Health is outside application
|
|
middleware; the existing HTTP collector excludes operational traffic. These
|
|
operational endpoints are reserved and are never version-owned contracts.
|
|
|
|
## Ownership and lifecycle
|
|
|
|
Runtime bootstrap opens shared stores once and injects those stores into the
|
|
customer service, auth flow and second-factor service. Notification connections
|
|
are opened once. Every installer receives the same typed dependencies and its
|
|
own router, validated mount, URL provider and logger. Installers register routes
|
|
relative to their mount and do not open or close process resources.
|
|
|
|
Auth v1 handlers, request DTOs and response mappers live under
|
|
`backend/product/auth/http/v1`; factor transport lives under
|
|
`backend/product/twofactor/http/v1`. Models, services and storage remain in their
|
|
owning features. A future version owns its wire contract and reuses domain
|
|
services, so changing its DTOs does not silently change v1. The generic runtime
|
|
and HTTP middleware do not import concrete API versions.
|
|
|
|
All version routers are built before any application router is attached. An
|
|
installer error aborts startup, preserves the cause and closes shared resources.
|
|
Bootstrap must either return a cleanup callback for resources it opened or close
|
|
them itself before returning an error; it must not do both. The built-in bootstrap
|
|
cleans its partial initialization internally. Runtime invokes an acquired cleanup
|
|
callback once, including on installation failure or repeated/concurrent shutdown.
|
|
The server retains ownership of the shared database factory.
|
|
|
|
The removed generic service registry and untyped runtime component lookup have no
|
|
product consumers. The typed dependencies and installer registry replace them.
|
|
This changes internal Go composition APIs; public v1 JSON and HTTP paths remain
|
|
compatible. No database migration is required.
|
|
|
|
## Cookies and links
|
|
|
|
Runtime binds browser cookie scope to the installed mount using request context.
|
|
Set and clear operations use the same `<mount>/accounts` path. The existing v1
|
|
path remains `/api/v1/accounts`; `/api/v2` would use `/api/v2/accounts`. Cookie
|
|
name, host-only policy, Secure, HttpOnly and SameSite settings are unchanged.
|
|
Changing an existing mount requires clients to authenticate at the new path;
|
|
cookies at the old path do not migrate automatically. Versions share domain
|
|
session state, so account-wide revocation continues to apply across versions.
|
|
|
|
`API_ENDPOINT` no longer overrides cookies globally. Direct standalone handler
|
|
calls retain their request-path fallback; installed APIs always use explicit
|
|
scope. Installers generate API links through `scope.URLs`, which combines the
|
|
configured origin and that installation's mount. The origin must use HTTP or
|
|
HTTPS with a hostname and optional port. Configured notification activation URLs
|
|
remain frontend links and are not rewritten as API links.
|
|
|
|
## Validation
|
|
|
|
Runtime tests exercise independently behaving versions, shared dependency identity,
|
|
disabled routes, invalid mounts, scoped links, cookie set/delete behavior, failed
|
|
installation cleanup and repeated shutdown. The existing Mongo-backed startup
|
|
test covers the default v1 installation on an empty database. Existing auth and
|
|
factor tests moved with their transports and retain their contract assertions.
|
|
Run `make test` and `make lint-backend` from the repository root.
|