Building a Taxi app in the open — Part 1

Pieter Raubenheimer
5 min readJun 22, 2018

We can’t get enough of get-something-from-somewhere-now apps: Deliveroo, Uber Eats, Grindr, Tinder, and many others. Taxi apps, too, are huge, and it’s become quite a serious business. Uber has been working on self-driving cars for some time, and Daimler (Mercedes-Benz), pioneer of autonomous driving technology, actually owns mytaxi, the European taxi app that merged with UK start-up Hailo. Here in London there are so many to choose from: Gett, TaxiApp, Kabbee, Taxify and even old Addison Lee’s.

So why build another taxi app? I want to see what it would take. Having built a few mobile apps, and working on web platforms at scale, I know that there’s more to it than building a prototype as a side project. But what if we can simplify the concept to require almost no ongoing cost? Going as ‘serverless as possible’ on AWS, we can keep code to a minimum, we won’t need to pay when it doesn’t get used and it should scale beautifully if it ever needs to. To show how it works, we can do it all in the open.

We’ll call it OpenTaxi.

This series of articles, will take us through a prototyping process: designing, architecting and coding; including wireframes, deployment templates, source code (Python and JavaScript), and references to tools/documentation we used.

Our focus is not on optimising user experience, but rather on how efficiently we can build something end-to-end. We’re going to try to be innovative, so we are likely to make some mistakes along the way.

If you’re back for more, skip to Part 2 — Connecting Riders to Drivers.

The Concept

We need to keep it simple, so:

  1. We only allow licensed taxis. This avoids issues with safety and authorities. They typically need to display their taxi license certificate in the window and riders can verify this before they get in. (It should be no less safe than licensed taxis picking people up on the street.)
  2. All you need is mobile phone number to sign in. We can verify the number via SMS, which means the user doesn’t have to remember a password and we always have both driver and rider’s mobile number verified.
  3. We won’t take payment. Licensed taxis can already take payment.

A picture is worth a thousand words, so let’s start with some app wireframes:

Rider Flow

It would be very similar for new sign-ups and returning riders.

We’ll give the rider an option to filter on payment method. (Licensed taxi cabs in London must nowadays accept card payments, but their card machines are still sometimes ‘broken’. 🙄)

Driver Flow

For drivers we’d want to take some license details. The driver can toggle whether they are currently available and payment methods they support.

They may want to see the approximate area for requests coming in. We don’t want to show an exact location to avoid them bypassing the app, and multiple taxis scrambling for the same rider. The rider’s name, phone number and location should only be revealed to the one driver who wins the ride.

Since we aren’t taking payment, collecting the duration and route taken would be for the record only. I imagine users and authorities would be keen for us to keep this.

I think that’s enough for us to work with.

The Architecture

We’ll build the functionality incrementally and will try to always have it working end-to-end, using real infrastructure. To figure out where to start, I’m inclined to go for the area I feel most uncertain about. I’m fairly confident about the front-end user interface, now that we have some wireframes, so we’ll create the back-end service architecture first.

We already said that we want to use AWS ‘as serverless as possible’. I’m not going to make an exhaustive list of all the benefits of this approach, but here are some considerations:

  • Performance and scalability: As long as we avoid single points of failure and build using stateless components and proven scalable services, we’ll hardly need to worry about this.
  • Security: Using AWS IAM to limit access to resources and services at a high level of granularity and always giving the least permissive privileges, we can reduce the chances of creating vulnerabilities in our source code. By mostly relying on centralised configuration, controls are more transparent and emergency restrictions can be dynamically put in place.
  • Loose coupling: We’ll use asynchronous patterns where appropriate and assume eventual consistency wherever we can.
  • Availability and durability: This becomes a matter of configuration with most AWS databases and services, but still need to be considered up front.

We’ll explain more about our needs and choices as we go along. At a this stage we shouldn’t have all the answers yet. From experience, I’d say our stack could end up looking something like this, but let’s keep an open mind:

Next up: In Connecting Riders to Drivers we’ll get our infrastructure working.

--

--