Driving Through Domains: A Deep Dive into Uber/Grab’s System with Domain Driven Design (Ver. Eng)

Navamongkol Tongta
ABACUS digital
Published in
6 min readMay 8, 2024

--

Hi! Have you ever wondered what goes on behind the scenes of applications like Uber or Grab Delivery? From the moment you book a driver to the point where you rate the system, there’s a lot happening in the background. In this article, I’ll take you through an analysis of how these systems work, using the concept of Domain-Driven Design.

User Story

User Story is the transformation of a user’s narrative into requirements for easy reading and understanding. For example, “As a customer, I need … so that…”

Customer

As a customer, I need a map interface so that I can pin a pick-up point.
As a customer, I need to know delivery options so that I can pick the one that works for me.
As a customer, I need to clearly understand the price for each options so that I can know how much I need to pay.
As a customer, I need to know how to pay so that I can use my preferred payment method.
As a customer, I need to request a ride so that I can be matched with a driver.
As a customer, I need a rating system so that I can provide feedback on both the system and the driver.

Driver

As a driver, I need to be available in the system so that I can get matched with a customer.
As a driver, I need an information on the distance between myself, the customer, and the destination so that I can plan my route effectively.
As a driver, I need a way to accept customer requests so that I can respond promptly to ride requests.
As a driver, I need a payment system so that I can receive income for providing rides.
As a driver, I need a feedback system so that I can receive ratings and comments from customers.

After we’ve obtained the User Stories for both stakeholders, let’s break down the text into simple sticky notes for easy visualization.

user story

Domain Event

Domain Event is something that happens within the domain. It’s often written in past tense or something that has already occurred.

After we have obtained the User Journey in the previous section, let’s try transforming it into Domain Events to describe the events that occur.

user story mapping to domain event

Let’s go through them step by step to see which Domain Events we can derive from the User Journey

.

Starting with the customer selecting pickup and destination points (Route Selected), the system calculates the distance between the points (Trip Evaluated) and possibly calculates the price based on the type of vehicle chosen, such as Motorcycle, Car, Van, etc. (Vehicle Consumption Calculated).

.

When requesting a ride, there are events like Request, Get request, and Confirmed. Therefore, in terms of Events, we can use the term “Offer” because it’s offering the service to the driver from the customer’s end (Offer Created). The system offers the request to multiple drivers (Nearby Driver Matched/Notified), and they can accept the offer (Offer Accepted), leading to the confirmation of the trip between customer and driver (Offer Confirmed).

.

After the “Offer Confirmed” event, the system should reserve Customer Credit (Credit Reserved) to release it to the driver in the future.

.

To deliver the passenger to their destination, the system needs to find a route for the driver (Route Mapped) and conclude the journey upon reaching the destination (Trip Finished).

.

When the “Trip Finished” event occurs, the system should release the reserved credit (Credit Charged), possibly deducting service fees before transferring the payment to the driver (Fare Deducted), then transferring the money to the driver (Payment Transferred) and completing the payment (Payment Completed).

.

After the journey, the customer could rate and provide a feedback to either the system and/or the driver (Driver/Service Rated). This can be used for future development

Role

In Event Storming, a Role is the person or entity that causes a particular Event to occur.

domain event with role

Then, let’s try adding an Actor to our Domain Events so that we can determine who is responsible for causing each Event.

Bounded Context

Bounded Context is the definition of the working scope within a Domain.

Next, it’s important to divide our Bounded Contexts within our system, as illustrated in the diagram below.

domain event with bounded context

Booking Context

In this context, we focus on the booking process as the main aspect, starting from the customer selecting the destination to the driver accepting the customer’s offer.

Trip Context

In this section, I intend to include all calculations related to the journey. You’ll notice that all calculations regarding expenses for the trip or route searching are included here.

Matching Pool Context

This context is defined by the process that involves matching nearby drivers with customers who are seeking for a ride. It encapsulates 2 events, which involves a crucial algorithm that selects the best match between the available driver and potential customer and notify them accordingly.

Payment Context

This context is quite straightforward, handling everything related to finances from reserving customer funds to distributing payments to drivers. Additionally, I’ve added a note:

Purple → indicates policies, serving as trigger points for the next event based on certain conditions.

Pink → indicates External Systems. Surely, we wouldn’t want to build a payment system from scratch to avoid adding unnecessary complexity to our system. Thus, we’ll opt for an existing Payment Gateway instead.

Rating Context

Finally, we have the rating aspect. It’s quite straightforward as its main function is to provide ratings.

Domain, Subdomain, and Core domain

Core Domain is the most valuable aspect in terms of business.

Supporting Domain supports the continued operation of the core domain but is not as critical.

Generic Domain refers to standardized systems that can be widely purchased and applied to our system.

After we have divided the Bounded Contexts, we will categorize them to prioritize and choose the most suitable approach to address these issues effectively.

domain prioritization

To make it easier to understand, I’ll divide it into 3 colors:

  • Red = Core Domain
  • Yellow = Supporting Domain
  • Gray = Generic Domain

Starting with the Core Domain, I’ve designated the Trip Context and Matching Pool Context as Core Domain because what makes our product unique compared to others is the accuracy and efficiency of our customer-driver matching system, as well as the optimization of trip expenses and routes to maximize profitability. For these reasons, I consider these two aspects to be the most critical in terms of the business aspect of the system.

.

Next is the Supporting Domain. Since travel cannot occur without prior booking, the Booking Context helps strengthen our Core Domain, although it’s not as crucial as the Core Domain itself. Therefore, we may not allocate as many resources to this area initially. However, in the future, if it holds enough business value, we may promote it to Core Domain status.

.

Lastly, the Generic Domain refers to systems we can utilize that already exist. For example, there are many Payment systems available, so it might be beneficial to use one that’s already developed and prioritize aspects that provide more business value.

Note: If any readers have different ideas or perspectives, I’m open to hearing your feedback. If there are any inaccuracies or corrections needed, feel free to comment so we can discuss further.

Thank you.

--

--

Navamongkol Tongta
ABACUS digital

I'm Ter, Software Engineer(Data Analytics) at Abacus Digital, Bachelor Degree of Computer Science at Assumption University. Passionate in Software/Data Engineer