feat: implement input validation for API v2

- Added go-playground/validator dependency

- Created pkg/validation/ package with custom validator wrapper

- Implemented request validation for v2 greet endpoint

- Added structured validation error responses

- Extended BDD tests to cover validation scenarios

- Updated AGENTS.md with v2 API documentation

- Created ADR 0011-validation-library-selection.md

- Simplified server handler creation code

- Updated CHANGELOG with implementation details
This commit is contained in:
2026-04-04 21:08:13 +02:00
parent 875eb09fb7
commit d3b6d190d1
11 changed files with 489 additions and 14 deletions

View File

@@ -10,6 +10,7 @@ import (
"DanceLessonsCoach/pkg/config"
"DanceLessonsCoach/pkg/greet"
"DanceLessonsCoach/pkg/validation"
"DanceLessonsCoach/pkg/telemetry"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
@@ -20,19 +21,29 @@ import (
)
type Server struct {
router *chi.Mux
readyCtx context.Context
withOTEL bool
config *config.Config
router *chi.Mux
readyCtx context.Context
withOTEL bool
config *config.Config
tracerProvider *sdktrace.TracerProvider
validator *validation.Validator
}
func NewServer(cfg *config.Config, readyCtx context.Context) *Server {
// Create validator instance
validator, err := validation.GetValidatorFromConfig(cfg)
if err != nil {
log.Error().Err(err).Msg("Failed to create validator, continuing without validation")
} else {
log.Trace().Msg("Validator created successfully")
}
s := &Server{
router: chi.NewRouter(),
readyCtx: readyCtx,
withOTEL: cfg.GetTelemetryEnabled(),
config: cfg,
router: chi.NewRouter(),
readyCtx: readyCtx,
withOTEL: cfg.GetTelemetryEnabled(),
config: cfg,
validator: validator,
}
s.setupRoutes()
return s
@@ -76,7 +87,7 @@ func (s *Server) registerApiV1Routes(r chi.Router) {
func (s *Server) registerApiV2Routes(r chi.Router) {
greetServiceV2 := greet.NewServiceV2()
greetHandlerV2 := greet.NewApiV2GreetHandler(greetServiceV2)
greetHandlerV2 := greet.NewApiV2GreetHandler(greetServiceV2, s.validator)
r.Route("/greet", func(r chi.Router) {
greetHandlerV2.RegisterRoutes(r)
})