Code Monkey home page Code Monkey logo

Comments (5)

darraghoriordan avatar darraghoriordan commented on May 29, 2024

yea sounds like a great idea to me. I guess it would be an optional one to turn on though (not in the recommended rule set).

What swagger docs do you set in the @apiParam/@queryparam decorators? Descriptions and such?

from eslint-plugin-nestjs-typed.

SunsetFi avatar SunsetFi commented on May 29, 2024

It seems our usage of NestJS is falling through, so unfortunately I do not have the capacity to contribute these rules. However, for those who come after me, I can give a summary of our original intent.

The goal was to create linter rules that enforce enough metadata on nest controllers that sensible swagger docs would be generated. This proved to be a pretty complex problem, and quite a bit beyond my original post.

Our initial thought was to enforce that all @Param(name) instances have a matching @ApiParam(name, ...) entry (and same with @Query, and @Headers). Descriptions would certainly be a candidate to enforce but possibly a bit heavy handed for all use cases.

We would also have needed enforcement of @ApiBody wherever nest could not infer the type, which would be wherever arrays or non-class types were used for @Body annotated arguments. We would need the same with response objects, especially where the function returns a promise and nest cannot infer that. This could be something like requiring at least one @ApiResponse (or variant decorators). I remember there being a companion decorator to inform nest of the native return type for swagger purposes, but I am failing to find that in the documentation at the moment.

Even with that, we still had a problem of the hand-rolled validation logic not being kept in sync with the api decorators, so we moved onto using DTOs. This is because nestjs is nominally capable of generating swagger from the class-validator validation decorators on the DTOs. However, this would bring its own set of rules in order to ensure the process works correctly:

  • Ban all use of the name-variants of input decorators in favor of the bulk variety with DTO objects, eg @Param() params: MyRequestParamsDTO.
  • All types used for @Param() and @Query() must be class objects
  • All class objects used for @Param() and @Query() must come from a *.dto.ts, or whatever the nest cli is configured to target for automatic @ApiProperty generation.
  • For non-dto-class, non-primitive, or union properties, require an @ApiProperty decorator, as nestjs cannot process these.

All in all, the effort to enforce robust swagger on a nestjs app ended up being too high of a cost for adoption, and we ended up adapting an older library of ours for an openapi-first approach.

For anyone still looking to do this, the closest we got to unifying the swagger docs and nestjs validation was to abandon nest's class-validator validation altogether and use express-openapi-validator fed with nest's own runtime-generated swagger. This at least gave us a what the swagger says is what is enforced assurance, but the linter rules described here would still be essential in ensuring that the swagger is generated correctly.

I am closing this issue since we no longer have an interest or need for this feature, but hopefully anyone else seeking to wrangle swagger with nest can pick this up for inspiration.

from eslint-plugin-nestjs-typed.

darraghoriordan avatar darraghoriordan commented on May 29, 2024

Sorry you've probably already subscribed and this is unrelated to the issue so no need to reply if you don't have time.

But I'm keen to hear what you're using instead of nest? I work in consulting type stuff and havent used nestjs in a year at work i think. It's all NextJS or serverless these days?

from eslint-plugin-nestjs-typed.

SunsetFi avatar SunsetFi commented on May 29, 2024

So we had one big advocate for Nest on the team, but in the end the amount of effort it would take to get accurate OpenAPI specs and prevent misuse wasn't worth what switching over to it would buy us. OpenAPI accuracy and non-optional validation was a particular sticking point, as these are public APIs that need to be robustly validated, documented, and monitored for breaking changes.

We had already made a decorator-based controller library in the past to solve our validation woes with json schema, and it essentially produced OpenAPI specs as an afterthought. We took that design, kept the api, and inverted it. The decorators now directly generate OpenAPI describing the operation, with additional extension properties to record the handler function and positional arguments. Then the resulting spec is used to generate a router where all requirements defined by the spec are enforced before the handler method is called.

The new library lives at SunsetFi/simply-openapi for now, with GitBook documentation. There's a minimalist example, but I really need to put together a more significant demonstration showing off how the spec can be leveraged with regard to tests and linting. For example, we have jest snapshot tests being auto generated for all endpoints to capture any api changes, and we are using Spectral with a custom ruleset to enforce our API design guidelines.

It's framework agnostic, we have it running with an Inversify DI base right now, but as it essentially emits express middleware it can be used anywhere express is. The engine is very nearly generic enough to be abstracted to run on koa or fastly too, but that's not going to be a priority for a while.

from eslint-plugin-nestjs-typed.

darraghoriordan avatar darraghoriordan commented on May 29, 2024

hah this is interesting yea. i'm working on a client project at the moment and the team has a custom decorator open api spec generator for controllers. its for aws lamda handlers though.

we use zod for validation and use a zod to open api spec library for the open api model generation

Interesting how there is value in the spec but the breadth of javascript ecosystem means the tooling might never converge on one framework/implementation. good and bad i supose.

best of luck with the project anyways 🫡

from eslint-plugin-nestjs-typed.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.