HTML Diff
1 added 1 removed
Original 2026-01-01
Modified 2026-02-26
1 <p>В программировании часто используется аббревиатура<a>CRUD</a>. Она обозначает четыре базовых операции над информацией:</p>
1 <p>В программировании часто используется аббревиатура<a>CRUD</a>. Она обозначает четыре базовых операции над информацией:</p>
2 <ul><li>Создание</li>
2 <ul><li>Создание</li>
3 <li>Чтение</li>
3 <li>Чтение</li>
4 <li>Обновление</li>
4 <li>Обновление</li>
5 <li>Удаление</li>
5 <li>Удаление</li>
6 </ul><p>CRUD строят вокруг какой-то сущности. Для этого создают либо интерфейс с формами, либо HTTP API эндпоинты. В этом уроке мы научимся проводить все эти операции на примере сервиса<a>HTTP Server</a>.</p>
6 </ul><p>CRUD строят вокруг какой-то сущности. Для этого создают либо интерфейс с формами, либо HTTP API эндпоинты. В этом уроке мы научимся проводить все эти операции на примере сервиса<a>HTTP Server</a>.</p>
7 <p>Этот сервис создан специально для обучения.</p>
7 <p>Этот сервис создан специально для обучения.</p>
8 <p>Посмотрим на пример данных для сущности "задача":</p>
8 <p>Посмотрим на пример данных для сущности "задача":</p>
9 <p>Как видите, в URL постоянно повторяется 1 - это идентификатор конкретной задачи. Он будет меняться в зависимости от того, с какой задачей мы работаем прямо сейчас.</p>
9 <p>Как видите, в URL постоянно повторяется 1 - это идентификатор конкретной задачи. Он будет меняться в зависимости от того, с какой задачей мы работаем прямо сейчас.</p>
10 <p>Кстати, идентификатор необязательно должен быть числом. Здесь все зависит от того, что бэкенд считает идентификатором и как идентификаторы создаются в базе данных. Часто в качестве идентификатора используют<a>UUID</a>состоящий из цифр, букв и дефисов.</p>
10 <p>Кстати, идентификатор необязательно должен быть числом. Здесь все зависит от того, что бэкенд считает идентификатором и как идентификаторы создаются в базе данных. Часто в качестве идентификатора используют<a>UUID</a>состоящий из цифр, букв и дефисов.</p>
11 <p>Давайте вернемся к примеру выше и обратим внимание на использование методов HTTP. У методов есть определенный смысл:</p>
11 <p>Давайте вернемся к примеру выше и обратим внимание на использование методов HTTP. У методов есть определенный смысл:</p>
12 <ul><li>GET нужен для извлечения данных</li>
12 <ul><li>GET нужен для извлечения данных</li>
13 <li>POST - для создания и отправки форм</li>
13 <li>POST - для создания и отправки форм</li>
14 <li>PATCH - для обновления</li>
14 <li>PATCH - для обновления</li>
15 <li>DELETE - для удаления</li>
15 <li>DELETE - для удаления</li>
16 </ul><p>При этом URL часто остается одним и тем же.</p>
16 </ul><p>При этом URL часто остается одним и тем же.</p>
17 - <p>В API важно использовать подходящие методы. Любые HTTP-запросы обрабатываются веб-серверами и промежуточными прокси, которые могут находиться на пути к веб-серверу. И веб-сервер, и прокси знают про особенности HTTP. В зависимости от параметров запроса они могут делать разлиные оптимизации и кешировать результат.</p>
17 + <p>В API важно использовать подходящие методы. Любые HTTP-запросы обрабатываются веб-серверами и промежуточными прокси, которые могут находиться на пути к веб-серверу. И веб-сервер, и прокси знают про особенности HTTP. В зависимости от параметров запроса они могут делать различные оптимизации и кешировать результат.</p>
18 <p><strong>Кеширование</strong>- это такая техника, которая позволяет веб-серверу или прокси сохранить ответ от сервера и отдавать его при следующих запросах без обращения к самому серверу.</p>
18 <p><strong>Кеширование</strong>- это такая техника, которая позволяет веб-серверу или прокси сохранить ответ от сервера и отдавать его при следующих запросах без обращения к самому серверу.</p>
19 <p>Кеширование ускоряет доступ к ресурсам и разгружает серверы. Результат (ответ) на GET запрос можно кэшировать, для ускорения доступа, потому что GET запрос не должен менять данные. Однако другие типы запросов данные менять могут, поэтому один и тот же GET-запрос может возвращать разные ответы, если данные изменились. В этом случае будут закешированы новые данные.</p>
19 <p>Кеширование ускоряет доступ к ресурсам и разгружает серверы. Результат (ответ) на GET запрос можно кэшировать, для ускорения доступа, потому что GET запрос не должен менять данные. Однако другие типы запросов данные менять могут, поэтому один и тот же GET-запрос может возвращать разные ответы, если данные изменились. В этом случае будут закешированы новые данные.</p>
20 <p>Методы POST, PATCH и DELETE кешировать нельзя - они должны постоянно приходить на сервер, так как они вносят изменения.</p>
20 <p>Методы POST, PATCH и DELETE кешировать нельзя - они должны постоянно приходить на сервер, так как они вносят изменения.</p>
21 <h2>Добавление задачи</h2>
21 <h2>Добавление задачи</h2>
22 <p>Попробуем добавить задачу. Для этого по<a>документации HTTP Server</a>нам нужно отправить POST-запрос на эндпоинт<em><a>https://http.hexlet.app/http-api/tasks</a></em>.</p>
22 <p>Попробуем добавить задачу. Для этого по<a>документации HTTP Server</a>нам нужно отправить POST-запрос на эндпоинт<em><a>https://http.hexlet.app/http-api/tasks</a></em>.</p>
23 <p>Подключение через telnet к серверу выполняется через порт 80:</p>
23 <p>Подключение через telnet к серверу выполняется через порт 80:</p>
24 <p>Данные можно отправлять в разных форматах, HTML-формой или JSON-файлом. Чтобы использовать JSON, во время подготовки запроса нужно выполнить два шага:</p>
24 <p>Данные можно отправлять в разных форматах, HTML-формой или JSON-файлом. Чтобы использовать JSON, во время подготовки запроса нужно выполнить два шага:</p>
25 <ol><li>Указать заголовок<em>Content-Type</em>со значением<em>application/json</em></li>
25 <ol><li>Указать заголовок<em>Content-Type</em>со значением<em>application/json</em></li>
26 <li>Преобразовать данные в JSON</li>
26 <li>Преобразовать данные в JSON</li>
27 </ol><p>В итоге запрос будет выглядеть так:</p>
27 </ol><p>В итоге запрос будет выглядеть так:</p>
28 <p>Есть несколько возможных вариантов ответа от сервера:</p>
28 <p>Есть несколько возможных вариантов ответа от сервера:</p>
29 <ul><li>Код<em>201</em>- ресурс успешно создан</li>
29 <ul><li>Код<em>201</em>- ресурс успешно создан</li>
30 <li>Код<em>422</em>- ошибка валидации</li>
30 <li>Код<em>422</em>- ошибка валидации</li>
31 <li>Код<em>406</em>- некорректные данные или неверный формат</li>
31 <li>Код<em>406</em>- некорректные данные или неверный формат</li>
32 </ul><p>Подробнее можно прочитать<a>в гайде по HTTP-кодам</a>. Большая часть из них может встречаться с любым HTTP-методом.</p>
32 </ul><p>Подробнее можно прочитать<a>в гайде по HTTP-кодам</a>. Большая часть из них может встречаться с любым HTTP-методом.</p>
33 <h2>Обновление задачи</h2>
33 <h2>Обновление задачи</h2>
34 <p>Для обновления задачи мы должны отправить PATCH-запрос на эндпоинт<em><a>https://http.hexlet.app/http-api/tasks/:id</a></em>. Обновлять можно любой набор параметров, не обязательно сразу все:</p>
34 <p>Для обновления задачи мы должны отправить PATCH-запрос на эндпоинт<em><a>https://http.hexlet.app/http-api/tasks/:id</a></em>. Обновлять можно любой набор параметров, не обязательно сразу все:</p>
35 <p>Если все прошло успешно, то возможны два варианта ответа:</p>
35 <p>Если все прошло успешно, то возможны два варианта ответа:</p>
36 <ul><li>Код<em>200</em>с какими-то данными - например, JSON с обновленными данными ресурса</li>
36 <ul><li>Код<em>200</em>с какими-то данными - например, JSON с обновленными данными ресурса</li>
37 <li>Код<em>204</em>- нет тела ответа</li>
37 <li>Код<em>204</em>- нет тела ответа</li>
38 </ul><h2>Удаление задачи</h2>
38 </ul><h2>Удаление задачи</h2>
39 <p>Для удаления задачи мы должны отправить DELETE-запрос на эндпоинт<em><a>https://http.hexlet.app/http-api/tasks/:id</a></em>. Тела запроса в таком случае нет, потому что все понятно из адреса запроса:</p>
39 <p>Для удаления задачи мы должны отправить DELETE-запрос на эндпоинт<em><a>https://http.hexlet.app/http-api/tasks/:id</a></em>. Тела запроса в таком случае нет, потому что все понятно из адреса запроса:</p>
40 <p>Если все прошло успешно, то возможны два варианта ответа:</p>
40 <p>Если все прошло успешно, то возможны два варианта ответа:</p>
41 <ul><li>Код<em>200</em>и какие-то данные</li>
41 <ul><li>Код<em>200</em>и какие-то данные</li>
42 <li>Код<em>204</em>и пустое тело ответа</li>
42 <li>Код<em>204</em>и пустое тело ответа</li>
43 </ul><h2>Идемпотентность</h2>
43 </ul><h2>Идемпотентность</h2>
44 <p>Когда мы работаем с API, очень важна<strong>идемпотентность запросов</strong>. Это свойство указывает, насколько безопасно выполнять HTTP-вызов повторно. Идемпотентный запрос приводит к одному и тому же результату независимо от количества сделанных вызовов.</p>
44 <p>Когда мы работаем с API, очень важна<strong>идемпотентность запросов</strong>. Это свойство указывает, насколько безопасно выполнять HTTP-вызов повторно. Идемпотентный запрос приводит к одному и тому же результату независимо от количества сделанных вызовов.</p>
45 <p>Для примера возьмем эндпоинт<em>/tasks</em>. Он возвращает список задач и ничего не меняет на сервере. Каждый новый вызов этого эндпоинта возвращает идентичный список задач - значит, это<strong>идемпотентный запрос</strong>.</p>
45 <p>Для примера возьмем эндпоинт<em>/tasks</em>. Он возвращает список задач и ничего не меняет на сервере. Каждый новый вызов этого эндпоинта возвращает идентичный список задач - значит, это<strong>идемпотентный запрос</strong>.</p>
46 <p>Список задач может поменяться, если его меняют где-то в другом месте. Но даже это не поменяет идемпотентность GET-запроса на<em>/tasks</em>, ведь он сам ничего не меняет.</p>
46 <p>Список задач может поменяться, если его меняют где-то в другом месте. Но даже это не поменяет идемпотентность GET-запроса на<em>/tasks</em>, ведь он сам ничего не меняет.</p>
47 <p>А вот POST-запрос - точно не идемпотентный. Каждый вызов<em>/tasks</em>имеет два исхода:</p>
47 <p>А вот POST-запрос - точно не идемпотентный. Каждый вызов<em>/tasks</em>имеет два исхода:</p>
48 <ul><li>добавляет новую задачу, хотя и с теми же самыми данными</li>
48 <ul><li>добавляет новую задачу, хотя и с теми же самыми данными</li>
49 <li>возвращает ошибку, если на сервере добавлена проверка на уникальность каких-то данных</li>
49 <li>возвращает ошибку, если на сервере добавлена проверка на уникальность каких-то данных</li>
50 </ul><p>Именно поэтому при отправке форм после обновления страницы браузер всегда спрашивает, точно ли мы хотим выполнить этот запрос повторно.</p>
50 </ul><p>Именно поэтому при отправке форм после обновления страницы браузер всегда спрашивает, точно ли мы хотим выполнить этот запрос повторно.</p>
51 <p>По стандарту PATCH тоже не идемпотентный, хотя на практике чаще его делают идемпотентным. Но на это уже не могут рассчитывать браузеры или веб-серверы, потому что они не знают про специфику конкретных приложений.</p>
51 <p>По стандарту PATCH тоже не идемпотентный, хотя на практике чаще его делают идемпотентным. Но на это уже не могут рассчитывать браузеры или веб-серверы, потому что они не знают про специфику конкретных приложений.</p>
52 <p>Самое интересное - это DELETE. По стандарту он идемпотентный, то есть повторное удаление уже удаленного ресурса должно возвращать код<em>204</em>по спецификации HTTP. На практике об этом знают далеко не все программисты, поэтому обычно повторное удаление приводит к ошибке<em>404</em>.</p>
52 <p>Самое интересное - это DELETE. По стандарту он идемпотентный, то есть повторное удаление уже удаленного ресурса должно возвращать код<em>204</em>по спецификации HTTP. На практике об этом знают далеко не все программисты, поэтому обычно повторное удаление приводит к ошибке<em>404</em>.</p>
53 <p>Идемпотентность по стандарту закреплена за методами HTTP в спецификации. Но на практике все может работать иначе. Нельзя с уверенностью сказать, насколько конкретное HTTP API соответствует этим правилам. Все зависит от разработчиков, которые создавали его.</p>
53 <p>Идемпотентность по стандарту закреплена за методами HTTP в спецификации. Но на практике все может работать иначе. Нельзя с уверенностью сказать, насколько конкретное HTTP API соответствует этим правилам. Все зависит от разработчиков, которые создавали его.</p>