Меню

Обработка HTTP PUT запроса для обновления данных

01.07.2018 - Back-end, NodeJS

Handling HTTP PUT Request

Теперь посмотрим как нам обновить курс. Давайте добавим новый url handler.
Мы будем использовать метод put для обновления ресурсов. Путь будет /api/courses и тут в конце нам нужен route параметр — :id, потому что мы имеем дело с определенным курсом. Дальше пишем route handle функцию. Теперь в функции нам нужно найти курс с нужным нам id. Если курс не найден, нам нужно вернуть 404 ошибку. Иначе, нам нужно валидировать курс, проверить что он в хорошей форме. Если корявый, то нужно вернуть 400ю ошибку. Если всё хорошо, то обновить курс, и вернуть обновленный курс клиенту. Это логика, которую мы хотим имплементировать.

Часть кода мы уже реализовывали ранее, поэтому можем просто взять его оттуда.
Поиск курса, ок. Подходит. Валидация. Возможны проблемы. Проблема в том, что у нас очень простая схема валидации. Что если мы будем иметь дело со сложным объектом? Там где как минимум несколько свойств. Логика валидации будет дублироваться в нескольких route hanlerах. Пока скопируем как есть, затем вернемся и переделаем.

Теперь переходим к обновлению курса. Установим имя с тела запроса. Если есть другие параметры, можем их указать также.

Теперь нам осталось вернуть обновленный курс клиенту.

app.put('/api/courses/:id', (req, res) => {
    const course = courses.find(course => parseInt(req.params.id, 10) === course.id);
    if (!course) res.status(404).send('The course with the given ID was not found');

    const schema = {
        name: Joi.string().min(3).required()
    };
    const result = Joi.validate(req.body, schema);

    if (result.error) {
        //400 Bad Request
        res.status(400).send(result.error.details[0].message);
        return;
    }

    //Update course
    course.name = req.body.name;

    res.send(course);
});

Теперь разберемся с дублированием логики валидации. Выделим часть в отдельную функцию, которую мы сможем переиспользовать. В разных роут хэндлерах. Передадим параметр методу validate и вернут результат этого метода из функции.

И теперь воспользуемся новой функцией для валидации.

app.put('/api/courses/:id', (req, res) => {
    const course = courses.find(course => parseInt(req.params.id, 10) === course.id);
    if (!course) res.status(404).send('The course with the given ID was not found');

    const result = validateCourse(req.body);

    if (result.error) {
        //400 Bad Request
        res.status(400).send(result.error.details[0].message);
        return;
    }
    //Update course
    course.name = req.body.name;

    res.send(course);
});

function validateCourse(course) {
    const schema = {
        name: Joi.string().min(3).required()
    };
    return Joi.validate(course, schema);
}

Можем сделать код немного короче и чище, используя деструктуризацию. Как видите, мы обращаемся к result.error в двух разных местах. Выглядит, что вас интересует только свойство error. Мы можем получить к нему доступ используя деструктуризацию. Теперь воспользуемся аналогичным способом в post request route handlerе.

app.put('/api/courses/:id', (req, res) => {
    const course = courses.find(course => parseInt(req.params.id, 10) === course.id);
    if (!course) res.status(404).send('The course with the given ID was not found');

    const { error } = validateCourse(req.body);

    if (error) {
        //400 Bad Request
        res.status(400).send(error.details[0].message);
        return;
    }
    //Update course
    course.name = req.body.name;

    res.send(course);
});

function validateCourse(course) {
    const schema = {
        name: Joi.string().min(3).required()
    };
    return Joi.validate(course, schema);
}

Мы удалим схему и проверку валидации. И вставим копию кода с update.

app.post('/api/courses/', (req, res) => {

    const { error } = validateCourse(req.body);

    if (error) {
        //400 Bad Request
        res.status(400).send(error.details[0].message);
        return;
    }

    const course = {
        id: courses.length + 1,
        name: req.body.name
    };
    courses.push(course);
    console.log(courses);
    res.send(course);
});
Метки: , , , ,

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *