package httpapi import ( "net/http" "git.vakhrushev.me/av/healthlog/internal/catalog" ) // catalogResponse — оболочка ответа каталога. // // Объект, а не голый массив: список метрик — не единственное, что каталогу // когда-нибудь придётся отдать, а массив верхнего уровня расширить нечем. type catalogResponse struct { Metrics []catalog.Metric `json:"metrics"` } // handleMetrics отдаёт каталог разрезов с измеренным родом агрегации. // // Список приходит из домена уже непустым срезом: nil сериализуется в `null`, и // пустая витрина отдавала бы клиенту `"metrics": null` вместо `[]`. Тест, // сравнивающий разобранные структуры, этого не увидел бы — потому приёмочная // проверка сравнивает байты ответа. Второй страховки здесь нет намеренно: // подстраховка поверх подстраховки прячет отказ первой. func (a *api) handleMetrics(w http.ResponseWriter, r *http.Request) { metrics, err := a.catalog.Metrics(r.Context()) if err != nil { // Исход операции логирует доменный слой, транспорт только переводит его // в ответ. Наружу уходит человекочитаемое сообщение, а не текст ошибки: // в нём имена колонок и форма запроса. writeError(w, http.StatusInternalServerError, "каталог не собрался") return } writeJSON(w, http.StatusOK, catalogResponse{Metrics: metrics}) }