diff --git a/docs/howtos/solutions/caching-architecture/write-behind/index-write-behind.mdx b/docs/howtos/solutions/caching-architecture/write-behind/index-write-behind.mdx
index ce29b3ea2a..cd3fb298f0 100644
--- a/docs/howtos/solutions/caching-architecture/write-behind/index-write-behind.mdx
+++ b/docs/howtos/solutions/caching-architecture/write-behind/index-write-behind.mdx
@@ -16,6 +16,8 @@ import mongoCompassImage from './images/mongo-compass.png';
Stylish and comfortable, ...",
+ "createdOn": "2023-07-13T14:07:38.020Z",
+ "createdBy": "ADMIN",
+ "lastUpdatedOn": "2023-07-13T14:07:38.020Z",
+ "lastUpdatedBy": null,
+ "statusCode": 1
}
//...
],
@@ -160,66 +155,36 @@ In our sample application, the products service publishes an API for filtering p
}
```
-### Implementing cache-aside with Redis and MongoDB
+### Implementing cache-aside with Redis and primary database (MongoDB/ Postgressql)
-The following code shows the function used to search for products in MongoDB:
+The following code shows the function used to search for products in primary database:
```typescript title="server/src/services/products/src/service-impl.ts"
-async function getProductsByFilter(productFilter: IProductFilter) {
- const mongo = getMongodb();
- const filter: Document = {
- statusCode: {
- $eq: DB_ROW_STATUS.ACTIVE,
- },
+async function getProductsByFilter(productFilter: Product) {
+ const prisma = getPrismaClient();
+
+ const whereQuery: Prisma.ProductWhereInput = {
+ statusCode: DB_ROW_STATUS.ACTIVE,
};
if (productFilter && productFilter.productDisplayName) {
- filter['data.productDisplayName'] = {
- $regex: productFilter.productDisplayName,
- $options: 'i',
+ whereQuery.productDisplayName = {
+ contains: productFilter.productDisplayName,
+ mode: 'insensitive',
};
}
- const projection: IProduct = {
- productId: 1,
- data: {
- id: 1,
- price: 1,
- productDisplayName: 1,
- variantName: 1,
- brandName: 1,
- ageGroup: 1,
- gender: 1,
- displayCategories: 1,
- styleImages: {
- default: {
- imageURL: 1,
- },
- },
- productDescriptors: {
- description: {
- value: 1,
- },
- },
- },
- };
+ const products: Product[] = await prisma.product.findMany({
+ where: whereQuery,
+ });
- const limit = 100;
- const sort = {};
- const products = await mongo.find(
- COLLECTIONS.PRODUCTS.collectionName,
- filter,
- projection,
- limit,
- sort,
- );
return products;
}
```
-If you're familiar with MongoDB, this code should be pretty straightforward. You simply make a call to MongoDB to find products based on a filter on the product’s `displayName` property. You also define a projection object to specify which properties to get out of MongoDB. You can set up multiple columns for better fuzzy searching, but we simplified it for the purposes of this tutorial.
+You simply make a call to primary database (MongoDB/ Postgressql) to find products based on a filter on the product's `displayName` property. You can set up multiple columns for better fuzzy searching, but we simplified it for the purposes of this tutorial.
-Using MongoDB directly without Redis works for a while, but eventually it slows down. That's why you might use Redis, to speed things up. The cache-aside pattern helps you balance performance with cost.
+Using primary database directly without Redis works for a while, but eventually it slows down. That's why you might use Redis, to speed things up. The cache-aside pattern helps you balance performance with cost.
The basic decision tree for cache-aside is as follows.
@@ -228,7 +193,7 @@ When the frontend requests products:
1. Form a hash with the contents of the request (i.e., the search parameters).
1. Check Redis to see if a value exists for the hash.
1. Is there a cache hit? If data is found for the hash, it is returned; the process stops here.
-1. Is there a cache miss? When data is not found, it is read out of MongoDB and subsequently stored in Redis prior to being returned.
+1. Is there a cache miss? When data is not found, it is read out of primary database and subsequently stored in Redis prior to being returned.
Here’s the code used to implement the decision tree:
@@ -256,7 +221,7 @@ router.post(API.GET_PRODUCTS_BY_FILTER, async (req: Request, res: Response) => {
result.data = docArr;
result.isFromCache = true;
} else {
- // get data from mongodb
+ // get data from primary database
const dbData = await getProductsByFilter(body); //method shown earlier
if (body && body.productDisplayName && dbData.length) {
diff --git a/docs/howtos/solutions/microservices/common-data/microservices-arch-with-redis-old.mdx b/docs/howtos/solutions/microservices/common-data/microservices-arch-with-redis-old.mdx
new file mode 100644
index 0000000000..fe4df59d0e
--- /dev/null
+++ b/docs/howtos/solutions/microservices/common-data/microservices-arch-with-redis-old.mdx
@@ -0,0 +1,10 @@
+The e-commerce microservices application discussed in the rest of this tutorial uses the following architecture:
+
+1. `products service`: handles querying products from the database and returning them to the frontend
+1. `orders service`: handles validating and creating orders
+1. `order history service`: handles querying a customer's order history
+1. `payments service`: handles processing orders for payment
+1. `digital identity service`: handles storing digital identity and calculating identity score
+1. `api gateway`: unifies services under a single endpoint
+1. `mongodb`: serves as the primary database, storing orders, order history, products, etc.
+1. `redis`: serves as the **stream processor** and caching database
diff --git a/docs/howtos/solutions/microservices/common-data/microservices-arch-with-redis.mdx b/docs/howtos/solutions/microservices/common-data/microservices-arch-with-redis.mdx
index 7f65be673d..282a895298 100644
--- a/docs/howtos/solutions/microservices/common-data/microservices-arch-with-redis.mdx
+++ b/docs/howtos/solutions/microservices/common-data/microservices-arch-with-redis.mdx
@@ -6,5 +6,11 @@ The e-commerce microservices application discussed in the rest of this tutorial
1. `payments service`: handles processing orders for payment
1. `digital identity service`: handles storing digital identity and calculating identity score
1. `api gateway`: unifies services under a single endpoint
-1. `mongodb`: serves as the primary database, storing orders, order history, products, etc.
-1. `redis`: serves as the stream processor and caching database
+1. `mongodb/ postgresql`: serves as the primary database, storing orders, order history, products, etc.
+1. `redis`: serves as the **stream processor** and caching database
+
+:::info
+
+You don't need to use MongoDB/ Postgresql as your primary database in the demo application; you can use other [prisma supported databases](https://www.prisma.io/docs/reference/database-reference/supported-databases) as well. This is just an example.
+
+:::
diff --git a/docs/howtos/solutions/microservices/common-data/microservices-arch.mdx b/docs/howtos/solutions/microservices/common-data/microservices-arch.mdx
index caf295b901..95d2b74d4a 100644
--- a/docs/howtos/solutions/microservices/common-data/microservices-arch.mdx
+++ b/docs/howtos/solutions/microservices/common-data/microservices-arch.mdx
@@ -5,10 +5,10 @@ You eventually land on the following architecture:
1. `order history service`: handles querying a customer's order history
1. `payments service`: handles processing orders for payment
1. `api gateway`: unifies the services under a single endpoint
-1. `mongodb`: serves as the write-optimized database for storing orders, order history, products, etc.
+1. `mongodb/ postgresql`: serves as the write-optimized database for storing orders, order history, products, etc.
:::info
-You don’t need to use MongoDB as your write-optimized database; you can use other databases such as a SQL database as well. This is just an example.
+You don't need to use MongoDB/ Postgresql as your write-optimized database in the demo application; you can use other [prisma supported databases](https://www.prisma.io/docs/reference/database-reference/supported-databases) as well. This is just an example.
:::
diff --git a/docs/howtos/solutions/microservices/common-data/microservices-ecommerce-old.mdx b/docs/howtos/solutions/microservices/common-data/microservices-ecommerce-old.mdx
new file mode 100644
index 0000000000..88f06afcf3
--- /dev/null
+++ b/docs/howtos/solutions/microservices/common-data/microservices-ecommerce-old.mdx
@@ -0,0 +1,13 @@
+The e-commerce microservices application consists of a frontend, built using [Next.js](https://nextjs.org/) with [TailwindCSS](https://tailwindcss.com/). The application backend uses [Node.js](https://nodejs.org). The data is stored in
+[Redis](https://redis.com/try-free/) and MongoDB. Below you will find screenshots of the frontend of the e-commerce app:
+
+- `Dashboard`: Shows the list of products with search functionality
+
+ 
+
+- `Shopping Cart`: Add products to the cart, then check out using the "Buy Now" button
+ 
+
+- `Order history`: Once an order is placed, the `Orders` link in the top navigation bar shows the order status and history
+
+ 
diff --git a/docs/howtos/solutions/microservices/common-data/microservices-ecommerce.mdx b/docs/howtos/solutions/microservices/common-data/microservices-ecommerce.mdx
index c84fbe0162..62ef1b49cd 100644
--- a/docs/howtos/solutions/microservices/common-data/microservices-ecommerce.mdx
+++ b/docs/howtos/solutions/microservices/common-data/microservices-ecommerce.mdx
@@ -1,4 +1,5 @@
-The e-commerce microservices application consists of a frontend, built using [Next.js](https://nextjs.org/) with [TailwindCSS](https://tailwindcss.com/). The application backend uses [Node.js](https://nodejs.org). The data is stored in [MongoDB](https://www.mongodb.com/) and [Redis](https://redis.com/try-free/). Below you will find screenshots of the frontend of the e-commerce app:
+The e-commerce microservices application consists of a frontend, built using [Next.js](https://nextjs.org/) with [TailwindCSS](https://tailwindcss.com/). The application backend uses [Node.js](https://nodejs.org). The data is stored in
+[Redis](https://redis.com/try-free/) and MongoDB/ Postgressql using [Prisma](https://www.prisma.io/docs/reference/database-reference/supported-databases). Below you will find screenshots of the frontend of the e-commerce app:
- `Dashboard`: Shows the list of products with search functionality
diff --git a/docs/howtos/solutions/microservices/common-data/microservices-source-code-tip-old.mdx b/docs/howtos/solutions/microservices/common-data/microservices-source-code-tip-old.mdx
new file mode 100644
index 0000000000..1de0c9f615
--- /dev/null
+++ b/docs/howtos/solutions/microservices/common-data/microservices-source-code-tip-old.mdx
@@ -0,0 +1,7 @@
+:::tip GITHUB CODE
+
+Below is a command to the clone the source code for the application used in this tutorial
+
+git clone --branch v1.0.0 https://github.com/redis-developer/redis-microservices-ecommerce-solutions
+
+:::
diff --git a/docs/howtos/solutions/microservices/common-data/microservices-source-code-tip.mdx b/docs/howtos/solutions/microservices/common-data/microservices-source-code-tip.mdx
index 1de0c9f615..c3a5c22dc4 100644
--- a/docs/howtos/solutions/microservices/common-data/microservices-source-code-tip.mdx
+++ b/docs/howtos/solutions/microservices/common-data/microservices-source-code-tip.mdx
@@ -2,6 +2,6 @@
Below is a command to the clone the source code for the application used in this tutorial
-git clone --branch v1.0.0 https://github.com/redis-developer/redis-microservices-ecommerce-solutions
+git clone --branch v4.2.0 https://github.com/redis-developer/redis-microservices-ecommerce-solutions
:::
diff --git a/docs/howtos/solutions/microservices/cqrs/images/redis-1-order-with-products.png b/docs/howtos/solutions/microservices/cqrs/images/redis-1-order-with-products.png
new file mode 100644
index 0000000000..dea925a123
Binary files /dev/null and b/docs/howtos/solutions/microservices/cqrs/images/redis-1-order-with-products.png differ
diff --git a/docs/howtos/solutions/microservices/cqrs/index-cqrs.mdx b/docs/howtos/solutions/microservices/cqrs/index-cqrs.mdx
index 857dd9b745..36e418c537 100644
--- a/docs/howtos/solutions/microservices/cqrs/index-cqrs.mdx
+++ b/docs/howtos/solutions/microservices/cqrs/index-cqrs.mdx
@@ -14,6 +14,7 @@ import RedisEnterprise from '../common-data/redis-enterprise.mdx';
import cqrsPattern from './images/cqrs-pattern.png';
import cqrsArchitectureWithCdc from './images/cqrs-architecture-with-cdc.png';
+import imageSampleOrder from './images/redis-1-order-with-products.png';
- return orderId;
-}
-```
+:::tip
+Download [**RedisInsight**](https://redis.com/redis-enterprise/redis-insight/) to view your Redis data or to play with raw Redis commands in the workbench. Learn more by reading the [**RedisInsight tutorial**](/explore/redisinsight/)
+:::
### Order history API
@@ -220,67 +248,53 @@ The code that follows shows an example API request and response to get a custome
{
"data": [
{
- "orderId": "01GTH7JTQWP5QSEY32NNKT6B88",
- "userId": "ADMIN",
- "orderStatusCode": 1,
+ "orderId": "d4075f43-c262-4027-ad25-7b1bc8c490b6",
+ "userId": "USR_22fcf2ee-465f-4341-89c2-c9d16b1f711b",
+ "orderStatusCode": 4,
"products": [
{
- "productId": 11000,
- "qty": 10,
- "productPrice": 3995,
+ "productId": "11002",
+ "qty": 1,
+ "productPrice": 4950,
"productData": {
- "id": 11000,
- "price": 3995,
- "productDisplayName": "Puma Men Slick 3HD Yellow Black Watches",
- "variantName": "Slick 3HD Yellow",
+ "productId": "11002",
+ "price": 4950,
+ "productDisplayName": "Puma Men Race Black Watch",
+ "variantName": "Race 85",
"brandName": "Puma",
"ageGroup": "Adults-Men",
"gender": "Men",
"displayCategories": "Accessories",
- "styleImages": {
- "default": {
- "imageURL": "http://cdn_service/images/11000.jpg"
- }
- },
- "productDescriptors": {
- "description": {
- "value": "Stylish and comfortable, this motor sport inspired wrist watch from puma is designed with a plastic case and ..."
- }
- }
+ "masterCategory_typeName": "Accessories",
+ "subCategory_typeName": "Watches",
+ "styleImages_default_imageURL": "http://host.docker.internal:8080/images/11002.jpg",
+ "productDescriptors_description_value": "
This watch from puma comes in a heavy duty design. The assymentric dial and chunky..." } }, { - "productId": 11001, - "qty": 19, - "productPrice": 5450, + "productId": "11012", + "qty": 2, + "productPrice": 1195, "productData": { - "id": 11001, - "price": 5450, - "productDisplayName": "Puma Men Top Fluctuation Red Black Watches", - "variantName": "Top Fluctuation Red", - "brandName": "Puma", - "ageGroup": "Adults-Men", - "gender": "Men", - "displayCategories": "Accessories", - "styleImages": { - "default": { - "imageURL": "http://cdn_service/images/11001.jpg" - } - }, - "productDescriptors": { - "description": { - "value": "This watch from puma comes in a clean sleek design. This active watch is perfect for urban wear and ..." - } - } + "productId": "11012", + "price": 1195, + "productDisplayName": "Wrangler Women Frill Check Multi Tops", + "variantName": "FRILL CHECK", + "brandName": "Wrangler", + "ageGroup": "Adults-Women", + "gender": "Women", + "displayCategories": "Sale and Clearance,Casual Wear", + "masterCategory_typeName": "Apparel", + "subCategory_typeName": "Topwear", + "styleImages_default_imageURL": "http://host.docker.internal:8080/images/11012.jpg", + "productDescriptors_description_value": "
Composition
Navy blue, red, yellow and white checked top made of 100% cotton, with a jabot collar, buttoned ..."
}
}
],
- "createdOn": "2023-03-02T13:18:31.657Z",
- "createdBy": "ADMIN",
- "lastUpdatedOn": null,
- "lastUpdatedBy": null
+ "createdBy": "USR_22fcf2ee-465f-4341-89c2-c9d16b1f711b",
+ "lastUpdatedOn": "2023-07-13T14:11:49.997Z",
+ "lastUpdatedBy": "USR_22fcf2ee-465f-4341-89c2-c9d16b1f711b"
}
- //...
],
"error": null
}
@@ -289,43 +303,30 @@ The code that follows shows an example API request and response to get a custome
When you make a request, it goes through the API gateway to the `order history service`. Ultimately, it ends up calling a `viewOrderHistory` function, which looks as follows:
```typescript title="server/src/services/order-history/src/service-impl.ts"
-async function viewOrderHistory(userId: string) {
+const viewOrderHistory = async (userId: string) => {
const repository = OrderRepo.getRepository();
- let orders: IOrder[] = [];
-
- const result = repository
+ let orders: Partial