Фабрика отчётов и сбор данных из разных источников

↑ 5.6 Генерация документов и отчётов · ← Предыдущая · → Следующая

Желательно~3 мин чтенияУровень: middle

Зачем это на собесе

Архитектурный вопрос: как спроектировать сервис отчётов, собирающий данные из нескольких систем.

Объяснение

Фабрика отчётов — компонент, который по типу отчёта выбирает провайдеры данных и рендерер, а затем формирует документ.

flowchart LR
  R[Запрос отчёта] --> F[ReportFactory]
  F --> P1[Провайдер: PostgreSQL]
  F --> P2[Провайдер: ClickHouse]
  F --> P3[Провайдер: внешний API]
  P1 & P2 & P3 --> M[Модель отчёта]
  M --> RN[Рендерер PDF/Excel/HTML]
  RN --> S[(MinIO)]
  S --> L[Ссылка клиенту]

Разделение ответственности:

ЧастьЗадача
Определение отчётапараметры, права доступа, формат
Провайдеры данныхполучение данных из источников (параллельно, с таймаутами)
Агрегаторобъединение и расчёт итогов
Рендерервывод в формат; один набор данных → PDF/XLSX/CSV
Оркестрацияасинхронная задача, статус, повторы, отмена
public interface IReportDefinition { string Type { get; } Task<ReportModel> BuildAsync(ReportRequest r, CancellationToken ct); }
public interface IReportRenderer { string Format { get; } Task RenderAsync(ReportModel m, Stream output, CancellationToken ct); }
 
public class ReportService(IEnumerable<IReportDefinition> defs, IEnumerable<IReportRenderer> renderers)
{
    public async Task RunAsync(ReportRequest r, Stream output, CancellationToken ct)
    {
        var model = await defs.Single(d => d.Type == r.Type).BuildAsync(r, ct);
        await renderers.Single(x => x.Format == r.Format).RenderAsync(model, output, ct);
    }
}

Долгие отчёты: POST /reports → 202 Accepted + Location: /reports/{id}; клиент опрашивает статус или получает уведомление (SignalR/вебхук).

Нюансы и подводные камни

  • Отчёты на боевой БД нагружают её: читайте с реплики или из аналитического хранилища (ClickHouse).
  • Согласованность данных из разных источников: фиксируйте момент среза.
  • Права: пользователь видит только свои данные (фильтры на уровне провайдера).
  • Ограничения: лимит на объём и время; отмена по токену.
  • Кэшируйте готовые отчёты по параметрам.

Практика

  1. Реализуйте фабрику с двумя определениями и тремя рендерерами.
  2. Сделайте асинхронный API отчёта со статусом и ссылкой на файл.
  3. Ограничьте параллелизм сборки отчётов и добавьте отмену.

Вопросы с ответами

Связанные темы