Worst.API.Ever

Back when I was developing Android applications, the worst REST API I ever had to consume had a response that looked something like this:

[
	[true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false],
	[false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true],
	[true,true,true,false,false,false,false,false,false,false,true,true,true,true,true,true],
	[true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false],
	[],
	[false,false,false,false,false,false,false,false,false,false,false,false,false,false],
	[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],
]

Allow me to explain:

  • This API was used to retrieve available time slots in the upcoming week.
  • Each nested array represents a day in the upcoming week. So for example: If today is Friday, then the array at index 0 represents Saturday.
  • Each boolean in the nested array represents whether that half-hour time slot is available or not. The boolean at index 0 represents 8 AM.

I’ve attached a picture below to make the above explanation clearer:

Worst API Ever

The Android project used a tool to generate the client code and so there was no abstraction whatsoever. The UI code was working directly with this multi-dimensional array of booleans.

You don’t need me to tell you how ugly and complicated the code looked! There were for-loops all over to place to figure what the date was and what time slot each boolean corresponded to.

I just hoped I never had to touch the logic but I did and debugging could easily take days! There were no unit or integration tests in the project either!


At the time, I was working for a software agency and sometimes we had a little extra time on our hands.

We had a long term contract to maintain the application that consumed the API described above so I gave myself the task to add an abstraction layer. This is what I came up with:

public interface WeekSchedule{
	@NonNull
	Set<LocalDate> getUpcomingDays();

	@Nullable
	DaySchedule getScheduleForDate(@NonNull LocalDate date);
}
public interface DaySchedule{
	@NonNull
	Collection<TimeSlot> getTimeSlots();

	boolean isWeekend();

	boolean hasAvailabeSlots();
}
public interface TimeSlot{
	@NonNull
	LocalDateTime getStartTime();

	@NonNull
	LocalDateTime getEndTime();

	boolean isAvailable();
}

Implementing the abstraction took one day and then it took another day to get the unit tests coverage up to 90+%.

After that, whenever I had time, I’d pick a screen in the booking journey to refactor!

Getting rid of that mess felt SO good! Suddenly the code became readable and easier to maintain. I just love replacing large swathes of code with a simple line or two. The unit tests even brought to light a corner case bug though I can’t remember what that was.

Key Takeaways

I think this story highlights the importance of 2 things:

Investing time to come up with the right abstractions:

This involves understanding the domain and its terminology so that you can use it correctly in the code.

When I worked in Banking, studying the ISO 20022 standard really helped me come up with better abstractions.

Not all developers have worked in Banking, so I feel this story is a good one to help communicate developers the value of understanding and using domain terminology

API-First development approach

A discussion between backend and front-end on the API contract before any development would have been an efficient use of time.

Waqqas avatar
Waqqas
Principal Engineer