Accessing custom attributes in Swagger Codegen

Introduction

Customizing your Swagger code generation is easier than you would expect. Adding new custom attributes into your specification file is easy as the OpenAPI spec knows the term extensions  or vendor extensions  which are basically custom attributes within your Swagger contract.

Hopefully you’ve read the previous parts of my Swagger Codegen with Gradle series, if you haven’t, make sure you do it before continuing.

Let’s check how the generated server-side stub looks like.

As you can see, we have ResponseEntity  for all the generated operations, but what if we don’t want that. How can we achieve this in the code generation process?

Extending the code generator

First of all, putting extension attributes  into the contract file has a rule, they have to start with x-  prefix. One could come out with a solution like the following

Note the only difference between the previous Swagger contract is that now we have the   x-responseEntity: true attribute for the POST  endpoint. That’s it. In this case we defined the endpoint to have the ResponseEntity  as a return type, all the others where it’s not there with a value of true , it will not be generated.

Now the remaining part is to adjust the template for the Api , the ApiController  and the ApiDelegate . Accessing the custom attribute from the contract within the template is done via the vendorExtensions  property.

Open up the api.mustache  in the template  folder and let’s change the return type part of the template to this

What this is doing is that first, it checks whether the value of the x-responseEntity  attribute is true , if yes then it generates the ResponseEntity  into the return type. However, if that’s false  or not provided the second part will be evaluated which purely just generates the return type of the operation.

The full content of the api.mustache  for me is this

Now we have to put the very same return type generation logic into the apiController.mustache  and apiDelegate.mustache .

Executing ./gradlew clean build install  in the contract project will result in the following generated code for the controller

As you can see, the getUsers  method doesn’t have ResponseEntity  anymore which is what we wanted to achieve.

The last remaining building block is to adjust the code in the payment-service and in the user-service to follow newly generated contract

Conclusion

We checked how it’s possible to put custom attributes into the Swagger contract in order to introduce some custom behavior into the code generation process. In this small example, we saw how to include or omit the ResponseEntity  from the return type on operation basis. It’s also possible to put other logic here, for example custom security checks, localization check and so much more.

The full code can be found on GitHub and if you liked the article or the series, make sure you share it with others. Follow me on Twitter for further interesting topics and let me know what you think about my writings.

3 Replies to “Accessing custom attributes in Swagger Codegen”

  1. i am using the sample Pet Store JSON file to generate the spring-boot based project. To add annotation such as @EnableEurekaClient in the generated code I am trying to use vendor extension in swagger file. Extensions name can be seen below as x-enableEureka in swagger defination.

    swagger: “2.0”
    info:
    description: “This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key special-key to test the authorization filters.”
    version: “1.0.0”
    title: “Swagger Petstore”
    termsOfService: “http://swagger.io/terms/”
    x-enableEureka: true

    I have modified the controller.mustache by adding below items. However, I am unable to access its value in generated Controller Class from either of the below statment.

    {{vendorExtensions.x-enableEureka}}
    {{x-enableEureka}}

    My intent is to use x-enableEureka as a condition.

    {{^vendorExtensions.x-enableEureka}}
    @EnableEurekaClient
    {{/vendorExtensions.x-enableEureka}}

    Similar way to access the vendor extension has been defined here. I am not sure why it’s not working.

    Can somebody please help me. I am not sure if I am placing the vendor extension at wrong place. I even tried to place that inside the Path block as well.

    Swagger Codegen Version 2.4.15

    Json FIle Path https://petstore.swagger.io/v2/swagger.json

Leave a Reply

Your email address will not be published. Required fields are marked *