NestJS defaults to code-first OpenAPI where decorators like @ApiResponse are runtime metadata that TypeScript never type-checks, allowing controller return types to silently drift from the spec. This post demonstrates a spec-first alternative: using the Hey API nestjs plugin (contributed by Evil Martians) to generate TypeScript interface types from an OpenAPI spec, then using the `implements` keyword on NestJS controller classes to get compile-time enforcement. The approach requires switching from per-field parameter decorators to whole-object style (@Param() path instead of @Param('id') id), but in return the build fails immediately when a controller no longer matches the contract. Runtime validation and routing decorators remain unchanged.

9m read timeFrom evilmartians.com
Post cover image
Table of contents
Other parts:NestJS teaches you code-first, and it works (until it doesn’t)The decorator layer is documentation, not enforcementWhat if the spec came first?Generate controller method types from the specimplements: the compiler becomes your contract enforcerWhat this doesn’t do (and why that’s fine)Where this fits in the contract-first stack

Sort: