God speaks to us in various ways… we should know how to parse all of it

Kaushal Shubhank
Roposo Engineering
Published in
4 min readMay 30, 2017

As we have been discussing in our posts, we have so far built the server side of Roposo with Play Framework. In the beginning, we were using the Scala templates for front end and we hadn’t yet launched our mobile apps.

So guess what, NO APIs! All the html was formed in backend and sent across to browsers.

We started working on APIs when we started developing our android app. We thought of different approaches that would help us follow best practices in API development. At the time, we had only two people developing the app (one of them being a founder). So any time spent on repetitive things was very costly.

The idea of individual visual cards that bunched together make a screen was picking up. Most android apps had implemented modular and consistent design with cards.

We couldn’t, however, find examples of apps that were using a modular card-like way of sending card information in the backend APIs.

When sending data for these cards, we wanted our app to be able to simply draw infinite types of screens with infinite cards instead of treating different screens as totally different views that had to be put together. We wanted to be able to draw an array of cards on different types of views without any extra effort.

The API examples that we saw at the time could be categorised in two :

  1. The app knew what cards were to be drawn on a given screen. All the data for a screen was being sent in one API call. The app drew cards after picking the required information from such API calls.
  2. The app knew what cards were to be drawn on a given screen. Data for different cards was being sent in different API calls. The app drew cards sequentially after getting data from different APIs.

The common problem with both these approaches was that the app needed to be aware of the structure of the screen. So any change in the arrangement of cards was only possible with changes in the app. We wanted the control to be with backend, so we could try different things in one release and also personalize views for users.

We decided to make JSON blocks for every card type. These blocks contained all the data that would be required to draw that card.

The response to draw the above screen would be something like this:

{
"blocks": [
{
"title": "Superhero #OOTW",
"creator": {"n": "Batman", "alias": "Bruce Wayne"}
},
{
"title": "a",
"creator": {"n": "Batman", "alias": "Bruce Wayne"}
}
],
"next": "/featured?start=2&count=2"
}

As we can see in the example above, there are two batmen (but at one time, like God there should be only one batman). With bigger responses, there was a lot of repetition. To optimize this, we broke the blocks into a dictionary kind of formation — blocks and det — blocks keep the keys of the cards in a sorted fashion and det are the details for that key. The response would become something like this.

{
"blocks": [
{
"title": "Superhero #OOTW",
"creator": "ID"
},
{
"title": "a",
"creator": "ID"
}
],
"det": {"ID": {"n": "Batman", "alias": "Bruce Wayne"}},
"next": "/featured?start=2&count=2"
}

We modified everything to send similar responses to all APIs.

A bitter-sweet moment came when we saw our feed coming in our shop section! Happened because of a stupid bug where responses were being overwritten across two controllers (epic fail). But our feed worked flawlessly with infinite scroll and ATM (all time modifiable) views ;).

We also modified our tabs APIs to make them modifiable without app releases. Any response could give information about tabs, details about each tab and flag for the current tab.

Tabs in the Profile View

We optimized this further by sending the data in det-blocks for the current tab to save an API call. It was now effortless to create a tabbed view within a view based on the response.

{
"ontab": 1,
"tabs": [
{
"link": "/url/to/posts",
"title": "Posts"
},
{
"link": "/url/to/reposts",
"title": "Reposts"
},
{
"link": "/url/to/activities",
"title": "Activities"
},
{
"link": "/url/to/lists",
"title": "Lists"
},
{
"link": "/url/to/liked/posts",
"title": "Likes"
}
]
}

We recently introduced Roposo chat via XMPP. Guess what, the responses (or messages) follow our dictionary det-block pattern as well. So we can send any kind of view cards not only through http APIs, but also XMPP messages and push notifications!

Days of future past

We are now planning to send commands, status, other meta via these blocks of information in addition to viewable cards. For example, a message or response could be sent to the app to refresh feed (which may not be the current view of the user) and notifies the user of the availability of the new content.

We could send such messages bundled with some other API’s response. For example, in the response for one profile’s data, we could slip in a block (that the app knows is a non-viewable command-block) and avoid extra chatter between the app and backend server.

In conclusion, this approach has helped us in A/B testing and increased efficiency in app development. With very little effort, we can create a generic app that needs to be told only the first API to hit and can then draw multiple complex screens from a combination of very few types of cards.

--

--