
Неважно, в какой сфере вы работаете: backend-разработчик, frontend, архитектор БД, системный аналитик, тестировщик или кто-то еще. А может, вы только ищете работу в IT? Или просто интересуетесь, как устроен цифровой мир. Эта статья - возможность освежить в памяти базовые концепции программирования, подготовиться к собеседованию (ведь вопрос про CRUD-операции может прозвучать не напрямую, но почти всегда скрыт в других задачах или кейсах) или просто понять, как устроены ваши любимые приложения.
Вопрос на миллион: Знаете ли вы, что общего между созданием поста в Нельзяграм, покупкой на Ozon и обновлением резюме на hh.ru?
Ответ прост: в их основе лежат четыре базовые операции, скрытые за аббревиатурой CRUD. И да, эти операции — первая ступень к пониманию того, как работают современные API.
Что такое API и при чем тут CRUD?
Прежде чем переходить к CRUD, давайте вспомним, что такое API (Application Programming Interface).
Рассмотрим на простом примере:
Представим ресторан. Вы — клиент (Frontend), видите меню (Интерфейс) и делаете заказ. Официант (API) принимает ваш заказ, относит его на кухню (Backend и База данных) и приносит вам готовое блюдо.
Таким образом, API — это мост между пользователем и системой, между интерфейсом и базой данных. Это набор правил и протоколов, который позволяет разным программам общаться друг с другом.
Когда вы публикуете пост, лайкаете комментарий или обновляете профиль — вы не думаете о том, какие запросы происходят «под капотом». А там как раз работает API, который передаёт команды серверу: «Создай запись», «Покажи мне список», «Обнови данные», «Удали неактуальное».
Любой интерактивный веб-сервис — от простого блога до сложного финтех-приложения — это механизм, который позволяет клиенту как-то взаимодействовать с данными. Это взаимодействие всегда сводится к четырём простым действиям: что-то создать, прочитать, изменить и удалить.
Именно для структурирования и стандартизации этих действий существует концепция CRUD.
Что такое CRUD?
CRUD — это акроним, который расшифровывается как:
Create (Создать)
Read (Прочитать)
Update (Обновить)
Delete (Удалить)
Именно эти операции лежат в основе всей архитектуры веб-приложений (соцсетей, интернет-магазинов, банковских приложений), API и баз данных. Прежде чем проектировать базу данных или интерфейс, разработчик продумывает — что пользователь сможет создавать, что читать, что редактировать и что удалять. Это и есть логика CRUD. Без CRUD приложение будет статичным, как старая HTML-страничка. А с ними — динамичным, удобным и масштабируемым.
Разбираем CRUD на живом примере
Чтобы не быть голословными, рассмотрим все операции на примере, знакомом каждому — публикации поста в социальной сети. А в качестве примера кода мы возьмем условный HTTP-запрос:
1. Create (Создать) — «Написать пост»
Это момент, когда вы создаете что-то новое в системе.
Что делаете вы: Вводите текст, добавляете заголовок и фото, жмете «Опубликовать».
-
Что происходит за кулисами: Ваше приложение отправляет через API запрос на сервер с командой «Создать новую запись (пост) с этими данными».

Метод POST в HTTP как раз и отвечает за создание
2. Read (Прочитать/Получить) — «Смотреть ленту или открыть пост»
Это операция получения данных без их изменения.
Что делаете вы: Листаете ленту, открываете чью-то страницу, читаете пост.
-
Что происходит за кулисами: Приложение шлет запрос: «Дай мне данные поста с таким-то ID». Сервер находит пост с id=789 (к примеру) и возвращает его вашем приложению, которое красиво его отображает.

Метод GET — для чтения
3. Update (Обновить) — «Редактировать пост»
Исправление опечатки или добавление нового фото в уже опубликованное.
Что делаете вы: Жмете «Редактировать», вносите изменения, сохраняете.
-
Что происходит за кулисами: Запрос: «Обнови запись с ID=789, заменив старые данные на эти».

