This is a very simple food delivery distributed system. It allows to search for food and then order them with a delivery.
The entire system is made of 5 microservices (1 React, 4 Java/Spring):
- ui - React application, used by customers to place orders, manage them and track deliveries, url: http://localhost:80,
- bff - backend for frontend service, used to provide REST endpoint for ui, url: http://localhost:8081/swagger-ui.html,
- food - service that handles adding available meals to Redis, url: http://localhost:8084/swagger-ui.html,
- ordering - core service for managing orders,
- delivery - core service for managing deliveries.
Here's a short video that explains the project and how it uses Redis:
Here is the overview of a system architecture with used Redis modules:
Most of the communication is based on commands and events. E.g. in order to place an order a proper command needs to be pushed to orders
Redis Stream. It's then read and processed by the ordering
service and result in an event which also added to the central orders
stream, so other services, like delivery
can read and process further.
Also bff
is reading from the orders
stream to create its own read model (Command Query Responsibility Segregation, CQRS) of all deliveries and store it in Redis Hash. These are used to serve a current state of a delivery on a frontend.
Both ordering
and delivery
services have their own event stores in which they store relevant events, so they can event source them to make a projection of an order or a delivery.
All requests that are coming from a frontend are first queued in two Redis Task queues - ordering-inbox
and delivery-inbox
. These inboxes are used to store all incoming REST requests to bff
before converting them to relevant commands and publishing to the orders
stream.
Finally the food
service stores all available meals in the food
RedisJSON store. It also has an index created which enables a full-text search of all meals on a frontend.
There are several Redis modules that are used to store data:
orders
- Redis Stream, used to store commands and events as JSON. It stores all events that are happening across the entire system.bff
is publishing commands into it.ordering
&delivery
are publishing events. Exemplary event:
{
"header": {
"messageId":"c065e910-1806-4ab5-b1c9-8c8a105323f6",
"channel":"orders",
"type":"FoodDelivered",
"itemId":"order-2",
"createdAt":"2022-08-28T12:14:10.557171900Z"
},
"body":{
"orderId":"order-2"
}
}
ordering::[orderId]
&delivery::[orderId]
- Redis Streams, used to store only events relevant events for each service as JSON. Each order/delivery has its own stream. They hold the same events as it's in theorders
stream.
delivery-view
- Redis Hash, used to store delivery read models used for a frontend.field
in the hash stores an orderId andvalue
stores a projection of a delivery. Data is populated here by thebff
service. Exemplary delivery view:
{
"orderId":"order-2",
"customerId":"Pam Beesly",
"restaurantId":"Ristorante Da Aldo",
"deliveryManId":"nicest-guy",
"status":"FOOD_DELIVERED",
"address":"Cottage Avenue 11",
"items":[
{
"name":"Lemony Asparagus Penne",
"amount":1,
"pricePerItem":9.49
},{
"name":"Tea",
"amount":1,
"pricePerItem":1.99
}
],
"deliveryCharge":1.99,
"tip":4.59,
"total":18.06
}
__rq
- Redis task queue, two inboxes (ordering-inbox
&delivery-inbox
) used to store incoming REST request and queue their processing. Their entire lifecycle is managed by the library sonus21/rqueue. Data is here populated and consumed by thebff
service.
food:[foodId]
- RedisJSON document, stores information about meals. Data are populated by thefood
service.
food-idx
- RedisJSON index, index forfood:[foodId]
RedisJson document used to enable full-text search of meal name.
orders
-bff
,ordering
&delivery
are consumers of this stream. They're using standard Spring BootStreamListener
.ordering::[orderId]
&delivery::[orderId]
-ordering
&delivery
services are the producers and consumers for these event stores. They're using the Spring BootRedisTemplate
to achieve it.delivery-view
-bff
is adding and fetching data from this hash using the Spring BootRedisTemplate
.__rq
-bff
is queueing and consuming data from the task queue using the sonus21/rqueue library.food:[foodId]
&food-idx
-bff
is using the RedisLab'sStatefulRediSearchConnection
to full-text search available meals.
- Docker - v20.10.17 (tested on, but earlier should work too)
- Docker Compose - v2.7.0
Run all commands in a terminal:
- Start redis
docker-compose up -d redis
- Create
food-idx
docker run --rm -it --network food-delivery-redis_default redis redis-cli -h redis FT.CREATE food-idx ON JSON PREFIX 1 "food:" SCHEMA $.name AS name TEXT
- Start all services
docker-compose up -d bff ordering delivery food ui
- Run script to populate Redis with initial data
bash init-data.sh
- Stop all containers
docker-compose down --rmi local
- Clean data:
docker volume rm food-delivery-redis_redis-data
In case you've got installed Taskfile just run the command:
task init
Run a command:
task infra-clean
Here some resources to help you quickly get started using Redis Stack. If you still have questions, feel free to ask them in the Redis Discord or on Twitter.
- Sign up for a free Redis Cloud account using this link and use the Redis Stack database in the cloud.
- Based on the language/framework you want to use, you will find the following client libraries:
- Redis OM .NET (C#)
- Watch this getting started video
- Follow this getting started guide
- Redis OM Node (JS)
- Watch this getting started video
- Follow this getting started guide
- Redis OM Python
- Watch this getting started video
- Follow this getting started guide
- Redis OM Spring (Java)
- Watch this getting started video
- Follow this getting started guide
- Redis OM .NET (C#)
The above videos and guides should be enough to get you started in your desired language/framework. From there you can expand and develop your app. Use the resources below to help guide you further:
- Developer Hub - The main developer page for Redis, where you can find information on building using Redis with sample projects, guides, and tutorials.
- Redis Stack getting started page - Lists all the Redis Stack features. From there you can find relevant docs and tutorials for all the capabilities of Redis Stack.
- Redis Rediscover - Provides use-cases for Redis as well as real-world examples and educational material
- RedisInsight - Desktop GUI tool - Use this to connect to Redis to visually see the data. It also has a CLI inside it that lets you send Redis CLI commands. It also has a profiler so you can see commands that are run on your Redis instance in real-time
- Youtube Videos
- Official Redis Youtube channel
- Redis Stack videos - Help you get started modeling data, using Redis OM, and exploring Redis Stack
- Redis Stack Real-Time Stock App from Ahmad Bazzi
- Build a Fullstack Next.js app with Fireship.io
- Microservices with Redis Course by Scalable Scripts on freeCodeCamp