The Universality of APIs
The client should never ever decide how the server should response.
A few days ago, I was faced by the options to choose whether our API design should compromise its universality by changing the response in a non-standard format or stick with the original design. The need to change the API to the non-standard format came from one of its clients because they have some virtual restriction on how to process the response.
Let me explain that a little bit.
Recently, we have a project with one of telco companies here and we need to be able to open the API to talk to the SMS Gateway as well as IVR. We have defined a set of rules that should never be changed unless the end of the world is near. One of the API is a resource which can store the data into the database based on user’s SMS.
Let’s say that a user type these into their phone and send it as a text message to our server:
REGISTER John Doe#12345678#10-04-2002#Jakarta
and the user, John, will get a lot of information from the server like this:
Welcome, John Doe. It’s nice to meet you here and we welcome you to our brand new service. There are 102,452 people behind you waiting to access this service and can’t wait to join the new era of communication. Once again, congratulations on your joining today and here is your username along with a password. Username: johndoe. Password: johndoe123.
The backend will look something like this:
John Doe send a text message to a short number, 1234, and the phone will send it through MSC and SMSC. SMSC forward the packet to SMS Gateway and the SMS Gateway will forward the information to the server. The server’s response will be accepted by SMS Gateway and it will forward to the SMSC. SMSC to the MSC and finally, the user get the response from MSC. (Fiuh, what a confusing world we lived in).
So, why is it all related to the universality of APIs?
We discuss further on how to make a long response fit into user’s phone without even a single word being broken. As we’re already know, SMS is limited to 160 characters and we have the response exceeds this limitation, it will gonna break into two or more text messages. It’s fine. No problem with that.
The actual problem is that we don’t want to break even one word to be two pieces which became no meaning at all. Take as an example: welcome become wel come, communication become commun ication, and so on. This is not good.
So there comes the idea to break the long response into pieces and every pieces is no longer than 160 chars.
But how?
One of our team suggest that the server response would be something like this:
{
'status': 'OK',
'code': '200',
'data': {
'response': 'register_ok',
'response_txt': 'Welcome, John Doe. It\'s nice to meet you
here and we welcome you to our brand new service.
There are 102,452 | people behind you waiting to access
this service and can\'t wait to join the new era
of communication. Once again, congratulations
on your joining | today and here is your username
along with a password. Username: johndoe.
Password: johndoe123.
}
}
(If you noticed that I’m putting the pipe ‘|’ there, yes, you’re right. That is the separator for every 160 chars. Even though I didn’t put it exactly at the 160th char. This is just for illustration.)
This suggestion sounds very good and fix the problem. But be aware that this problem also break the API’s rule, universality (or in other term generality), and potentially create problems.
So what’s the problem?
So with the new API, the SMS Gateway is able to split the long response into pieces, each pieces has no longer than 160 chars. Everyone happy. The SMS Gateway is happy. The user is also happy (or maybe don’t care at all). But what about another third party app (such as Android or iOS client) that decided to use our API?
Yes, they have to split the response also. Or the proper way to do that is to strip the separator ‘|’ char from the response. But it’s not a proper way either. And suddenly, all third party clients questioning and complaining our API why in the world we always putting pipe in the middle of our response?
The Solution
The client should never ever decide how the server should response. We rolled back the API to the way it used to be –long response without the ugly pipe– and we suggest this simple function written in Python to solve the SMS Gateway problem:
def split_to_sms(txt):
results = []
txt_temp = txt
while len(txt_temp) > 160:
cut_pos = string.rfind(txt_temp, ' ', 0, 160)
results.append(txt_temp[0 : cut_pos])
txt_temp = txt_temp[cut_pos + 1 : ]
if len(txt_temp) > 0:
results.append(txt_temp)
return results
We put the code in the client (SMS Gateway) and everybody is now really happy (the user still don’t care though, the response is much the same as before.)
Problem solved without compromising the API’s design principle.