ApiStruct: An API Wrapper with Response Serialization in Ruby
- 114607 views
- 4 min
- Apr 23, 2018
Application programming interfaces, or APIs, are frequently used in all sorts of applications, both web-based and mobile. The reason for using APIs is obvious: they provide ready-made pieces of code that implement certain functionality so you don’t have to build it from scratch.
Here at RubyGarage, we use different APIs to extend the functionality of the projects we build.
When working on Zanie, a Slackbot that connects people and fosters productive conversations, we needed to standardize our work with multiple APIs that we used. As a result, we came up with ApiStruct ‒ a Ruby gem that allows you to quickly create wrappers for APIs.
What is ApiStruct?
The idea behind ApiStruct was to build a single interface for communicating with different APIs. ApiStruct provides two main classes: ApiStruct::Client and ApiStruct::Entity. The ApiStruct::Client class is used for writing API wrappers (describing header parameter requests). The other class, ApiStruct::Entity, lets you serialize responses and use them in ORM-like style.
The gem is built upon several other gems:
- dry-configurable to implement gem configuration;
- dry-monads for response serialization;
- http for sending requests.
Benefits of ApiStruct
Here’s what makes ApiStruct stand out from its competitors:
- Flexibility. Most of ApiStruct’s competitors work only with REST actions. ApiStruct is more flexible than that: it enables you not only to use RESTful actions but also to describe requests to any URL with any set of parameters and HTTP headers.
- A single library. ApiStruct works as a library that enables you to build interactions with different APIs. Thus, you don’t need to write the codebase from scratch. Instead, you can use a ready-made template to describe API endpoints.
- A single configuration file. When you start working with multiple APIs, you need to write the logic that will implement a certain task. ApiStruct provides a single configuration file for working with other APIs. In this configuration file, you can write specifications for each separate API, such as route URL and headers. ApiStruct lets you configure all the APIs it will work with, specify the data you’ll send and receive (like JSON), specify the tokens necessary for authorization, and more.
- A basic Ruby gem. Last but not least, ApiStruct can also work as a basic library for your project – for instance, when you need to write a new wrapper for a new public API because it doesn’t have its own official gem yet. With ApiStruct, you can easily code that public API.
Who is ApiStruct for?
ApiStruct can stand you in good stead if you use a microservice architecture and interact with a large number of internal APIs. To spare some time, you can use ApiStruct as a ready-made solution for building an interface for all the APIs involved in your project without having to write your own solution.
On top of that, you can use ApiStruct as basic classes for describing requests to make your code more readable and to lower the barrier to entry for newcomers to your project team.
Let’s see ApiStruct in action
Now let’s consider a use case that demonstrates when and how you can use ApiStruct. Let’s assume you have a News API that indexes articles from popular news sources like Business Insider and BBC News. This API has no official gem, so if you require the API for your project, you’ll need to write a wrapper for it.
Below, we describe the whole process of writing a wrapper for the News API.
- Initialize a new gem:
- Add api_struct to the dependencies:
- The News API provides three endpoints. Create a lib/news_api/clients/ directory and describe each endpoint inside the directories by inheriting from ApiStruct::Client
- Next, write serializers of API responses by inheriting from ApiStruct::Entity and specifying the clients you’ve created before with the help of the client_service method:
- For nested arrays in responses that are present in several endpoints, let’s put repeatedly used entities in the lib/entities/ directory:
- To add a configuration, let’s add the the dry-configuration dependency to the gem and provide an opportunity to specify the api_key:
- To load the written files, require them in lib/news_api.rb.
Congratulations, your Ruby gem is ready to use!