searcherside/handlers/api/v1/search_handler.go

70 lines
1.8 KiB
Go

package v1
import (
"encoding/json"
"log/slog"
"net/http"
"strconv"
"github.com/go-chi/chi/v5"
"code.icb4dc0.de/prskr/searcherside/core/ports"
"code.icb4dc0.de/prskr/searcherside/internal/logging"
)
type SearchHandler struct {
Curator ports.IndexCurator
}
func (h SearchHandler) PreviewSearch(writer http.ResponseWriter, request *http.Request) {
logger := logging.GetLogger(request.Context())
idxKey := ports.IndexKey{
Module: chi.URLParam(request, "module"),
Instance: chi.URLParam(request, "instance"),
}
logger.Info("Get searcher for index", slog.String("module", idxKey.Module), slog.String("instance", idxKey.Instance))
searcher, err := h.Curator.Searcher(idxKey)
if err != nil {
logger.Error("Error getting searcher", logging.Error(err))
}
result, err := searcher.Search(request.Context(), searchRequestFrom(request))
if err != nil {
logger.Error("Failed to search", logging.Error(err))
http.Error(writer, "Failed to search", http.StatusInternalServerError)
}
writer.Header().Set("Content-Type", "application/json")
encoder := json.NewEncoder(writer)
if err := encoder.Encode(result); err != nil {
logger.Error("Failed to encode search result", logging.Error(err))
http.Error(writer, "Failed to encode search result", http.StatusInternalServerError)
return
}
writer.WriteHeader(http.StatusOK)
}
func searchRequestFrom(req *http.Request) ports.IndexSearchRequest {
query := req.URL.Query()
sr := ports.IndexSearchRequest{
ExactSearch: false,
MaxHits: 25,
Query: query.Get("query"),
}
if query.Has("isExactSearch") {
if exactSearch, err := strconv.ParseBool(query.Get("isExactSearch")); err == nil {
sr.ExactSearch = exactSearch
}
}
if query.Has("maxHits") {
if maxHits, err := strconv.Atoi(query.Get("maxHits")); err == nil {
sr.MaxHits = maxHits
}
}
return sr
}