Memphis

How to build your own “Doordash” app

Yaniv Ben Hemo August 21, 2023 3 min read

practical, (relatively) easy-to-do tutorial for developing an event-driven, distributed food delivery app, just like “Doordash”.

Many thanks to Dhanush Kamath for the use case and supporting article.

Meet Fastmart — The fastest and most reliable food delivery app ever built.

Fastmart app logo

The stack we will use –

The stack for building Fastmart
Event-driven architecture using Message Broker
Event-driven architecture using Message Broker

High-Level Plan

    1. Sign up to Memphis Cloud here.
    2. Clone “Fastmart” GitHub repo.
    3. Review the code, the different services, and how they interact with each other
    4. Deploy “Fastmart” over Kubernetes
    5. Order food!

Let’s start!

1. Sign up to Memphis.dev Cloud

Please head to Memphis.dev Cloud Signup, and create a free acount.

Memphis.dev Cloud dashboard
Memphis.dev Dashboard

2. Clone the Fastmart repo

git clone https://github.com/yanivbh1/FastMart.git

3. Review the System Architecture, Code, and Flow

System Architecture, Code, and Flow

Follow the numbers to understand the flow.

FastMart has three main components:

order-service – Exposes REST endpoints that allow clients to fetch the food menu, place an order and track the order in real-time.

A new order will be saved in mongo with the status “Pending” and will be produced (Pushed) into the “orders” station

GET: /<orderId>
Example: curl http://order-service:3000/30POST: /<order_details>
Example: curl -X POST http://order-service:3000/api/orders -d ‘{“items”:[{“name”:”burger”,”quantity”:1}], “email”:”test@test.com”}’ -H ‘Content-Type: application/json’

Part 1 of System Architecture, Code, and Flow

The code responsible for communicating with Memphis will be found on –

./order-service/src/services/mqService.js

email-service – Responsible for notifying the client of the different stages.

email-service consumer messages from two stations: orders and notifications.

As soon as an order is inserted into the station, the email service notifies the client with an order confirmation.

At the same time listens for new notification requests of other services

Part 2 of System Architecture, Code, and Flow

resturant-service – Responsible for fulfilling an order.

  1. Consume an order
  2. Process the order
  3. Change order status at the MongoDB level to “Accepted”
  4. Using constant sleep time to mimic the preparation of the food by the restaurant
  5. Change order status at the MongoDB level to “Delivered”
  6. Sending notifications to the client

4. Deploy “Fastmart” over Kubernetes

Fastmart repo tree –

Fastmart files tree

To deploy the Fastmart namespace and different services,

please run kubectl apply -f k8s-deployment.yaml

kubectl get pods -n fastmart

Output –


NAME                                 READY   STATUS             RESTARTS   AGE
email-service-5ddb9b58d6-bq2xd       0/1     CrashLoopBackOff   3          103s
fastmart-ui-5c9bc497bd-kn4lk         1/1     Running            0          11m
orders-service-5b689b66-4h8t9        0/1     CrashLoopBackOff   7          11m
resturant-service-6d97cf6fdc-c9mvs   0/1     Completed          4          103s

Let’s understand why Fastmart services cant start

 

kubectl logs email-service-5ddb9b58d6-bq2xd -n fastmart

Output –

> email-service@1.0.0 start
> node ./index.js

17-05-2022 07:10:09 PM - info: Sleeping for 300ms before connecting to Memphis.
17-05-2022 07:10:09 PM - info: Memphis - trying to connect
17-05-2022 07:10:09 PM - info: email-service started
17-05-2022 07:10:09 PM - fatal: Memphis - User is not exist

It appears that the services try to connect to “Memphis” with the user “Fastmart” which does not exist, and we require to create it.

Once the user gets created, the pods will restart automatically and reconnect with Memphis.

5. Order food!

To expose the orders-service through localhost, run –

kubectl port-forward service/orders 9001:80 --namespace fastmart > /dev/null &

Get the menu

curl localhost:9001/api/menu

Output –

{“items”:[{“name”:”burger”,”price”:50},{“name”:”fries”,”price”:20},{“name”:”coke”,”price”:10}]}

Make an order

curl -X POST localhost:9001/api/orders -d ‘{“items”:[{“name”:”burger”,”quantity”:1}], “email”:”test@gmail.com”}’ -H ‘Content-Type: application/json’

An email should arrive shortly at the email address specified above.

Thanks!