#Making swagger show docs by version

27 messages · Page 1 of 1 (latest)

unreal ruin
#

I have enabled application versioning for my app and have decorated some controller methods with versions as well.
The problem is, when I go to the endpoint for the swagger api specification, I can see all endpoints of all versions and there's no way for me to filter by version...
Is it possible to achieve something like:

api/v1/docs -> swagger show all endpoints that are version 1
api/v2/docs -> swagger show all endpoints that are version 2
etc.?

charred badger
#

Have you tried doing something like this:

const apiOneOptions = new DocumentBuilder()
    .setTitle('API V1')
    .setDescription('The API v1 description')
    .setVersion('1.0')
    .addTag('ApiV1')
    .build();
  const apiOneDocument = SwaggerModule.createDocument(app, apiOneOptions, {
    include: [OneModule, TwoModule, ThreeModule],
  });
  SwaggerModule.setup('api/v1/docs', app, apiOneDocument);

  const apiTwoOptions = new DocumentBuilder()
    .setTitle('API V2')
    .setDescription('The API v2  description')
    .setVersion('2.0')
    .addTag('ApiV2')
    .build();
  const apiTwoDocument = SwaggerModule.createDocument(
    app,
    apiTwoOptions,
    {     
      include: [OneModule, TwoModule, ThreeModule],
    }
  );
  SwaggerModule.setup('api/v2/docs', app, apiTwoDocument);

```   ?
unreal ruin
#

I tried your suggestion, it just creates two endpoints (api/v1/docs and api/v2/docs) which both show all of my app endpoints regardless of which version they are

charred badger
#

later I'll try to experiment if I find a solution I'll write to you

unreal ruin
#

Thank you

charred badger
#

@unreal ruin if I understand you correctly you would like to do something like this( see screenshot), right?

unreal ruin
#

Yes

charred badger
#

ok so what you need to do was just use the code i wrote you above and then in each controller add something like this based on the api name:

@ApiTags('CatsApiV2')
@Controller({
   path: 'cats',
   version: '2',
})
#

I am attaching the example if you want in zip format ?

unreal ruin
#

But then wouldn't both tags appear in both docs?

#

You have to include the same modules in both of them

#

Also the problem is what if I want a controller to have 2 methods with different versions?

charred badger
charred badger
#

but it can help you understand how to set it up

unreal ruin
#

First thank you for your help, your example does work and is a way to do achieve what I said
The problem is as I said if I wanna have a controller that has two methods where one is V1 and the other is V2
If I include the module of this controller in a swagger doc it will show both the V1 and V2 methods
So I was wondering if there is any way to make that not be the case

#

Basically - seperation in the method level not just the controller level

charred badger
#

you mean like this :

#

@Controller()
export class CatsController {
  @Version('1')
  @Get('cats')
  findAllV1(): string {
    return 'This action returns all cats for version 1';
  }

  @Version('2')
  @Get('cats')
  findAllV2(): string {
    return 'This action returns all cats for version 2';
  }
}
``` ?
unreal ruin
#

Yes
And then have api/v1/docs show only findAllV1
And api/v2/docs show only findAllV2

charred badger
#

mmhh,I don't know if it can be done, there would be this way, but it still doesn't work as you say.

#
  constructor(private readonly catsService: CatsV1Service) {}

  @Version("1")
  @Get("cats")
  @ApiTags("CatsApiV1")
  findAllV1(): string {
    return "This action returns all cats for version 1";
  }

  @Version("2")
  @Get("cats")
  @ApiTags("CatsApiV2")
  findAllV2(): string {
    return "This action returns all cats for version 2";
  }

  @Post()
  @Version("1")
  @ApiTags("CatsApiV1")
  @ApiOperation({ summary: "Create cat" })
  @ApiResponse({ status: 403, description: "Forbidden." })
  async create(@Body() createCatDto: CreateCatDtoV1): Promise<Cat> {
    return this.catsService.create(createCatDto);
  }

  @Get(":id")
  @ApiTags("CatsApiV1")
  @ApiResponse({
    status: 200,
    description: "The found record",
    type: Cat,
  })
  findOne(@Param("id") id: string): Cat {
    return this.catsService.findOne(+id);
  }
}
unreal ruin
#

Yeah I understand

charred badger
#

Perhaps it is a feature that is missing, but I am not sure.

unreal ruin
#

Seems like it's not currently possible, maybe I'll make a feature suggestion on it and see

charred badger
#

It sounds like a good idea, it would be a nice feature 👍