diff --git a/README.md b/README.md index ebcc0f2..b3159b4 100644 --- a/README.md +++ b/README.md @@ -67,20 +67,14 @@ Security notes: - Replay protection is enforced by deduplicating `eventId` values in the ingestion service. - Duplicate deliveries are treated as safe no-ops and return `202 Accepted`. -## Prometheus Metrics +## API Versioning Policy -The backend exposes a standard Prometheus metrics endpoint at `GET /metrics`. +All new features and endpoints must be mounted under the `/api/v1` prefix. -- **HTTP Metrics**: Tracks request duration, error rates, and throughput (labels: `method`, `route`, `status_code`). -- **Custom Metrics**: Includes `job_sync_lag_seconds` to track background processing delay. -- **Default Metrics**: Standard Node.js process and runtime metrics (GC, memory, CPU). - -### Security - -In `production` Environments, the `/metrics` endpoint is protected by a Bearer token. -- Set `PROMETHEUS_AUTH_TOKEN` in your environment. -- Clients must provide `Authorization: Bearer `. -- In non-production environments, authentication is bypassed for easier debugging. +**Deprecation and Sunset Policy:** +We use HTTP headers to signal end-of-life for specific API versions: +- `X-API-Version`: Indicates the current version of the API responding to the request. +- `Deprecation`: A boolean flag (`true` or `false`) indicating if the API version is deprecated. When `true`, developers should migrate to a newer version as soon as possible. ## Scripts diff --git a/src/api/v1/router.ts b/src/api/v1/router.ts new file mode 100644 index 0000000..727fa09 --- /dev/null +++ b/src/api/v1/router.ts @@ -0,0 +1,16 @@ +import { Router, Request, Response, NextFunction } from "express"; +import streamsRouter from "./streams"; + +const v1Router = Router(); + +// Global middleware for v1 APIs +v1Router.use((_req: Request, res: Response, next: NextFunction) => { + res.setHeader("X-API-Version", "v1"); + res.setHeader("Deprecation", "false"); + next(); +}); + +// Mount existing streams logic +v1Router.use("/streams", streamsRouter); + +export default v1Router; diff --git a/src/index.ts b/src/index.ts index 7958f3a..b3f0f1a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,8 +4,7 @@ import cors from "cors"; import express, { Request, Response } from "express"; -import streamRoutes from "./api/v1/streams"; -import { metricsMiddleware, metricsHandler } from "./metrics/prometheus"; +import v1Router from "./api/v1/router"; import indexerWebhookRouter from "./routes/webhooks/indexer"; @@ -23,7 +22,7 @@ app.get("/health", (_req: Request, res: Response) => { res.json({ status: "ok", service: "streampay-backend", timestamp: new Date().toISOString() }); }); -app.use("/api/v1/streams", streamRoutes); +app.use("/api/v1", v1Router); if (require.main === module) { app.listen(PORT, () => {