Files
Messenger/server/internal/api/api.go
T

80 lines
2.3 KiB
Go
Raw Normal View History

package api
import (
"log/slog"
"net/http"
"strings"
"messenger/internal/auth"
"messenger/internal/platform/config"
"messenger/internal/realtime"
"messenger/internal/store"
)
type apiHandler struct {
store *store.Store
tokens *auth.TokenManager
hub *realtime.Hub
log *slog.Logger
secure bool
}
// NewHandler builds the /api/v1 route tree with all middleware applied.
// static, when non-nil, serves the built frontend for non-API paths.
func NewHandler(st *store.Store, tm *auth.TokenManager, hub *realtime.Hub, log *slog.Logger, cfg *config.Config, static http.Handler) http.Handler {
h := &apiHandler{
store: st,
tokens: tm,
hub: hub,
log: log,
secure: cfg.Environment == "production",
}
mux := http.NewServeMux()
authHandler := requireAuth(tm, http.HandlerFunc(h.websocket))
mux.HandleFunc("GET /api/v1/ping", func(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusOK, map[string]string{"message": "pong"})
})
mux.HandleFunc("POST /api/v1/auth/register", h.register)
mux.HandleFunc("POST /api/v1/auth/login", h.login)
mux.HandleFunc("POST /api/v1/auth/refresh", h.refresh)
mux.HandleFunc("POST /api/v1/auth/logout", h.logout)
mux.Handle("GET /api/v1/users/me", requireAuth(tm, h.me))
mux.Handle("GET /api/v1/users", requireAuth(tm, h.searchUsers))
mux.Handle("GET /api/v1/contacts", requireAuth(tm, h.listContacts))
mux.Handle("POST /api/v1/contacts", requireAuth(tm, h.addContact))
mux.Handle("DELETE /api/v1/contacts/{user_id}", requireAuth(tm, h.removeContact))
mux.Handle("GET /api/v1/conversations", requireAuth(tm, h.listConversations))
mux.Handle("POST /api/v1/conversations", requireAuth(tm, h.createDM))
mux.Handle("GET /api/v1/conversations/{id}/messages", requireAuth(tm, h.listMessages))
mux.Handle("POST /api/v1/conversations/{id}/messages", requireAuth(tm, h.sendMessage))
mux.Handle("GET /ws", authHandler)
if static != nil {
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if strings.HasPrefix(r.URL.Path, "/api/") {
writeError(w, http.StatusNotFound, "not found")
return
}
static.ServeHTTP(w, r)
})
}
return mux
}
func (h *apiHandler) websocket(w http.ResponseWriter, r *http.Request) {
userID, ok := userIDFrom(r.Context())
if !ok {
writeError(w, http.StatusUnauthorized, "unauthenticated")
return
}
h.hub.HandleWS(w, r, userID)
}