February 24, 2016
The development team at PointSource has grown very fond of using Swagger to build our REST APIs. We developed code for Node.js to simplify the process of implementing the APIs when using a Swagger spec, and released that as BlueOak Server. This is fantastic for backend code, but what about the frontend? This article covers how we’ve automated using Swagger on the frontend, and eliminated the maintenance work associated with implementing the client side of REST APIs.
The majority of our projects are built using the AngularJS framework. In the past, we’ve used $resource and Restangular, as well as raw $http to communicate with the backend server, but doing so has drawbacks. $resource and Restangular both make assumptions about the structure of your API. $http, of course, doesn’t, but also doesn’t help you either, forcing you to write more code.
The common problem with all three alternatives is that none of them are connected to your Swagger API spec– if the API changes, you are responsible for making corresponding changes in the frontend’s API implementation. If your API is stable (such as when you’re using a third-party service), this might be okay, but while you’re developing an application, the API between your frontend and backend is often unstable. This can lead to being on a treadmill, trying to keep the frontend implementation in sync with the spec. Fortunately, there’s a way to make the frontend code swagger-matic too.
William Candillon created a tool called swagger-js-codegen that takes a parsed Swagger spec, and using templates, generates an Angular service with methods named after the Swagger APIs. You can then call those methods from elsewhere in your app to make backend server calls.
To illustrate how this works, I’ll use the Uber API example from BlueOak Server. The Swagger spec for that has several operations defined in it, broken up into multiple files, one of which is GET on /me. The relevant snippets are:
Note: All the code for this blog post is available here.
To compile the Swagger spec into an Angular service, you could invoke swagger-js-codegen like this:
In the example above, it uses another tool, swagger-parser, to read, parse, and validate the Swagger spec file. This tool supports reading Swagger specs in both JSON and YAML format (see Sean Kennedy’s 3 Best Practices for API Development with Swagger for why you should choose YAML instead of JSON).
After reading the YAML file, it uses swagger-js-codegen to create the Angular code, and then write it as a .js file. That .js file can be included in your project and will register a service called UberV1 that can be used to make backend calls.
Continuing with the snippet from above, calling GET on the /me REST API would look like this:
The beauty of this is that your frontend’s API implementation is now connected to the Swagger spec doc– if the REST API changes, you may need to make changes to the application logic that issues calls, but you never have to update the low level code that implements calls. In addition, there is validation logic included in the generated methods to ensure that required parameters (as specified in the Swagger spec) are actually provided on the call to the API, which helps ensure that your application logic stays in sync with the REST API definition.
Taking this a step further, we also integrated the code generation process into our gulp build system so that the Swagger spec is treated as a source artifact. We created a custom gulp plugin that we added to our build process that invokes swagger-js-codegen. This eliminates any possibility of the frontend code getting out of sync with the API spec.
Another feature of swagger-js-codegen is that it allows you to use custom templates to generate code. This provides a lot of flexibility to be able to use Swagger even on projects with special requirements. For example, custom templates could be used to tweak the HTTP requests or provide custom error handling. We take advantage of it in our projects by using a template that creates a singleton Angular service that can use an Angular config block to set the URL of the server.
Overall, at PointSource, using Swagger with the automation provided by BlueOak Server and swagger-js-codegen has greatly sped up our development process. It’s allowed us to spend more time on high-value features instead of maintenance work, which has been a big win both for our developers and our clients. To try it out, download BlueOak Server and visit swagger.io to get started!