Skip to content

Commit a4fa678

Browse files
committed
Extract to business logic layer
1 parent 6e7a8d2 commit a4fa678

File tree

15 files changed

+115
-10656
lines changed

15 files changed

+115
-10656
lines changed

.DS_Store

4 KB
Binary file not shown.

example-application/.DS_Store

0 Bytes
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
const util = require('util');
2+
const axios = require('axios');
3+
const mailer = require('../libraries/mailer');
4+
const axiosRetry = require('axios-retry');
5+
const OrderRepository = require('../data-access/order-repository');
6+
const { AppError } = require('../error-handling');
7+
const MessageQueueClient = require('../libraries/message-queue-client');
8+
9+
const axiosHTTPClient = axios.create();
10+
axiosRetry(axiosHTTPClient, { retries: 3 });
11+
12+
module.exports.addOrder = async function (newOrder) {
13+
// validation
14+
if (!newOrder.productId) {
15+
throw new AppError('invalid-order', `No product-id specified`, 400);
16+
}
17+
18+
// verify user existence by calling external Microservice
19+
const userWhoOrdered = await getUserFromUsersService(newOrder.userId);
20+
21+
if (!userWhoOrdered) {
22+
throw new AppError(
23+
'user-doesnt-exist',
24+
`The user ${newOrder.userId} doesnt exist`,
25+
404
26+
);
27+
}
28+
29+
// save to DB (Caution: simplistic code without layers and validation)
30+
const DBResponse = await new OrderRepository().addOrder(newOrder);
31+
32+
if (process.env.SEND_MAILS === 'true') {
33+
await mailer.send(
34+
'New order was placed',
35+
`user ${DBResponse.userId} ordered ${DBResponse.productId}`,
36+
'admin@app.com'
37+
);
38+
}
39+
40+
// We should notify others that a new order was added - Let's put a message in a queue
41+
await new MessageQueueClient().sendMessage('new-order', newOrder);
42+
43+
return DBResponse;
44+
};
45+
46+
async function getUserFromUsersService(userId) {
47+
try {
48+
const getUserResponse = await axiosHTTPClient.get(
49+
`http://localhost/user/${userId}`,
50+
{
51+
timeout: 2000,
52+
validateStatus: (status) => {
53+
return status < 500;
54+
},
55+
}
56+
);
57+
console.log(getUserResponse.data);
58+
return getUserResponse.data;
59+
} catch (error) {
60+
if (error?.code === 'ECONNABORTED') {
61+
throw new AppError(
62+
'user-verification-failed',
63+
`Request to user service failed so user cant be verified`,
64+
503
65+
);
66+
}
67+
68+
throw error;
69+
}
70+
}
0 Bytes
Binary file not shown.

example-application/data-access/order-repository.js

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ module.exports = class OrderRepository {
3939

4040
async getOrderById(id) {
4141
return await orderModel.findOne({ where: { id } });
42+
4243
}
4344

4445
async addOrder(orderDetails) {

example-application/entry-points/api.js

+5-59
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
11
const express = require('express');
22
const util = require('util');
33
const bodyParser = require('body-parser');
4-
const axios = require('axios');
5-
const axiosRetry = require('axios-retry');
6-
const mailer = require('../libraries/mailer');
74
const OrderRepository = require('../data-access/order-repository');
85
const errorHandler = require('../error-handling').errorHandler;
9-
const { AppError } = require('../error-handling');
10-
const MessageQueueClient = require('../libraries/message-queue-client');
6+
const orderService = require('../business-logic/order-service');
117

128
let connection;
139

14-
const client = axios.create();
15-
axiosRetry(client, { retries: 3 });
16-
1710
const initializeWebServer = (customMiddleware) => {
1811
return new Promise((resolve, reject) => {
1912
// A typical Express setup
@@ -53,51 +46,8 @@ const defineRoutes = (expressApp) => {
5346
console.log(
5447
`Order API was called to add new Order ${util.inspect(req.body)}`
5548
);
56-
57-
// validation
58-
if (!req.body.productId) {
59-
res.status(400).end();
60-
61-
return;
62-
}
63-
64-
// verify user existence by calling external Microservice
65-
try {
66-
await getUserFromUsersService(req.body.userId);
67-
} catch (error) {
68-
const { response } = error;
69-
70-
if (response && response.status === 404) {
71-
res.status(404).end();
72-
return;
73-
}
74-
75-
if (error?.code === 'ECONNABORTED') {
76-
throw new AppError(
77-
'user-doesnt-exist',
78-
`The user ${req.body.userId} doesnt exist`,
79-
503
80-
);
81-
}
82-
83-
throw error;
84-
}
85-
86-
// save to DB (Caution: simplistic code without layers and validation)
87-
const DBResponse = await new OrderRepository().addOrder(req.body);
88-
89-
if (process.env.SEND_MAILS === 'true') {
90-
await mailer.send(
91-
'New order was placed',
92-
`user ${DBResponse.userId} ordered ${DBResponse.productId}`,
93-
'admin@app.com'
94-
);
95-
}
96-
97-
// We should notify others that a new order was added - Let's put a message in a queue
98-
new MessageQueueClient().sendMessage('new-order', req.body);
99-
100-
res.json(DBResponse);
49+
const addOrderResponse = await orderService.addOrder(req.body);
50+
return res.json(addOrderResponse);
10151
} catch (error) {
10252
next(error);
10353
}
@@ -116,6 +66,8 @@ const defineRoutes = (expressApp) => {
11666
res.json(response);
11767
});
11868

69+
// delete order by id
70+
11971
router.delete('/:id', async (req, res, next) => {
12072
console.log(`Order API was called to delete order ${req.params.id}`);
12173
await new OrderRepository().deleteOrder(req.params.id);
@@ -144,12 +96,6 @@ process.on('unhandledRejection', (reason) => {
14496
errorHandler.handleError(reason);
14597
});
14698

147-
async function getUserFromUsersService(userId) {
148-
return await client.get(`http://localhost/user/${userId}`, {
149-
timeout: 2000,
150-
});
151-
}
152-
15399
module.exports = {
154100
initializeWebServer,
155101
stopWebServer,

example-application/index.js

-3
This file was deleted.

example-application/openapi.json

+4
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@
8686
"404": {
8787
"description": "User Not Found",
8888
"content": {}
89+
},
90+
"500": {
91+
"description": "Unkonwn error occured",
92+
"content": {}
8993
}
9094
}
9195
}

example-application/start.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const { initializeWebServer } = require('./entry-points/api');
2-
const {MessageQueueStarter} = require('./entry-points/message-queue-starter');
2+
const { MessageQueueStarter } = require('./entry-points/message-queue-starter');
33

44
async function start() {
55
await initializeWebServer();

example-application/test/basic-tests.test.js

+1-4
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,7 @@ describe('/api', () => {
208208

209209
test('When the user does not exist, return 404 response', async () => {
210210
//Arrange
211-
nock('http://localhost/user/').get(`/7`).reply(404, {
212-
message: 'User does not exist',
213-
code: 'nonExisting',
214-
});
211+
nock('http://localhost/user/').get(`/7`).reply(404, null);
215212
const orderToAdd = {
216213
userId: 7,
217214
productId: 2,

graphics/.DS_Store

0 Bytes
Binary file not shown.
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit 6e7a8d277f34184e7dc24aa24698769c3ccdbb82

0 commit comments

Comments
 (0)