Skip to content

Commit 82473bd

Browse files
committed
add a health endpoint
1 parent 4aa51aa commit 82473bd

File tree

5 files changed

+78
-29
lines changed

5 files changed

+78
-29
lines changed

backend/src/app.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as express from 'express';
22
import * as dotenv from 'dotenv';
33
import feedbackRoutes from './routes/feedback.routes';
4+
import healthRoutes from './routes/health.routes';
45
import * as swaggerUi from 'swagger-ui-express';
56
import * as YAML from 'yamljs';
67
import * as path from 'path';
@@ -15,10 +16,9 @@ app.use(express.json());
1516

1617
// Routes
1718
// @ts-ignore
18-
app.get('/', (req, res) => {
19-
res.redirect('/api-docs');
20-
});
19+
app.get('/', (req, res) => res.redirect('/api-docs'));
2120
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
2221
app.use('/feedbacks', feedbackRoutes);
22+
app.use('/health', healthRoutes)
2323

2424
export default app;

backend/src/controllers/feedback.controller.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,17 @@ import { Feedback } from '../models/feedback.model'
44
export const addNewFeedback = async (req, res) => {
55
try {
66
const { name, email, text } = req.body;
7+
if (!name || !email || !text) {
8+
return res.status(400).json({ message: 'Name, email, and text are required.' });
9+
}
710
const feedback = new Feedback({ name, email, text });
811
console.debug('Adding new feedback:', { name, email, text });
912
await feedback.save();
1013
res.status(201).json({ message: 'Feedback submitted successfully' });
1114
} catch (error: any) {
15+
if (error.name === 'SequelizeValidationError') {
16+
return res.status(422).json({ message: `Validation error: ${error.errors}` });
17+
}
1218
console.error('Error submitting feedback:', error);
1319
res.status(500).json({ message: `Error submitting feedback: ${error.message}` });
1420
}
@@ -33,6 +39,6 @@ export const getFeedbackById = async (req, res) => {
3339
}
3440
res.status(200).json(feedback);
3541
} catch (error) {
36-
res.status(500).json({ message: 'Error fetching feedback', error });
42+
res.status(500).json({ message: `Error fetching feedback ${error}` });
3743
}
3844
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { sequelize } from '../db';
2+
3+
// @ts-ignore
4+
export const healthCheck = async (req, res) => {
5+
try {
6+
await sequelize.query('SELECT 1');
7+
res.status(200).json({ status: 'OK', message: 'Service is healthy' });
8+
} catch (error: any) {
9+
console.error('Health check error:', error);
10+
res.status(500).json({ status: 'ERROR', message: `DB not accessible yet: ${error.message}` });
11+
}
12+
}

backend/src/docs/openapi.yaml

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,38 @@ components:
1212
schemas:
1313
Feedback:
1414
type: object
15+
description: Feedback submitted by users
1516
properties:
1617
name:
1718
type: string
19+
type:
20+
type: string
21+
example: "bug" # or "feature"
1822
email:
1923
type: string
2024
text:
2125
type: string
2226

27+
ResponseMessage:
28+
type: object
29+
description: Plain response with a message field
30+
properties:
31+
message:
32+
type: string
33+
example: "Feedback submitted successfully"
34+
35+
HealthStatus:
36+
type: object
37+
description: Health status of the service
38+
properties:
39+
status:
40+
type: string
41+
example: "OK"
42+
message:
43+
type: string
44+
example: "Service is healthy"
45+
46+
2347
paths:
2448
/feedbacks:
2549
post:
@@ -37,21 +61,26 @@ paths:
3761
content:
3862
application/json:
3963
schema:
40-
type: object
41-
properties:
42-
message:
43-
type: string
44-
example: "Feedback submitted successfully"
64+
$ref: '#/components/schemas/ResponseMessage'
4565
'400':
4666
description: Bad request
4767
content:
4868
application/json:
4969
schema:
50-
type: object
51-
properties:
52-
error:
53-
type: string
54-
example: "Invalid input data"
70+
$ref: '#/components/schemas/ResponseMessage'
71+
'422':
72+
description: Unprocessable payload or validation error
73+
content:
74+
application/json:
75+
schema:
76+
$ref: '#/components/schemas/ResponseMessage'
77+
'500':
78+
description: Internal server error
79+
content:
80+
application/json:
81+
schema:
82+
$ref: '#/components/schemas/ResponseMessage'
83+
5584
get:
5685
summary: Get all feedbacks
5786
operationId: getFeedbacks
@@ -69,11 +98,7 @@ paths:
6998
content:
7099
application/json:
71100
schema:
72-
type: object
73-
properties:
74-
error:
75-
type: string
76-
example: "Internal server error"
101+
$ref: '#/components/schemas/ResponseMessage'
77102

78103
/feedbacks/{id}:
79104
get:
@@ -97,11 +122,7 @@ paths:
97122
content:
98123
application/json:
99124
schema:
100-
type: object
101-
properties:
102-
error:
103-
type: string
104-
example: "Feedback not found"
125+
$ref: '#/components/schemas/ResponseMessage'
105126

106127

107128
/health:
@@ -114,11 +135,13 @@ paths:
114135
content:
115136
application/json:
116137
schema:
117-
type: object
118-
properties:
119-
status:
120-
type: string
121-
example: "OK"
138+
$ref: '#/components/schemas/HealthStatus'
139+
'500':
140+
description: Service is unhealthy
141+
content:
142+
application/json:
143+
schema:
144+
$ref: '#/components/schemas/HealthStatus'
122145

123146

124147

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import * as express from 'express';
2+
import { healthCheck } from '../controllers/health.controller';
3+
4+
const router = express.Router();
5+
6+
router.get('/', healthCheck);
7+
8+
export default router;

0 commit comments

Comments
 (0)