Для обновления часто используются методы PUT или PATCH. При использовании PATCH мы меняем только текст и добавляем флаг "edited": true, остальные поля поста (author, imageUrl, likes, createdAt) — не трогаем.
Давайте сразу поймем отличия: "В чем разница между PUT и PATCH?". Этот вопрос вы также можете часто слышать на собеседовании.
PATCH изменяет только часть ресурса (частичное обновление). Используется, если необходимо изменить определенные поля объекта (как поле text в примере выше).
-
PUT полностью заменяет существующий ресурс новыми данными. Передаются все поля объекта, сервер возвращает обновлённую полную версию ресурса (старый объект полностью перезапишется). Поэтому очень важно при использовании PUT передать всю структуру поста, а не только изменённые поля. Если пропустить, например, likes или imageUrl, сервер может их удалить, потому что считает, что это новая версия объекта. Вот, как будет выглядеть HTTP запрос и ответ сервера при PUT ?

При использовании PUT мы передаём всю структуру поста — как будто перезаписываем весь объект заново. Если мы не включим какие-то поля (например, likes), сервер может их стереть, потому что PUT предполагает полную замену.
Также ответим на вопрос, который всегда зададут вам при упоминании PUT и PATCH. Какой из методов является идемпотентным, а какой - нет?
Идемпотентность — это свойство операции, при которой повторный запрос даёт тот же результат, что и первый.
PUT — идемпотентный. Если вы отправите один и тот же запрос PUT несколько раз — результат всегда будет одинаковым. Каждый раз сервер просто перезапишет запись одними и теми же данными.
С PATCH все немного сложнее. PATCH может быть как идемпотентным, так и неидемпотентным, — всё зависит от того, как сервер реализует обработку частичных обновлений.
Если мы каждый раз будем отправлять одинаковый запрос (к примеру мы 100 раз отправим HTTP запрос запрос на изменение полей "text" и "edited" из примера выше с одними и теми же значениями), и сервер каждый раз приводит объект в одно и то же состояние, — то это идемпотентный PATCH.
Если сервер применяет операцию на основе текущего состояния, то повторный вызов изменяет результат. Пример: когда пользователь нажимает кнопку «Лайк», браузер отправляет на сервер PATCH-запрос, который увеличивает значение счётчика лайков на 1 — и при каждом повторном запросе значение счётчика продолжает расти. В таком случае PATCH является неидемпотентен, так как не просто «устанавливается» новое значение, а меняется существующее, и поэтому результат каждый раз будет разным.
4. Delete (Удалить) — «Удалить пост»
И вот вы стоите в очереди за кофе, листаете свою страницу со старыми постами и, раскрыв очередную статью, думаете: "Как можно было написать такую ерунду?". Вы решаете удалить старый пост.
Что делаете вы: Жмете на три точки и выбираете «Удалить».
Что происходит за кулисами: Запрос: «Удали запись с ID=789 навсегда».

Заключение
CRUD - это фундамент, на котором строятся все интерактивные веб-приложения, ведь за каждым вашим кликом стоит четкая команда для базы данных.
CRUD — это основа для:
Проектирования базы данных.
Написания логики на бэкенде.
Создания интуитивно понятного интерфейса.
Именно поэтому эти операции нужно знать всем, кто хоть как-то касается данных, API или пользовательского функционала.
Комментарии (12)

Akina
28.11.2025 07:26Что происходит за кулисами: Запрос: «Обнови запись с ID=789, заменив старые данные на эти».
Вот ни разу не догма. За кулисами может быть, например, такое:
Удали старую версию записи с ID=789, и создай вместо неё новую, с ID=789 и новыми данными.
Или такое:
Создай новую запись с ID=789, новыми данными, и установи значение поля version на единицу больше максимального для уже имеющихся записей с ID=789.
И даже такое:
Установи у имеющейся записи с ID=789 значение поля actual=FALSE, и cоздай новую запись с ID=789, новыми данными и actual = TRUE.
Аналогично - для DELETE.
В общем, маппинг операции на фронте на операцию на бэке - он ни разу не 1:1 (хотя может и оказаться таковым). И маппинг операции на бэке на операцию в СУБД тоже не 1:1.
PS. Но вообще - сплошная вода, тянет разве что на введение к статье на заявленную тему...

martin_wanderer
28.11.2025 07:26Вы сейчас как будто MVCC описали. То есть в принципе огромное число сервисов с Постгресом под ними реально так и работают)

