Beyond REST. Reduce development time by using type safe code generation
In the last decade, with the advent of mobile apps and rich internet applications written in Ajax, the world has moved forward from the previous generation of XML-based SOAP Web Services, CGI and backend generated HTML pages. REST + JSON has quickly become the new standard to interact with modern web servers.
Many times, when a new project is started, the backend and the web frontend are developed together. Environments like Node.js have allowed frontend developers to step also in backend development and create both the APIs and the frontend with a single language. Wonderful.
After that, some mobile developers are hired to complete the awesomeness and that’s when the magic begins 😁
The backend is ready, we already use the APIs in the frontend. You will only need to check our docs, make some requests with Postman to have an idea of the data structure and that’s all, the heavy lifting has been done for you!
All it’s left is pure fun!
That’s what they say 😄 until you poor mobile developer discover some fancy stuff like this:
This is completely fine in a dynamic world where every JSON field can be everything, but that plan field which can be both a string and a boolean in this case will cause some serious issues 😵.
OkHttp + Retrofit on Android or Alamofire + SwiftyJSON on iOS allows you to save considerable time writing a REST client, avoiding you to write boxing, unboxing and type validation manually. In this case however, you will see a type-safe error when you make the network call, which will crash your app because of the plan field. This is one of the most annoying things in mobile development, as it happens at runtime, during a sunny Sunday which can quickly become an inferno.
A little unnoticed backend deploy with a change like this can break your hardly reached 100% crash-free statistics in minutes. Good luck in recovering from 1 star ratings and answering to angry customers which paid for your awesome non-stop service and want it working NOW ⚡️ 😠 !!
- Your frontend friend ❤️
Until an user opens the cool frontend dashboard and sees something like this:
Uncaught TypeError: Cannot read property ‘value’ of undefined
Type safety would have saved the frontend from this error. You know that starting a language or platform war is not the solution, but caring about variable types is really important even in dynamic languages. This article explains it well.
We are engineers, we solve problems 💪 and we already have plenty of them to deal with, so why do we have to create them between us 🤔?
Sometimes, thinking about the ideal world can be illuminating, so let’s do it!
What do we want from the ideal mobile backend?
- Guaranteed type safety
- Guarantee that the docs are always aligned with the actual implementation, because resorting to Postman every time is time consuming and frustrating, and lowers the trust in our backend colleagues
- Not having to write a lot of boilerplate and manual checks to map requests and responses. We want to write the data structures in a single point and automatically generate the required mapping code for backend, frontend and mobile
- Easily spot API signature changes at compile time. If a backend buddy changes a type from string to a list or adds a new method or field, we want our cool IDEs to help us while we are developing, with some errors and warnings.
- Ensured retro compatibility, so if a client does not get updated after a backend change, it will continue to work without crashing
- No communication overhead between server and clients and no time-consuming meetings just to evaluate the impact of a new change. Simply make the change, spin up the CIs and see if everything is ok.
- Use the so-called
dot-clickprogramming and have our IDEs list all the methods available on the server by writing
apiClient.This saves a huge amount of time and adds confidence
- Be able to start the client-side development in parallel with the backend development, to be more productive. No more time spent waiting for the backend to be implemented before starting the client. No more JSON stubs full of errors.
- High level of backend scalability and performance
- Less bandwidth used to send and receive data, compared to JSON
Hey man, you’re not living in the ideal world, you want the impossible, get back to reality! 😆
Maybe you should step in the reality, my friend, I have something to show you, which fulfills all of the above! 😎
Please welcome Apache Thrift!
Thrift is a lightweight, language-independent software stack with an associated code generation mechanism for RPC. Thrift provides clean abstractions for data transport, data serialization, and application level processing. The code generation system takes a simple definition language as its input and generates code across programming languages that uses the abstracted stack to build interoperable RPC clients and servers.
Thrift makes it easy for programs written in different programming languages to share data and call remote procedures. With support for over 20 programming languages, chances are Thrift supports the ones that you currently use.
Initially developed by some brilliant engineers at facebook, Thrift has been donated to the Apache community and it’s on GitHub, free for you to use and contribute to! Here you can see the original paper.
This, in turn, has allowed a great community to flourish and some great guides to be written, like:
- Thrift: The Missing Guide by Diwaker Gupta and
- The Programmer’s Guide to Apache Thrift by Randy Abernethy.
Thrift is much more than what I’m about to show here, so I strongly encourage you to discover more about it. I have to thank Matteo Brancaleoni, which was the first one to introduce it to me.
Ok, enough talking, show me the awesomeness!
Let’s create a ToDo list app for iOS and Android with a Thrift backend
The backend will be coded in Kotlin, which is a great language, 100% interoperable with Java and which syntax is very similar to Swift. Thrift runtime for Java backends is really well done and we won’t need an Application Server.
Stay tuned for the full tutorial and source code, which will be available for you to try and play on GitHub!
Thanks to all the people who dedicated a bit of their time to review this article, your feeeback was very precious. Thank you ❤️