Files
baya-monorepo/dev/contracts/conventions/api-conventions.md
T
2026-06-28 21:59:59 +03:30

2.9 KiB

API conventions (read before writing or consuming any contract)

These hold for every Balinyaar endpoint. Per-domain contract docs assume them and don't restate them.

Base & versioning

  • Base URL from NEXT_PUBLIC_API_URL (client) / https://localhost:5002 (server default).
  • Versioned routes: api/v{version}/... (Asp.Versioning). Default v1.
  • All URL segments are snake_case (server SnakeCaseParameterTransformer). Controllers use [controller]/[action] tokens, so GetNurseProfile.../get_nurse_profile.

Response envelope (OperationResultApiResult)

Every response is the server's standard envelope, not a bare body. Success and failure share the shape; the frontend's clientFetch/serverFetch already unwrap it and throw ApiError on failure. Document each endpoint's payload (the data/result) and its failure cases. The envelope carries at least: a success flag, an HTTP-aligned status, a user-safe message, and the typed data (or validation errors). The canonical shape is defined by Baya.Application/Models/ApiResult + OperationResult<T> on the server — mirror that, don't invent a new envelope.

Status codes

  • 200 success (payload in data).
  • 400 validation/business-rule failure (field-level errors included).
  • 401 unauthenticated (missing/expired token) · 403 unauthorized (lacks permission).
  • 404 not found.
  • 409 conflict (idempotency / duplicate / state-machine violation) where applicable.
  • 5xx unexpected (generic safe message; details only in server logs).

Auth

  • Bearer JWE in Authorization: Bearer <token> (access token, ~15 min). Refresh via the refresh endpoint; rotation + reuse-detection apply. The client attaches the header automatically in clientFetch. State which policy/role each endpoint needs.

Localisation

  • The client sends the active locale (Accept-Language / x-app-locale, fa default). Server-produced user-facing messages should honour it. Reference data that has name_fa/name_en returns both; the client picks by locale.

Pagination (mandatory on lists)

  • Query params: page (1-based) + page_size (cap it server-side, e.g. ≤100). Response payload carries items + total (+ page/page_size). Document the default and max page_size per endpoint.

Idempotency (money & side-effecting POSTs)

  • Where stated, the client sends an idempotency key (header or body field) and the server dedups. Webhook endpoints dedup on the provider's external_event_id. Document which endpoints require a key.

Naming

  • JSON properties are the server's serialized casing (follow what NSwag/Swagger emits — typically snake_case to match routing, or the project's configured policy; derive the exact casing from the published swagger.json, don't assume). The frontend types match the wire exactly.

When in doubt about an envelope/casing detail, the published openapi/swagger.json is authoritative.