Document your express API with swagger annotations

    Have you ever wanted to have a swagger documentation for your express API based on annotations? I have. And unfortunately didn’t find any way of doing it without having to manually create a swagger.json file. My wish was simple as this: I want to have a clean express app with multiple endpoints and I want to keep swagger documentation for every endpoint close to the endpoint implementation, not in a separate file.


    Maybe I’m just lacking some google skills, but I decided that it’d be much easier for me to create such a tool. And here it is: mgr-swagger-express


    Getting started


    Example here will be written in TypeScript, but the same can be done in Javascript project.
    So imagine a classical express app:


    image


    Here we have a resource “Book” and a some basic CRUD endpoints. The question is “How would you add a cool Swagger documentation to this API?” I really wanted to do it using annotations in order to keep every endpoint documentation close to the endpoint itself.


    This is what you’ll be able to do with mgr-swagger-express:
    index.ts:


    image


    BookService.ts:


    image


    There is a bot more code, but now we have all swagger documentation laying near the endpoint itself.
    Let’s see what’s happening here:


    • In index file, we create out express app, as usual. Also we have to initialise all middlewares (the bodyParser being the most important).
    • After this we call the SET_EXPRESS_APP to set the app object globally. This way mgr-swagger-express will be able to attach handlers to endpoints
    • Only after this we can import the service with annotations. It does not have to be a class, it could be just functions.
    • Then we create an instance of our service (or call an init function in case of not using classes)
    • And we generate swagger config based on all of the annotations we have in the project and attach it to our app using swagger-ui-express package

    Inside the service, there are multiple things going on, but let’s stop on a couple of them only. Everything else you can easily find in the mgr-swagger-express repo:


    • In the constructor we call addSwaggerDefinition function. It registers a swagger model with a given name. in our case we define BookDefinition under a Book name in order to reference it afterwards by #/definitions/Book
    • All handlers are annotated with @GET @POST @PUT @DELETE commands. All of them are taking in arguments an object of type SwaggerEndpoint:
      path: string;
      auth?: string;
      description?: string;
      tags?: string[];
      parameters?: SwaggerURLParameter[];
      query?: SwaggerQueryParameter;
      body?: SwaggerBodyParameter;
      success?: SwaggerSuccessResponse;

      It’s basically the classical swagger endpoint definition object, nothing special, except for the auth field, but I’ll come back to it in the future


      All handlers should have the following signature:
      (args: object, context: Context) => Promise<any>

      The args object contains all parameters pathed to your endpoint. It can be URL parameters (like book_id in our example), query parameters or even body value.



      The context object is used for handling authentication and security, but again, about it later.


      Conclusion


      Now we have a simple CRUD express API annotated with Swagger and a beautiful swagger UI, where all Swagger definitions are laying nearby the endpoint implementation. As usual — always glad to have any feedback! ️

    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 3

    • UFO just landed and posted this here
        0
        I never thought about VSCode extension for this thanks! Will think about it.
        For the generation of swagger endpoint definition based on a function signature — it's not that easy. I wanted to to this in the beginning but then ended up with the existing solution. So now instead of getting SwaggerEndpointDefinition from signature (which should be edited to allow some additional information like shape of the body object, parameters in URL or query, etc etc etc) this definition is done manually in JSON and then your method signature looks almost like in GraphQL: list of arguments coming from any source (body, url, query) and a context (for auth flow) and a request (not implemented yet, will be implemented in future as I need it now for my projects)

        Tree-based API navigator — cool idea as well. Will think about VSCode extension fo this, thanks :)
        • UFO just landed and posted this here

      Only users with full accounts can post comments. Log in, please.