Files

84 lines
2.9 KiB
Go
Raw Permalink Normal View History

2026-04-13 08:14:09 +03:00
package api
import (
"fmt"
"log/slog"
"net/http"
)
// UserService — интерфейс сервиса пользователей для хендлера.
type UserService interface {
GetProfile(token string) string
}
// AuthService — интерфейс сервиса авторизации для хендлера.
type AuthService interface {
// методы, которые хендлер использует из сервиса авторизации
}
// NotificationService — интерфейс сервиса уведомлений для хендлера.
type NotificationService interface {
// методы, которые хендлер использует из сервиса уведомлений
}
// Handler — интерфейс HTTP-обработчика.
// Содержит только хендлеры и роутинг.
// Ничего не знает про http.Server, порт или lifecycle —
// это ответственность app-слоя.
// Структура неэкспортируемая — создать объект можно только через NewHandler.
type Handler interface {
Routes() http.Handler
}
// handler — обработчик HTTP-запросов.
type handler struct {
userService UserService
authService AuthService
notificationService NotificationService
}
// NewHandler создаёт обработчик HTTP-запросов.
func NewHandler(
userService UserService,
authService AuthService,
notificationService NotificationService,
) Handler {
return &handler{
userService: userService,
authService: authService,
notificationService: notificationService,
}
}
// Routes возвращает маршрутизатор со всеми зарегистрированными хендлерами.
// App-слой использует этот http.Handler при создании http.Server.
func (h *handler) Routes() http.Handler {
mux := http.NewServeMux()
mux.HandleFunc("/health", h.healthHandler)
mux.HandleFunc("/users/me", h.getUserProfile)
return mux
}
func (h *handler) healthHandler(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
if _, err := fmt.Fprintln(w, "ok"); err != nil {
slog.Error("ошибка записи ответа", "err", err)
}
}
// getUserProfile — хендлер профиля пользователя.
// Вызывает userService.GetProfile(), который внутри дёрнет authService.ValidateToken().
// Если authService == nil (как в antipattern-broken) — тут будет nil pointer dereference.
func (h *handler) getUserProfile(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("Authorization")
profile := h.userService.GetProfile(token)
w.WriteHeader(http.StatusOK)
if _, err := fmt.Fprintln(w, profile); err != nil {
slog.Error("ошибка записи ответа", "err", err)
}
}