Перейти к содержанию

M3: Web API — ASP.NET Core, OData, валидация, маппинг

На M3 проект защиты получает «лицо» — Web API поверх доменной модели и БД. Стажёр знакомится с большинством технологий слоя Application из боевого DeepGeo: валидация (FluentValidation), маппинг (Mapperly), спецификации (Ardalis.Specification), OData, NSwag. Также впервые упоминается MediatR — на уровне концепции.

⚠️ Уровень детализации. Постановка задачи и целевые навыки зафиксированы. Конкретные шаги реализации (состав эндпоинтов, форма спецификаций, структура DTO) — самостоятельное решение стажёра на основе материалов. Снять пометку и уточнить детали можно после сверки с intern-development-strategy-design.md.

Срок

Месяц 4 Фазы 1 (~40–60 часов).

Цель

Построить REST/OData API над доменной моделью из M1–M2. API позволяет:

  • читать Project, Borehole, Sample, Sample_Lab, ParameterValue (с фильтрами и пагинацией через OData);
  • создавать новые записи;
  • обновлять и удалять;
  • запускать парсер из M1 по HTTP (загрузить файл → получить результат → сохранить в БД).

Целевые навыки

Группа Что осваивается
ASP.NET Core Web API Контроллеры, маршрутизация, [HttpGet]/[HttpPost], статус-коды, async/await
OData Гибкие запросы ($filter, $select, $expand, $top, $skip). Когда уместно, когда нет
FluentValidation Валидация DTO отдельным классом-валидатором (а не data-annotations)
Riok.Mapperly Маппинг домен ↔ DTO через source generator. Проекции на уровне EF Core
Ardalis.Specification Паттерн «спецификация» для переиспользуемых запросов к данным
NSwag Генерация Swagger/OpenAPI-описания API. Стажёр видел Swagger стенда — теперь строит свой
MediatR (концептуально) Что такое CQRS, зачем разделение Command/Query. Без практики — только понимание
Serilog (концептуально) Структурированное логирование. Базовая настройка

Технологии на M3

  • Microsoft.AspNetCore.OData + Microsoft.OData.Core
  • FluentValidation + FluentValidation.DependencyInjectionExtensions
  • Riok.Mapperly
  • Ardalis.Specification + Ardalis.Specification.EntityFrameworkCore
  • NSwag.AspNetCore
  • Serilog.AspNetCore

Задание

Постановка

Построить Web API над моделью из M1–M2 так, чтобы все данные стали доступны по HTTP, а парсер можно было запускать загрузкой файла через эндпоинт.

Требования к результату

Контроллеры и эндпоинты

Спроектировать REST API для основных сущностей (Borehole, Sample — обязательно; Project, Sample_Lab, ParameterValue — на усмотрение). Для каждой сущности поддержать минимум:

  • чтение списка;
  • чтение одного по идентификатору;
  • создание;
  • обновление;
  • удаление.

Как сгруппировать эндпоинты (по одному контроллеру на сущность / иерархически), какие URL использовать, что возвращать — самостоятельное решение. Руководствоваться принципами REST (в материалах ниже).

Какие HTTP-статусы возвращать в каком случае — самостоятельное решение, но должно быть согласовано: одно и то же условие (например, «не найдено») возвращает один и тот же статус во всех эндпоинтах.

Эндпоинт запуска парсера

Один из эндпоинтов принимает файл (CSV или JSON), прогоняет через парсер из M1 и сохраняет результат в БД через DbContext из M2. Возвращает итог: сколько объектов какого типа создано, какие warnings возникли.

OData

Минимум один эндпоинт (например, чтение списка Sample) должен поддерживать OData-запросы: фильтрацию ($filter), проекцию полей ($select), пагинацию ($top/$skip). Где именно подключать OData и к каким сущностям — самостоятельное решение. Подсказка для размышления: OData уместен там, где клиенту нужна гибкость запросов. Не везде его включать разумно.

DTO и валидация

Данные принимаются и возвращаются через DTO, а не через доменные классы напрямую. Маппинг домен ↔ DTO реализовать через Mapperly.

Валидация входных DTO — через FluentValidation. Минимум один валидатор с нетривиальным правилом (не просто [Required], а логика — например, «глубина отбора не может быть отрицательной» или DepthTo > DepthFrom).

Спецификация

Применить Ardalis.Specification минимум в одном месте, где это уместно. Например: «все образцы конкретной выработки с глубиной больше N» или «все ParameterValue данного Sample_Lab, отсортированные по коду параметра». Идея — encapsулировать условие выборки в переиспользуемый объект.

Swagger

API должен быть описан в Swagger UI (через NSwag или встроенный Swashbuckle — на выбор). Все эндпоинты видны, их можно дёрнуть из браузера. Описание и примеры в Swagger — большой плюс.

Логирование

Подключить Serilog для структурированного логирования. Минимум — логирование в консоль и файл. Что именно логировать (уровни, события) — самостоятельное решение.

MediatR (знакомство, без практики)

Изучить концептуально, без внедрения в код:

  • что такое CQRS и зачем разделять чтение и запись;
  • как MediatR реализует этот паттерк в .NET;
  • почему в боевом DeepGeo выбран этот подход.

Это задел на Фазу 2 — при работе с основным репозиторием MediatR встретится везде.

Тесты

Покрыть API интеграционными тестами (WebApplicationFactory или аналогичный подход). Минимум — happy path по ключевым эндпоинтам (создание + чтение).

Инженерная культура

  • DI-регистрация всех компонентов в Program.cs.
  • Строка подключения и конфигурация — в appsettings.json.
  • Коммиты осмысленные, ветки под задачи.

Контрольная точка

В конце месяца 4 — встреча с наставником:

  • продемонстрировать API в Swagger UI;
  • показать CRUD по основным сущностям;
  • показать эндпоинт запуска парсера (загрузить файл, увидеть результат);
  • показать, как работает OData на одном эндпоинте;
  • показать FluentValidation-валидатор в действии (отправить невалидный DTO);
  • объяснить, где применена спецификация и почему;
  • показать логи Serilog.

Чек-лист завершения M3

  • Контроллеры для основных сущностей реализованы
  • CRUD покрыт интеграционными тестами
  • FluentValidation-валидаторы работают (минимум один нетривиальный)
  • Mapperly-мапперы генерируются
  • Хотя бы один OData-эндпоинт работает
  • Ardalis.Specification применена хотя бы один раз
  • Swagger UI корректно описывает API
  • Serilog пишет логи (минимум в консоль и файл)
  • Эндпоинт запуска парсера по HTTP работает end-to-end
  • Понимание CQRS/MediatR на концептуальном уровне (готовность объяснить)

Материалы по темам

ASP.NET Core Web API — основы

HTTP и REST (если нужно освежить)

OData

FluentValidation

Mapperly

Ardalis.Specification

NSwag и Swagger

Serilog

MediatR (только чтение, без практики)


Прогресс

[■■■■□] M3 из 5 вех — API готов, данные доступны по HTTP.

📚 Полный список ресурсов — в разделе Ресурсы.