Generating Swagger Client-side Code

The biggest advantage of having a formal description for a RESTful API is the ability to programmatically generate client-side code for calling the service. Unfortunately, it turned out that Swagger tooling still leaves much to be desired, at least for generating TypeScript Angular code.

Using the Tool

The tool is distributed as a jar archive and requires Java runtime to run.

Invoking it is straightforward and documented well enough:

  • Without any arguments, the tool will return a list of supported target languages:

      java -jar swagger-codegen-cli-2.2.2.jar
    
  • To generate code for an Ionic 2 application, I had to select typescript-angular2:

      java -jar swagger-codegen-cli-2.2.2.jar generate -i api-spec.json -l typescript-angular2
    
  • There's also a switch to output the generated files into a different directory:

      java -jar swagger-codegen-cli-2.2.2.jar generate -i api-spec.json -l typescript-angular2 -o ./api
    

Customizing the Generated Code

You can somewhat customize the generated code by passing a configuration file to the generator. You can find the documentation for that on GitHub. The available options depend on the target language. The tool can list them for you:

java -jar swagger-codegen-cli-2.2.2.jar config-help -l typescript-angular2

You need to put the options in a JSON file. I had to change the default camelCase property naming convention, because the generated code was broken when property names weren't already in camel case:

{
    "modelPropertyNaming": "original"
}

You can then include the config file path in your command line arguments:

java -jar swagger-codegen-cli-2.2.2.jar generate -i api-spec.json -l typescript-angular2 -o ./api -c swagger-config.json

Customizing the Templates

To further customize the code, you can replace the code generation templates with your own. Or even better, modify the existing templates instead of writing them from scratch.

You can find the templates for your language in the tool repository on GitHub. They are written using mustache - a templating engine that tries really hard to prevent you from putting any kind of logic into the templates. Still, I successfully managed to do many different types of modifications:

Getting all this working required some resourcefulness. E.g. to convert verb constants from Angular to IBM MobileFirst, I added a conversion method to the generated code:

private getVerb(method: RequestMethod): any {
    if (method == RequestMethod.Post) {
        return WLResourceRequest.POST;
    } else if (method == RequestMethod.Put) {
        return WLResourceRequest.PUT;
    } else {
        return WLResourceRequest.GET;
    }
}

I also found it useful to dump the models that are being passed to mustache templates:

java -DdebugModels -jar swagger-codegen-cli-2.2.2.jar generate -i api-spec.json -l typescript-angular2 -o ./api -c swagger-config.json

The code generated by the tooling is not perfect for all cases, but there are enough customization options available to tailor it for your specific needs. In spite of the effort required to generate code that worked for me, I still spent less time than I would if I had to write all the client code by hand. Even more so, because the API specifications tend to change quite often in my case.

Copyright
Creative Commons License