npm init -y
npm i express
package.json
{
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js"
}
}
index.js
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
|
const express = require('express');
const port = 5000;
const app = express();
let users = [
{ id: 1, name: 'nisim', age: 42 },
{ id: 2, name: 'shlomo', age: 23 },
{ id: 3, name: 'david', age: 666 },
];
app.use(express.json());
app.get('/ping', (req, res) => res.send('pong'));
app.get('/users', (req, res) => {
res.json(users);
});
app.get('/users/:id', (req, res) => {
const givenUserId = parseInt(req.params.id);
const requestedUser = users.find(u => u.id === givenUserId);
res.json(requestedUser);
});
app.post('/users', (req, res) => {
const userToAdd = req.body;
userToAdd.id = 666;
users.push(userToAdd);
res.status(201).send(`${userToAdd.name} was added`);
});
app.delete('/users/:id', (req, res) => {
const givenUserId = parseInt(req.params.id);
users = users.filter(u => u.id !== givenUserId);
res.send(`user with id ${givenUserId} was deleted`);
});
app.listen(port, () => {
console.log('listen to port', port);
});
|
Express Router#
routes/usersRouter.js
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
|
const express = require('express');
const router = express.Router();
let users = [
{ id: 1, name: 'nisim', age: 42 },
{ id: 2, name: 'shlomo', age: 23 },
{ id: 3, name: 'david', age: 666 },
];
router.get('/', (req, res) => {
res.json(users);
});
router.get('/:id', (req, res) => {
const givenUserId = parseInt(req.params.id);
const requestedUser = users.find(u => u.id === givenUserId);
res.json(requestedUser);
});
router.post('/', (req, res) => {
const userToAdd = req.body;
userToAdd.id = 666;
users.push(userToAdd);
res.status(201).send(`user ${userToAdd.name} was added`);
});
router.delete('/:id', (req, res) => {
const givenUserId = parseInt(req.params.id);
users = users.filter(u => u.id !== givenUserId);
res.send(`user with id ${givenUserId} was deleted`);
});
module.exports = router;
|
and refactor the index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
const express = require('express');
const port = 5000;
const app = express();
app.use(express.json());
app.get('/ping', (req, res) => {
res.send('pong');
});
app.use('/users', require('./routes/usersRoutes'));
app.listen(port, () => {
console.log('listen to port', port);
});
|
Manual Server Testing#
print all users
curl "localhost:5000/users"
print user by id
curl "localhost:5000/users/1"
curl "localhost:5000/users/2"
curl "localhost:5000/users/3"
insert “Avi Biter”
curl -X POST -H "Content-Type: application/json" \
-d '{"name": "avi biter", "age": 25}' \
"localhost:5000/users"
delete “Avi Biter”
curl -X DELETE "localhost:5000/users/666"
Test MongoDB#
.env
ATLAS_HOST=www.atlasmashu.com
ATLAS_USER=my-user
ATLAS_PASS=my-secret
test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
require('dotenv').config();
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
name: String,
age: Number,
});
const User = mongoose.model('user', userSchema);
main();
async function main() {
mongoose.connect(`mongodb+srv://${process.env.ATLAS_HOST}`, {
user: process.env.ATLAS_USER,
pass: process.env.ATLAS_PASS,
dbName: 'my-db-name'
});
console.log(await User.find({}));
mongoose.connection.close();
}
|
Break Script Into Files#
we will create:
db.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
require('dotenv').config();
const mongoose = require('mongoose');
function connect() {
mongoose.connect(`mongodb+srv://${process.env.ATLAS_HOST}`, {
user: process.env.ATLAS_USER,
pass: process.env.ATLAS_PASS,
dbName: 'bakery'
});
}
function disconnect() {
mongoose.connection.close();
}
module.exports = { connect, disconnect }
|
User.js
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
name: String,
age: Number,
});
module.exports = mongoose.model('user', userSchema);
test.js
1
2
3
4
5
6
7
8
9
10
|
const User = require('./models/User');
const db = require('./db');
main();
async function main() {
db.connect();
console.log(await User.find({}));
db.disconnect();
}
|
more tests:
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
|
const User = require('./models/User');
const db = require('./db');
main();
async function main() {
db.connect();
await printAllUsers();
await addAviBiter();
await addTurtles();
await deleteAllUsers();
db.disconnect();
}
async function printAllUsers() {
console.log(await User.find({}));
}
async function addAviBiter() {
const user = await User.create({ name: "avi biter", age: 18 });
console.log(user.name, 'was added');
}
async function addTurtles() {
const turtles = [
{ name: "rafael", age: 2 },
{ name: "donatelo", age: 2 },
{ name: "mikelangelo", age: 2 },
{ name: "leonardo", age: 2 },
];
await User.insertMany(turtles);
console.log('the turtles were added');
}
async function deleteAllUsers() {
await User.deleteMany({});
console.log('users collection is clean now');
}
|
Reset Script#
package.json
1
2
3
4
5
6
7
|
{
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"resetDB": "node resetDB.js"
}
}
|
resetDB.js
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
|
const db = require('./db');
const User = require('./models/User');
main();
async function main() {
db.connect();
await resetDB();
db.disconnect();
}
async function resetDB() {
await cleanDB();
await addDataSample();
}
async function addDataSample() {
const sampleOfUsers = require('./dataSample.json').users;
console.log('inserting data sample...');
await User.insertMany(sampleOfUsers);
console.log('data sample was inserted');
}
async function cleanDB() {
console.log('cleanning db...');
await User.deleteMany({});
console.log('db is clean');
}
|
dataSample.json
{
"users": [
{ "name": "nisim", "age": 42 },
{ "name": "shlomo", "age": 23 },
{ "name": "david", "age": 666 }
]
}
Refactor REST API to use mongoDB#
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
const db = require('./db');
const port = 5000;
const express = require('express');
const app = express();
db.connect();
app.use(express.json());
app.get('/ping', (req, res) => res.send('pong'));
app.use('/users', require('./routes/usersRoutes'));
app.listen(port, () => {
console.log('listen to port', port);
});
|
usersRoutes.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
const express = require('express');
const router = express.Router();
const User = require('../models/User');
router.get('/', async (req, res) => {
res.json(await User.find({}));
});
router.get('/:id', async (req, res) => {
res.json(await User.findById(req.params.id));
});
router.post('/', async (req, res) => {
const userToAdd = await User.create(req.body);
res.status(201).send(`${userToAdd.name} was added`);
});
router.delete('/:id', async (req, res) => {
const userToDelete =
await User.findByIdAndDelete(req.params.id);
res.send(`${userToDelete.name} was deleted`);
});
module.exports = router;
|
We should handle exceptions
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
|
const express = require('express');
const router = express.Router();
const User = require('../models/User');
router.get('/', async (req, res) => {
try {
res.json(await User.find({}));
}
catch (error) {
res.status(500).send('server error');
}
});
router.get('/:id', async (req, res) => {
try {
const requestedUser = await User.findById(req.params.id);
res.json(requestedUser);
}
catch (error) {
res.status(500).send('server error');
}
});
router.post('/', async (req, res) => {
try {
const userToAdd = await User.create(req.body);
res.status(201).send(`${userToAdd.name} was added`);
}
catch (error) {
res.status(500).send('server error');
}
});
router.delete('/:id', async (req, res) => {
try {
const userToDelete = await User.findByIdAndDelete(req.params.id);
res.send(`${userToDelete.name} was deleted`);
}
catch (error) {
res.status(500).send('server error');
}
});
module.exports = router;
|
Client Side#
add static routing
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
const db = require('./db');
const port = 5000;
const path = require('path');
const express = require('express');
const app = express();
db.connect();
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.json());
app.get('/ping', (req, res) => res.send('pong'));
app.use('/users', require('./routes/usersRoutes'));
app.listen(port, () => {
console.log('listen to port', port);
});
|
public/index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>my client</title>
<link rel="stylesheet" href="style.css">
<script src="script.js" defer></script>
</head>
<body>
<h1>My Awesome Client</h1>
<pre id="output-test"></pre>
</body>
</html>
|
public/script.js
1
2
3
4
5
6
7
8
9
10
11
12
13
|
const outputEl = document.querySelector('#output-test');
initPage();
async function initPage() {
const allUsers = await fetchAllUsers();
outputEl.innerText = JSON.stringify(allUsers, null, 2);
}
async function fetchAllUsers() {
const res = await fetch('/users');
return await res.json();
}
|
Table Element in Webpage#
public/index.html
1
2
3
4
5
6
|
<!-- head element stuff -->
<body>
<h1>My Awesome Client</h1>
<table id="users-table"></table>
</body>
|
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
|
const usersTable = document.querySelector('#users-table');
initPage();
async function initPage() {
const allUsers = await fetchAllUsers();
const usersInJSON = JSON.stringify(allUsers, null, 2);
outputEl.innerText = usersInJSON;
insertUsersToTable(allUsers);
}
function insertUsersToTable(users) {
const rows = users.map(u => createUserRow(u));
usersTable.append(...rows);
}
function createUserRow(user) {
const userRow = document.createElement('tr');
const cells = ['name', 'age']
.map(p => createTableCell(user[p]));
userRow.append(...cells);
return userRow;
}
function createTableCell(text) {
const cellEl = document.createElement('td');
cellEl.innerText = text;
return cellEl;
}
async function fetchAllUsers() {
const res = await fetch('/users');
return await res.json();
}
|