Skip to content

feat(interceptors): add ResponseValidationInterceptor for response DT…#31

Open
Chrisbankz0 wants to merge 1 commit into
BlockDash-Studios:mainfrom
Chrisbankz0:feat/public-api-schema-validation
Open

feat(interceptors): add ResponseValidationInterceptor for response DT…#31
Chrisbankz0 wants to merge 1 commit into
BlockDash-Studios:mainfrom
Chrisbankz0:feat/public-api-schema-validation

Conversation

@Chrisbankz0

Copy link
Copy Markdown

#closes
#26

This PR adds runtime response validation for public API handlers to prevent undocumented response shape drift. It introduces a small opt-in system where controller handlers or controllers can be decorated with @ResponseDto(...) and responses will be validated against the DTO class at runtime.

Key changes:

  • Add ResponseDto decorator to mark expected response DTOs.
  • Add ResponseValidationInterceptor to validate outgoing responses.
  • Register the interceptor globally in main.ts.
  • Annotate UsernamesController handlers as an example.
  • Add unit tests for the interceptor.

Files of interest:

Motivation

Controller implementations, DTO definitions, and OpenAPI documentation can drift over time. This PR provides a small safeguard that fails fast when runtime controller responses no longer conform to their declared DTOs, reducing integration bugs between frontend and backend and preventing client runtime errors.

Implementation details

  • ResponseDto is a metadata decorator (uses SetMetadata) to attach a DTO class to a controller or handler.
  • ResponseValidationInterceptor reads that metadata, transforms outgoing payloads into the DTO class instances using class-transformer, and validates with class-validator. If validation fails, an InternalServerErrorException with code: "RESPONSE_VALIDATION_ERROR" is thrown.
  • The interceptor is registered globally so it runs for all requests; only routes annotated with @ResponseDto(...) are validated.

How to test (step-by-step)

  1. Install dependencies (if needed):
pnpm install
  1. Run backend unit tests (includes the new interceptor spec):
cd app/backend
pnpm test:unit

Expected: tests pass. The spec includes a positive case (valid response) and a negative case (missing required fields causing a validation error).

  1. Run the backend in development mode and exercise annotated endpoints manually:
pnpm --filter ./app/backend dev
# or from backend folder:
cd app/backend && pnpm dev
  1. Call an annotated endpoint (e.g., GET /username) and confirm normal responses remain unchanged. If any annotated handler returns an invalid shape, the response will be a 500 with body { code: "RESPONSE_VALIDATION_ERROR", ... }.

  2. To add more coverage, annotate other controllers with @ResponseDto(YourDto) and add unit/integration tests asserting that invalid shapes fail.

Backwards compatibility & migration

  • This is opt-in: only routes annotated with @ResponseDto are validated. There is no breaking change for unannotated routes.
  • For DTOs that are plain interfaces or only use @ApiProperty without class-validator decorators, convert them to classes and add minimal validation decorators (or extend the interceptor later to read OpenAPI metadata).

Security & performance

  • Validation uses synchronous class-validator calls during the response path. For endpoints returning large arrays, you may want to limit array-size validation or move checks to background jobs. Current implementation validates arrays by checking every element synchronously.

Checklist for reviewers

  • Confirm the interceptor is registered in main.ts and does not interfere with error handling pipeline.
  • Verify the ResponseDto decorator metadata is read correctly for handler and controller-level annotations.
  • Ensure unit tests cover positive and negative scenarios.
  • Consider adding controller annotations for other public API modules (transactions, stellar, etc.).

Rollback plan

Revert the commit(s) or remove the global interceptor registration from main.ts to disable runtime response validation while keeping the decorator and tests for follow-up work.

Related issues

  • Implements part of API contract enforcement from the API stability task (ensure responses match OpenAPI/DTOs).

If you'd like, I can annotate additional controllers with @ResponseDto(...) and/or extend the interceptor to validate against OpenAPI schemas for DTOs that are not classes.

@MaryammAli

Copy link
Copy Markdown
Contributor

@Chrisbankz0
run
npm run build and npm run test to fix errors

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants