Node.js

 "name": "express-parser", 
 "version": "0.0.0", 
 "private": true, 
 "scripts": { 
 "start": "node ./bin/www", 
 "dev": "nodemon ./bin/www" 
 }, 
 "dependencies": 
 "cookie-parser": "~1.4.4", 
 "debug": "~2.6.9", 
 "express": "~4.16.1", 
 "http-errors": "~1.6.3", 
 "morgan": "~1.9.1", 
 "twig": "~0.10.3", 
 "nodemon": "^2.0.22", 
 "dotenv": "^16.0.3", 
 "mongodb": "^5.2.0"
 }
 }

Express и Mongoose

const mongoose = require("mongoose");
const express = require("express");
const Schema = mongoose.Schema;
const app = express();
const jsonParser = express.json();
  
const userScheme = new Schema({name: String, age: Number}, {versionKey: false});
const User = mongoose.model("User", userScheme);
  
app.use(express.static(__dirname + "/public"));
 
async function main() {
 
    try{
        await mongoose.connect("mongodb://127.0.0.1:27017/usersdb");
        app.listen(3000);
        console.log("Сервер ожидает подключения...");
    }
    catch(err) {
        return console.log(err);
    }
}
 
app.get("/api/users", async (req, res)=>{
    // получаем всех пользователей
    const users = await User.find({});
    res.send(users);
});
  
app.get("/api/users/:id", async(req, res)=>{
          
    const id = req.params.id;
    // получаем одного пользователя по id
    const user = await User.findById(id);
    if(user) res.send(user);
    else res.sendStatus(404);
});
     
app.post("/api/users", jsonParser, async (req, res) =>{
         
    if(!req.body) return res.sendStatus(400);
         
    const userName = req.body.name;
    const userAge = req.body.age;
    const user = new User({name: userName, age: userAge});
    // сохраняем в бд
    await user.save();
    res.send(user);
});
      
app.delete("/api/users/:id", async(req, res)=>{
          
    const id = req.params.id;
    // удаляем по id 
    const user = await User.findByIdAndDelete(id);
    if(user) res.send(user);
    else res.sendStatus(404);
});
     
app.put("/api/users", jsonParser, async (req, res)=>{
          
    if(!req.body) return res.sendStatus(400);
    const id = req.body.id;
    const userName = req.body.name;
    const userAge = req.body.age;
    const newUser = {age: userAge, name: userName};
     // обновляем данные пользователя по id
    const user = await User.findOneAndUpdate({_id: id}, newUser, {new: true}); 
    if(user) res.send(user);
    else res.sendStatus(404);
});
 
main();
// прослушиваем прерывание работы программы (ctrl-c)
process.on("SIGINT", async() => {
      
    await mongoose.disconnect();
    console.log("Приложение завершило работу");
    process.exit();
});

Валидация

Mongoose имеет ряд встроенных правил валидации, которые мы можем указать в схеме:

required: требует обязательного наличия значения для свойства

min и max: задают минимальное и максимальное значения для числовых данных

minlength и maxlength: задают минимальную и максимальную длину для строк

enum: строка должна представлять одно из значений в указанном массиве строк

match: строка должна соответствовать регулярному выражению
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
   
// установка схемы
const userScheme = new Schema({
    name: {
        type: String,
        required: true,
        minlength:3,
        maxlength:20
    },
    age: {
        type: Number,
        default: 22,
        required: true,
        min: 1,
        max:100
    }
});
const User = mongoose.model("User", userScheme);
const user = new User({name: "Li"});
 
async function main() {
 
    await mongoose.connect("mongodb://127.0.0.1:27017/usersdb");
    await user.save();
    console.log("Сохранен объект", user);
}
main().catch(console.log).finally(async()=>await mongoose.disconnect());

Index.html


<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Список пользователей</title>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
    <h2>Список пользователей</h2>
    <form name="userForm">
        <input type="hidden" name="id" value="0" />
        <div class="form-group">
            <label for="name">Имя:</label>
            <input class="form-control" name="name" />
        </div>
        <div class="form-group">
            <label for="age">Возраст:</label>
            <input class="form-control" name="age" />
        </div>
        <div class="panel-body">
            <button type="submit" class="btn btn-sm btn-primary">Сохранить</button>
            <a id="reset" class="btn btn-sm btn-primary">Сбросить</a>
        </div>
    </form>
    <table class="table table-condensed table-striped table-bordered">
        <thead><tr><th>Id</th><th>Имя</th><th>возраст</th><th></th></tr></thead>
        <tbody>
        </tbody>
    </table>
    
    <script>
    // Получение всех пользователей
        async function getUsers() {
            // отправляет запрос и получаем ответ
            const response = await fetch("/api/users", {
                method: "GET",
                headers: { "Accept": "application/json" }
            });
            // если запрос прошел нормально
            if (response.ok === true) {
                // получаем данные
                const users = await response.json();
                let rows = document.querySelector("tbody"); 
                users.forEach(user => {
                    // добавляем полученные элементы в таблицу
                    rows.append(row(user));
                });
            }
        }
        // Получение одного пользователя
        async function getUser(id) {
            const response = await fetch("/api/users/" + id, {
                method: "GET",
                headers: { "Accept": "application/json" }
            });
            if (response.ok === true) {
                const user = await response.json();
                const form = document.forms["userForm"];
                form.elements["id"].value = user._id;
                form.elements["name"].value = user.name;
                form.elements["age"].value = user.age;
            }
        }
        // Добавление пользователя
        async function createUser(userName, userAge) {
   
            const response = await fetch("api/users", {
                method: "POST",
                headers: { "Accept": "application/json", "Content-Type": "application/json" },
                body: JSON.stringify({
                    name: userName,
                    age: parseInt(userAge, 10)
                })
            });
            if (response.ok === true) {
                const user = await response.json();
                reset();
                document.querySelector("tbody").append(row(user));
            }
        }
        // Изменение пользователя
        async function editUser(userId, userName, userAge) {
            const response = await fetch("api/users", {
                method: "PUT",
                headers: { "Accept": "application/json", "Content-Type": "application/json" },
                body: JSON.stringify({
                    id: userId,
                    name: userName,
                    age: parseInt(userAge, 10)
                })
            });
            if (response.ok === true) {
                const user = await response.json();
                reset();
                document.querySelector(`tr[data-rowid='${user._id}']`).replaceWith(row(user));
            }
        }
        // Удаление пользователя
        async function deleteUser(id) {
            const response = await fetch("/api/users/" + id, {
                method: "DELETE",
                headers: { "Accept": "application/json" }
            });
            if (response.ok === true) {
                const user = await response.json();
                document.querySelector(`tr[data-rowid='${user._id}']`).remove();
            }
        }
   
        // сброс формы
        function reset() {
            const form = document.forms["userForm"];
            form.reset();
            form.elements["id"].value = 0;
        }
        // создание строки для таблицы
        function row(user) {
   
            const tr = document.createElement("tr");
            tr.setAttribute("data-rowid", user._id);
   
            const idTd = document.createElement("td");
            idTd.append(user._id);
            tr.append(idTd);
   
            const nameTd = document.createElement("td");
            nameTd.append(user.name);
            tr.append(nameTd);
   
            const ageTd = document.createElement("td");
            ageTd.append(user.age);
            tr.append(ageTd);
               
            const linksTd = document.createElement("td");
   
            const editLink = document.createElement("a");
            editLink.setAttribute("data-id", user._id);
            editLink.setAttribute("style", "cursor:pointer;padding:15px;");
            editLink.append("Изменить");
            editLink.addEventListener("click", e => {
   
                e.preventDefault();
                getUser(user._id);
            });
            linksTd.append(editLink);
   
            const removeLink = document.createElement("a");
            removeLink.setAttribute("data-id", user._id);
            removeLink.setAttribute("style", "cursor:pointer;padding:15px;");
            removeLink.append("Удалить");
            removeLink.addEventListener("click", e => {
   
                e.preventDefault();
                deleteUser(user._id);
            });
   
            linksTd.append(removeLink);
            tr.appendChild(linksTd);
   
            return tr;
        }
        // сброс значений формы
        document.getElementById("reset").addEventListener("click", e => {
   
            e.preventDefault();
            reset();
        })
   
        // отправка формы
        document.forms["userForm"].addEventListener("submit", e => {
            e.preventDefault();
            const form = document.forms["userForm"];
            const id = form.elements["id"].value;
            const name = form.elements["name"].value;
            const age = form.elements["age"].value;
            if (id == 0)
                createUser(name, age);
            else
                editUser(id, name, age);
        });
   
        // загрузка пользователей
        getUsers();
    </script>
</body>
</html>

Признаки "плохого кода"

Кратко рассмотрим 12 признаков, когда код можно улучшить: 1. Duplicated Code  — иногда повторяющийся код не всегда несет в себе пользу. Выде...