The unreasonably easy (and a little dirty) way to create an API client
APIs
APIs are all the rage nowadays: every service should present a clear interface to interact with.
This makes sense: an API allows you to reach out to new customers and partners, and — in best case scenarios — to create a vibrant community based on your product.
However, designing and implementing a good API is a challenge. Exposing “your” service to the rudeness of the internet takes some courage and has to be planned and executed carefully.
And then, when your API is here and ready to be used? Nobody will flock to it, if you don’t give them an intrinsic motivation to do so. So either you have to go big (e.g. like Azure) or you have to foster a tight-knit community.
API Clients
Thankfully, the client side looks way simpler: if your API is well described (e.g. OpenAPI), it is easy to create a client with the appropriate tools:
- https://editor.swagger.io/: creates clients and servers in a dozen of languages
- https://raml.org: another toolbox (which I don’t have much experience with)
And I see efforts to create more “ready to go” API clients in different languages.
What if an API is not well documented, and there is no reasonably implemented client in your language? First: shame on them. Then: If it is in JSON format at least, you still might have chance:
An API client, the fast way
- Get a json which describes a request or response as completely as possible
- Go to api.quicktype.io and generate your kotlin classes
- Tweak those classes and make them easily serializable with kotlinx.serialization
- Use khttp to create a simple http client in kotlin
- Do awesome stuff
Let us go through an example step by step:
(Step1) We build a very basic client for the Azure Text Analytics services. An example query json would look like this:
Response example:
(Step 2) api.quicktype.io generates the following classes:
The response classes:
See the name clash between request and response classes? There is a Document class in both. We simply renamed the response class to ResponseDocument. And since errors is not specified, Any is used there. We change this to String for the time being, since it should be serializable.
(Step 3) Define the classes to be @Serializable.
It cannot be overestimated how easy kotlinx.serialization makes working with kotlin and json in an interchangeable way. There is literally no friction between those two worlds.
(Step 4) Create the communication part of the client
khttp makes it easy to implement the communication aspects of our client. The barebone method looks like this:
I used my own instance of an Azure Cognitive Service, go to portal.azure.com, create your own and be started. The free tier easily gets you through your first steps.
Summary
No schemas or semi-cooked API clients were hurt for this blog post. I presented a quick and fun way to explore APIs using some technologies that work well together. APIs are the cornerstone of a service oriented IT landscape, and being able to work with them is one of the most important skills for any IT developer and engineer.
And now have fun, and find out what the sentiment of the following phrase is:
“I actually don’t feel too shabby today”
(Hint: sarcastic understatement is not detected yet….)