-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.js
More file actions
131 lines (118 loc) · 3.59 KB
/
server.js
File metadata and controls
131 lines (118 loc) · 3.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
const Joi = require("joi");
const mysql = require("mysql2");
const express = require("express");
const app = express();
app.use(express.json());
// Callback function do not work now because of the connection being a promise;
const pool = mysql
.createConnection({
host: "localhost",
user: "root",
password: "michael2001",
database: "blogger",
})
.promise();
const schema = Joi.object({
title: Joi.string().required(),
content: Joi.string().required(),
category: Joi.string().required(),
tags: Joi.array(),
});
async function fetchById(id) {
let row = await pool.query(`SELECT * FROM blog WHERE id=${id}`);
if (row[0][0]) {
row = row[0][0];
row.tags = row.tags.split(",");
return row;
}
return undefined;
}
async function fetchAll(string = "%") {
let rows = await pool.query(
`SELECT * FROM blog WHERE title LIKE '%${string}%' OR content LIKE '%${string}%' OR tags LIKE '%${string}%'`,
);
if (rows[0][0]) {
rows = rows[0];
for (let row of rows) {
row.tags = row.tags.split(",");
}
return rows;
}
return undefined;
}
app.get("/blogs", async (req, res) => {
let rows;
let term = req.query.term;
if (term) rows = await fetchAll(term);
else rows = await fetchAll();
if (rows) {
res.status(200).send(rows);
} else {
res.status(204).send({ error: "No rows found" }); // You aren't able to return data with a status of 204
}
});
app.get("/blogs/:id", async (req, res) => {
const row = await fetchById(req.params.id);
if (row) {
res.status(200).send(row);
} else {
res.status(404).send({ error: "Blog not found" });
}
// console.log("Retrieved data: ", row);
});
app.post("/blogs", async (req, res) => {
const valid = schema.validate(req.body);
if (typeof valid.error != "undefined") {
// TODO: Maybe change the data schema of the error message details to match the other API calls
res.status(400).send(valid.error.details);
return;
} else {
req.body.tags = req.body.tags.join();
const result = await pool.query(`INSERT INTO blog SET ?`, req.body);
const id = result[0].insertId;
let row = await fetchById(id);
res.status(200).send(row);
}
});
app.put("/blogs/:id", async (req, res) => {
const valid = schema.validate(req.body);
if (typeof valid.error != "undefined") {
res.status(400).send(valid.error.details);
return;
} else {
req.body.tags = req.body.tags.join();
try {
await pool.query(`UPDATE blog SET ?`, req.body);
let row = await fetchById(req.params.id);
res.status(200).send(row);
} catch (e) {
res.status(404).send({ error: "Blog not found" });
}
}
});
app.delete("/blogs/:id", async (req, res) => {
let row = await fetchById(req.params.id);
if (row) {
await pool.query(`DELETE FROM blog WHERE id=${req.params.id}`);
res.status(200).send(row);
} else {
res.status(404).send({ error: "Blog not found" });
}
});
const port = 3000;
app.listen(port, () => {
console.log("Listening for calls on http://localhost:3000");
});
// NOTE:
// 200 for proper response,
// 204 for not found but proper input (nothing to return),
// 400 for improper data or client usage,
// 404 for requested data not being found due to user error (bad path)
//
// NOTE:
// Data is return as an array of objects for plurality and an object for singularity
// Incoming updates and creations should contain the title, content, category, and tag fields
//
// NOTE:
// On top of that, a 'term' query may be added to only view blogs that contain the provided keystring
// which will be compared against the blog's title, content, category, and tags.