package greet import ( "context" "encoding/json" "net/http" "github.com/go-chi/chi/v5" "github.com/rs/zerolog/log" ) // GreetResponse represents a greeting response // // @Description GreetResponse represents a greeting response with a message // @Property message string "The greeting message" example("Hello John!") type GreetResponse struct { Message string `json:"message" example:"Hello John!"` } // GreetRequest represents a greeting request // // @Description GreetRequest represents a request with a name to greet // @Property name string "The name to greet" example("John") type GreetRequest struct { Name string `json:"name" example:"John"` } // ErrorResponse represents an error response // // @Description ErrorResponse represents an error response type ErrorResponse struct { Error string `json:"error" example:"invalid_request"` Message string `json:"message" example:"Invalid name parameter"` } // GreetResponseV2 represents a v2 greeting response // // @Description GreetResponseV2 represents a v2 greeting response type GreetResponseV2 struct { Message string `json:"message" example:"Hello my friend John!"` } // ValidationError represents a validation error response // // @Description ValidationError represents a validation error with details type ValidationError struct { Error string `json:"error" example:"validation_failed"` Message string `json:"message" example:"Invalid request data"` Details []ValidationDetail `json:"details,omitempty"` } // ValidationDetail represents a single validation error detail // // @Description ValidationDetail represents a single field validation error type ValidationDetail struct { Field string `json:"field" example:"name"` Error string `json:"error" example:"must be <= 100 characters"` } type Greeter interface { Greet(ctx context.Context, name string) string } type ApiV1Greet interface { RegisterRoutes(router chi.Router) } type apiV1GreetHandler struct { greeter Greeter } func NewApiV1GreetHandler(greeter Greeter) ApiV1Greet { return &apiV1GreetHandler{greeter: greeter} } func (h *apiV1GreetHandler) RegisterRoutes(router chi.Router) { log.Trace().Msg("Registering greet routes") router.Get("/", h.handleGreetQuery) router.Get("/{name}", h.handleGreetPath) log.Trace().Msg("Greet routes registered") } // handleGreetQuery godoc // // @Summary Get default greeting // @Description Returns a default greeting message // @Tags API/v1/Greeting // @Accept json // @Produce json // @Success 200 {object} GreetResponse "Successful response" // @Router /v1/greet [get] func (h *apiV1GreetHandler) handleGreetQuery(w http.ResponseWriter, r *http.Request) { name := r.URL.Query().Get("name") h.writeJSONResponse(w, h.greeter.Greet(r.Context(), name)) } // handleGreetPath godoc // // @Summary Get personalized greeting // @Description Returns a greeting with the specified name // @Tags API/v1/Greeting // @Accept json // @Produce json // @Param name path string true "Name to greet" // @Success 200 {object} GreetResponse "Successful response" // @Failure 400 {object} ErrorResponse "Invalid name parameter" // @Router /v1/greet/{name} [get] func (h *apiV1GreetHandler) handleGreetPath(w http.ResponseWriter, r *http.Request) { name := chi.URLParam(r, "name") h.writeJSONResponse(w, h.greeter.Greet(r.Context(), name)) } func (h *apiV1GreetHandler) writeJSONResponse(w http.ResponseWriter, message string) { w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]string{"message": message}) }