subzey
28.11.2025 07:26Просто мысли вслух по поводу круда (не статьи), если позволите.
Мы можем создать элемент, прочитать его, обновить и удалить. А как насчёт получить список элементов?
В этом месте говорят: легко! Это тоже Read, но не элемента, а коллекции.
Но по такой логике создание и удаление элемента — это просто обновление коллекции, верно. Тогда зачем в C.R.U.D нужны C и D?
Akina
28.11.2025 07:26А как насчёт получить список элементов?
Для получения списка надо прочитать каждый из элементов этого списка.
Это тоже Read, но не элемента, а коллекции.
А не надо слушать кого попало. Различайте чтение элемента и организацию цикла по чтению каждого из элементов. Цикл и его организация (включая и накопление результата) - с точки зрения процесса чтения элемента штука совершенно внешняя, чуждая, инородная, и даже как бы ненужная.
по такой логике создание и удаление элемента — это просто обновление коллекции, верно
Совершенно очевидно, что это неверно.

subzey
28.11.2025 07:26Для получения списка надо прочитать каждый из элементов этого списка.
Я имею в виду самый обычный листинг. Чтобы получить список файлов в папке, не обязательно же читать их содержимое?
Совершенно очевидно, что это неверно.
Understandable, have a nice day.

Akina
28.11.2025 07:26Я имею в виду самый обычный листинг. Чтобы получить список файлов в папке, не обязательно же читать их содержимое?
Чтобы получить список файлов в папке ака листинг вашим методом, файлам вообще не требуется существовать. Достаточно, чтобы существовали записи о файлах в файле папки. И обращаетесь вы вовсе не к файлам, а к файлу папки. Метаданные файла - не являются составной частью файла.

subzey
28.11.2025 07:26Я вас не понимаю.
Пишу: для получения списка элементов (например, имена файлов или список урлов, ничего не писал про их содержимое!), нужно прочитать объект-коллекцию (например, директорию), вы говорите, что это штука инородная и чуждая.
А потом говорите, что чтобы получить метаданные файла нужно прочитать файл директории.
Ну как так?

Akina
28.11.2025 07:26Давайте вернёмся к исходной формулировке ситуации.
Мы можем создать элемент, прочитать его, обновить и удалить. А как насчёт получить список элементов?В этом месте говорят: легко! Это тоже Read, но не элемента, а коллекции.
Что такое коллекция в данном случае? в вашем понимании.
Если ориентироваться на вашу (странную) фразу "Это тоже Read, но не элемента, а коллекции", то создаётся весьма странная ситуация - коллекция, по вашему мнению, не имеет никакого отношения к элементу, в неё входящему, и наоборот. Изменение элемента - на коллекции никак не отразится. Очевидно, что это не так, и изменяющая операция над элементом изменяет и коллекцию. И, соответственно, чтение коллекции и чтение элементов коллекции - не одно и то же.
Вам требуется получить некий список. То есть набор записей, каждая из которых содержит значение некоего (возможно, идентифицирующего, но в общем случае необязательно, и даже, возможно, неуникального или пустого) свойства одного экземпляра (элемента) этого списка. Расскажите, как вы намерены получить значение этого свойства, не обращаясь к самому элементу? Коллекция содержит ссылки на элементы в форме идентифицирующих значений атрибутов, но за любым другим атрибутом придётся лезть в соответствующий экземпляр.
Как я говорил выше, то, что вам нужно, с точки зрения экземпляра сущности Элемент Коллекции есть внешнее и в области его видимости несуществующее. А снаружи это есть метаданные коллекции экземпляров.
ncix
Справедливости ради, разницы нет никакой. Patch, put, get, post и другие - просто один из параметров запроса, сервер волен обрабатывать как ему вздумается. Поэтому правильный ответ - зависит от реализации сервера.
В том же json-rpc вообще все запросы - POST
Kelbon
вздумать он действительно может, но разница есть - она в rfc описана. И желательно понимать как это должно работать
anaxita
справедливости ради, согласно протоколу, браузер может сам повторить гет запрос, поэтому он должен быть идемпотентным.
Akina
o_O какая связь? Запрос, поступивший на сервер впервые, может обрабатываться не так, как поступивший повторно. Идемпотентность результата запроса не требует того же от процесса получения этого результата.