Lets start with the deepest level of our frontend application, and make our way upwards.

As a team, discuss contracts for a specific API, and document these contract discussions in Swagger Once the Swagger contract has been written out, run a command (implementation details below), to generate models (and potentially services) for the API Once the models are generated, the service can deserialize JSON responses from the API into models that can be consumed by your frontend application These models are strongly typed, and promote consistent and robust interactions between your app and its consumed API Updates to existing contracts are simple as well: Simply re-run your command to fetch the latest and greatest models These models can be gitignored to avoid code bloat, and generated on the fly during app startup

NOTE: Looking specifically at the frontend architecture, you’ll notice a Redux stack leveraged in the overview. There is no specific requirement to integrate with Redux; your components can directly interact with your services (but I would definitely recommend some level of state management on your FE application).

Implementation

For this post, we’ll be using swagger-js-codegen to support our push to generate models on the fly. Out of the box, this package offers you the ability to consume Swagger documents to generate Node/React/Angular/Typescript models. As mentioned above, for the purpose of this post, we’ll be focusing on Typescript models.

To get started, here’s a basic implementation of swagger-js-codegen.

Going from the top down, here’s a summary of what that code does:

Import the appropriate packages for reading/writing to files and the actual Swagger code generator Reference the path to the Swagger file and read it Generate a Person model off of the Swagger spec Write it to a new Person model file and a reference to that model in the index file (optional)

This approach seems relatively straightforward, but let’s try adding some complexity to the mix.

Situation: We’re dealing with YAML files for our specs, and the output models need some additional customization. Lets use the YAML file below as a reference.

The YAML file above has a GET on a person API, that returns a list of persons. We have 2 definitions defined, one for Person, and one for Address.

We need to modify our code generation script to cater to YAML files, and then work with multiple definitions.

Let’s run through code from the top again:

In addition to the packages mentioned in the basic setup, we’ve added a package for YAML parsing. This yields a Swagger object that we can filter through Iterate over the the list of definitions, and generate a custom model, leveraging CodeGen’s getCustomCode() function This function optionally takes a mustache template, that allows for fine-tuning of the generated model Once done, write each generated model to disk

A sample mustache template is defined below. This template allows us to fine-tune the generated model, to cater to styling, specific utilities, attributes etc. that we want to apply to each model that is generated.

This template constructs the basic model, with a constructor that maps out all props and a deserializer that maps JSON to the created model.

For reference, the deserializer referenced as an interface above is included below. This interface assists in deserializing the supplied JSON to an object.

Execution

This example leverages npm for package management, although Yarn or other flavors are certainly usable. Once the app is setup with a Swagger spec, the codegen script, a mustache template and the deserializer, we should be all set to generate a basic model. The script can be triggered with an npm command. We can start by registering an npm task to do this:

The generate-models command spins up node and runs the codegen-yaml-template.js we defined above.We’ve also included a postinstall task to ensure that these models are generated after all our dependencies are installed, but before app startup. Once the node instance completes, you will have a new Person model available for consumption.

Next Steps

The post above provides you with a basic approach to hit the ground running with model generation using npm/Typescript/Swagger. While this post should provide you with a sufficient foundation in generating Models from an API contract, complex Swagger definitions can add complexity to the script that generates your models.

For example, in the Swagger above, Address is a custom model that is referenced as a property on Person. In order to deserialize Address on the Person model, the script and mustache templates need further customization. With the current setup, Address will be deserialized as a plain Object (in Typescript land, the library will cast this object to type any).

swagger-js-codegen can also be used to generate your services. The tools use the APIs defined under the paths section of Swagger to create services. Using the Swagger defined above, we can generate a service to fetch a list of Persons.

Similar to the customizations documented for models, we can also leverage mustache templates to fine-tune our generated services.

While this setup may seem tedious, developers will find this level of automation very useful. This tooling helps reduce dev hours, as well as errors that could be incurred by manually writing out models from a Swagger contract.