Software Teams: Is your app development DRY enough?

Don’t Repeat Yourself (DRY) is a common refrain in software development. Entire development stacks are built around this concept, like Ruby on Rails with its convention over configuration mantra. Our app development team strives to be as DRY as possible, and we’ve taken this concept to a higher level with Swagger Codegen and generating boilerplate across all components of our projects.

We learn from each web and mobile application we build, and we can iterate and improve our patterns and architectures. In my opinion, iterative learning is one of the best parts of developing at a service-oriented organization. You get to learn and grow with each app development project.

A drawback of working at web development companies like this is the amount of boilerplate that goes into starting a new project. Frankly, boilerplate is boring. The plumbing is necessary, but not necessarily fun. For projects with a server component and multiple clients (web, iOS, Android), this boilerplate can use up a lot of budget before you get to the interesting pieces.

What if you could just push a button and get all that initial boilerplate work done? You can! Using a combination of an OpenAPI specification and Swagger Codegen with some custom templates, you can skip the boring part of a new project, reduce the number of errors that repeating yourself can introduce, and get going on the  fun new thing you were hired to do.

Swagger Codegen

Swagger Codegen is an open source tool that can read an OpenAPI specification to generate server stub code and fully functional clients. There are dozens of template projects for most of the major languages and frameworks that a modern web or mobile app development project would use. We’ve found the template projects to be invaluable starting points for our own templates. The templates are also excellent resources to learn from, and they’re backed by a huge community of contributors.

We modified several community-provided templates to match our server, Android, iOS, and web architectures. Our initial templates were modest tweaks to the provided templates and were merely made to eliminate some of the tedious boilerplate work we do on each project. Over time, we’ve modified our templates to incorporate more of our core architectural patterns. Before each project, we spend time refining and improving the templates. You learn something with each project you do, and responding to those lessons in our Swagger Codegen templates ensures we actually enact those lessons moving forward.

Our development process for getting things started can be summed up in four main steps:

  1. Define your API with an OpenAPI tool.
  2. Generate your server stub code from the API defined in step 1.
  3. Expose an OpenAPI definition of your actual back-end API.
  4. Generate client(s) from your actual server OpenAPI definition (step 3).

Let’s take a closer look at each step.

Define your API

There are several tools out there to help design an OpenAPI compliant API without doing any coding. For our app development team, apicur.io works well. There are plenty of other tools to be found at http://openapi.tools/. We use apicur.io to define our base API routes and models. It’s important to keep in mind that this phase of the process is meant to speed up the pace of development. Don’t get bogged down in creating the perfect API definition. When you know the final functionality of the end product, this phase might be a fully fleshed-out API that both server- and client-generating code can use, but more likely the specification will be a rough approximation of the final API. Defining the models and endpoints enough to use the code generation in step 2 is the main goal at this point.

Generate Server Stub Code

Once your API definition is defined enough that further refinement is unnecessary, you can use your server template to generate server stub code. The Swagger Codegen templates aren’t going to provide much more than stub code, but creating your own template will allow you to flesh out more of the common components. Keeping with the DRY mantra, when you find the same code in multiple projects, make a note. If this code is going to be in most future projects, add it to your template.

OpenAPI Integration

Because our projects are typically custom applications, we often have to revise our initial API specification. It’s possible to skip this step if your API is fully fleshed out, but incorporating a way to generate your OpenAPI specification from the server code will make it much easier to keep your clients in sync. There are many options to incorporate an OpenAPI specification in your actual server API code. Once the project becomes a real thing, the API will usually evolve to meet new and changing requirements. Incorporating a way to generate a new OpenAPI definition as your API contract changes is essential for keeping clients in sync with the server.

Client Code Generation

The Swagger Codegen templates produce fully functional clients. As with the server code, there are templates for just about any language and framework you would use to create a client. We started with templates that generated clients close to our client architectures and tweaked to match our Android, iOS, and web application architecture.

Because our server generates a self-describing OpenAPI definition, we can re-run our client generation code each time changes occur. This cycle allows us to iterate quickly and continue to focus on solving the interesting problems each project presents instead of modifying the boilerplate each time the API evolves. Our clients also remain in sync with the server without having to manually check that each client has updated itself accurately.

Outcomes

We started the process of using the Swagger Codegen tools and OpenAPI specification to reduce the time and effort we spent on boilerplate. We tried having an actual boilerplate project to use as a starting point but found it quickly got out of sync with any lessons learned, and it was difficult to maintain in addition to our actual projects. We were also losing valuable time keeping up with minor API changes.

Using the code generation process with an OpenAPI spec as our contract has allowed us to move more quickly on new projects and to keep our in-development projects in sync across server and multiple clients. It has also allowed us to ensure the lessons learned from prior projects are propagated more quickly through existing and new projects. We can react and respond to client input and changing requirements more quickly and confidently.

Bonus Outcomes

The process has also resulted in a few surprise positive outcomes.

Moving to a new language or framework is a big task for a developer, and even more so for an app development  company like us. As I described in a recent post evaluating Flutter, I was able to use Swagger Codegen and a provided Dart template to make real API calls in almost no time. The code generation template was much better than anything I could have pieced together in the limited time I had, and I was able to move forward with what I really wanted to do, which was to evaluate building mobile apps with Flutter.

Another bonus is the ability to use the OpenAPI definition as a source for a mock server. In some situations, server and clients are under development simultaneously. This situation can cause frustration on both sides of the development equation. With a mock server, the defined API can be used to generate endpoints that clients can use while the server is built. Being able to work in parallel without stepping on toes has been a nice bonus feature of using OpenAPI and the Swagger Codegen platform.

Conclusions

The process explained above has transformed how we develop apps at 3Advance. We’ve moved the concept of DRY into our process for generating common architectural components across our projects. The ability to rapidly spin up projects with significant amounts of boilerplate work already completed has made us more efficient, and we can benefit from iterations in our core architecture. This means we are better able to focus on what our clients need. The process also allows us to change the API while both server and clients remain on the same page.

In addition to the benefits for our clients, development is more interesting. We can focus on the challenges of each project that are unique, novel, and most rewarding. Using the code generation also creates a more stable and consistent code base, making it easier for us to move across projects and have confidence that our core architecture is solid.


3Advance is an app development company in Washington DC that helps startups, non-profits, and other businesses turn great ideas into beautiful, simple mobile and desktop apps. If you’d like to learn more about how we can help you create a better way forward for your company, drop us a line. We’d love to hear from you.