06 RESTful подход в MVC

Исходный файл: 06_RESTful-подход в MVC.docx
Лекция 6: RESTful-подход в MVC
Введение в RESTful-архитектуру
REST (Representational State Transfer) представляет собой стиль архитектуры, основанный на принципах, которые позволяют создавать масштабируемые, модульные и надежные веб-приложения. Основная идея REST заключается в использовании стандартных HTTP-методов для взаимодействия с ресурсами, представленными в виде уникальных URI. В контексте ASP.NET MVC Core RESTful-подход позволяет структурировать серверную логику таким образом, чтобы каждый контроллер отвечал за определенный ресурс, а действия (actions) соответствовали операциям над этим ресурсом. Это упрощает понимание API, делает его предсказуемым и удобным для интеграции с клиентскими приложениями.
Важно отметить, что REST — это не протокол, а набор ограничений и рекомендаций. Следование этим рекомендациям обеспечивает единообразие в проектировании API, что особенно критично в распределенных системах, где множество клиентов взаимодействуют с сервером. В ASP.NET MVC Core реализация RESTful-подхода тесно связана с использованием атрибутов маршрутизации, таких как [HttpGet], [HttpPost], [HttpPut] и [HttpDelete], которые явно указывают, какой метод контроллера должен обрабатывать конкретный HTTP-запрос.
Семантика HTTP-методов
HTTP-методы играют ключевую роль в RESTful-архитектуре, так как они определяют тип операции, которую клиент хочет выполнить над ресурсом. Каждый метод имеет строгую семантику, нарушение которой может привести к непредсказуемому поведению системы.
Метод GET
Метод GET предназначен для получения данных ресурса без внесения изменений в его состояние. Это безопасный (safe) и идемпотентный (idempotent) метод, что означает: многократное выполнение GET-запроса не должно влиять на состояние сервера. В ASP.NET MVC Core GET-запросы обрабатываются методами контроллера, помеченными атрибутом [HttpGet]. Например, метод GetUser(int id) может возвращать данные пользователя в формате JSON или HTML, в зависимости от контекста.
Пример использования GET-метода:
Здесь атрибут [HttpGet("users/{id}")] указывает, что метод обрабатывает запросы к URI вида /users/5. Если пользователь не найден, возвращается статус 404 Not Found, в противном случае — 200 OK с данными.
Метод POST
Метод POST используется для создания новых ресурсов. Он не является ни безопасным, ни идемпотентным, так как каждый POST-запрос может привести к созданию нового ресурса. В ASP.NET MVC Core POST-запросы обрабатываются методами с атрибутом [HttpPost]. Например, метод CreateUser(User user) принимает объект пользователя, валидирует его и сохраняет в базу данных.
Пример POST-метода:
Атрибут [FromBody] указывает, что данные пользователя должны быть десериализованы из тела запроса. В случае успеха возвращается статус 201 Created с URI нового ресурса в заголовке Location.
Метод PUT
Метод PUT применяется для полного обновления существующего ресурса. Он является идемпотентным: повторные одинаковые запросы не изменяют состояние системы. В ASP.NET MVC Core PUT-запросы обрабатываются методами с атрибутом [HttpPut]. Например, метод UpdateUser(int id, User user) обновляет данные пользователя с указанным идентификатором.
Пример PUT-метода:
Здесь NoContent() возвращает статус 204 No Content, что соответствует успешному обновлению без возврата данных.
Метод DELETE
Метод DELETE используется для удаления ресурсов. Как и PUT, он идемпотентен. В ASP.NET MVC Core DELETE-запросы обрабатываются методами с атрибутом [HttpDelete]. Например, метод DeleteUser(int id) удаляет пользователя по идентификатору.
Пример DELETE-метода:
Форматы ответов: ViewResult vs JsonResult
В ASP.NET MVC Core выбор формата ответа зависит от типа клиента и контекста использования API. Например, веб-браузеры обычно ожидают HTML, тогда как мобильные приложения или SPA (Single Page Applications) чаще работают с JSON.
ViewResult
ViewResult используется для возврата HTML-страниц, генерируемых на основе Razor-представлений. Это типичный сценарий для традиционных веб-приложений, где сервер рендерит интерфейс. Например, метод Index() может возвращать список пользователей в виде HTML-таблицы.
Пример использования ViewResult:
Здесь представление Index.cshtml получает список пользователей и генерирует HTML.
JsonResult
JsonResult возвращает данные в формате JSON, что удобно для API, ориентированных на обмен данными с клиентами, не требующими визуального представления. Например, метод GetAllUsers() может возвращать JSON-массив пользователей.
Пример JsonResult:
ASP.NET Core автоматически сериализует объект users в JSON с помощью System.Text.Json.
Content Negotiation
Content Negotiation позволяет клиенту запрашивать данные в определенном формате через заголовок Accept. Например, запрос с Accept: application/json получит JSON, а Accept: text/html — HTML. В ASP.NET Core это настраивается через форматтеры (formatters) в Startup.cs:
Теперь API может возвращать XML или JSON в зависимости от заголовка Accept.
Сериализация данных через System.Text.Json
Сериализация — процесс преобразования объектов в формат, пригодный для передачи по сети. В ASP.NET Core по умолчанию используется System.Text.Json, который отличается высокой производительностью и минимальными зависимостями.
Базовая сериализация
Для сериализации объекта в JSON используется метод JsonSerializer.Serialize(). Например:
Результат: {"Id":1,"Name":"Alice"}.
Настройка сериализации
System.Text.Json позволяет настраивать сериализацию через JsonSerializerOptions. Например, можно изменить naming policy на camelCase:
Результат:
Обработка циклических ссылок
Циклические ссылки возникают, когда объекты ссылаются друг на друга. По умолчанию System.Text.Json выбрасывает исключение в таких случаях. Чтобы игнорировать циклические ссылки, настройте ReferenceHandler:
Сериализация полей
По умолчанию сериализуются только публичные свойства. Чтобы включить поля, используйте атрибут [JsonInclude]:
Кастомизация через атрибуты
Атрибуты [JsonPropertyName] и [JsonIgnore] позволяют управлять сериализацией:
Интеграция RESTful-подхода в ASP.NET MVC Core
Маршрутизация и атрибуты
Маршрутизация в ASP.NET Core настраивается через атрибуты [Route] и [Http*]. Например, контроллер можно пометить атрибутом [Route("api/users")], а методы — [HttpGet("{id}")].
Валидация моделей
Валидация данных осуществляется через атрибуты [Required], [StringLength] и другие из пространства имен System.ComponentModel.DataAnnotations. Например:
В контроллере проверка выполняется через ModelState.IsValid.
Обработка ошибок
RESTful-API должен возвращать понятные HTTP-статусы. Например, 400 Bad Request при невалидных данных, 404 Not Found при отсутствии ресурса.
Версионирование API
Версионирование позволяет изменять API без нарушения работы старых клиентов. В ASP.NET Core это реализуется через параметры URL, заголовки или медиатипы. Например: