github.com/weaviate/weaviate@v1.24.6/modules/text2vec-contextionary/concepts/rest.go (about)

     1  //                           _       _
     2  // __      _____  __ ___   ___  __ _| |_ ___
     3  // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
     4  //  \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
     5  //   \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
     6  //
     7  //  Copyright © 2016 - 2024 Weaviate B.V. All rights reserved.
     8  //
     9  //  CONTACT: hello@weaviate.io
    10  //
    11  
    12  package concepts
    13  
    14  import (
    15  	"context"
    16  	"net/http"
    17  
    18  	"github.com/weaviate/weaviate/entities/models"
    19  )
    20  
    21  type RESTHandlers struct {
    22  	inspector Inspector
    23  }
    24  
    25  func NewRESTHandlers(inspector Inspector) *RESTHandlers {
    26  	return &RESTHandlers{
    27  		inspector: inspector,
    28  	}
    29  }
    30  
    31  func (h *RESTHandlers) Handler() http.Handler {
    32  	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    33  		switch r.Method {
    34  		case http.MethodGet:
    35  			h.get(w, r)
    36  		default:
    37  			w.WriteHeader(http.StatusMethodNotAllowed)
    38  		}
    39  	})
    40  }
    41  
    42  func (h *RESTHandlers) get(w http.ResponseWriter, r *http.Request) {
    43  	if len(r.URL.String()) == 0 || h.extractConcept(r) == "" {
    44  		w.WriteHeader(http.StatusNotFound)
    45  		return
    46  	}
    47  
    48  	h.getOne(w, r)
    49  }
    50  
    51  func (h *RESTHandlers) getOne(w http.ResponseWriter, r *http.Request) {
    52  	concept := h.extractConcept(r)
    53  
    54  	res, err := h.inspector.GetWords(r.Context(), concept)
    55  	if err != nil {
    56  		h.writeError(w, err, http.StatusBadRequest)
    57  		return
    58  	}
    59  
    60  	json, err := res.MarshalBinary()
    61  	if err != nil {
    62  		h.writeError(w, err, http.StatusInternalServerError)
    63  		return
    64  	}
    65  
    66  	w.Header().Add("content-type", "application/json")
    67  	w.WriteHeader(http.StatusOK)
    68  	w.Write(json)
    69  }
    70  
    71  func (h *RESTHandlers) writeError(w http.ResponseWriter, err error, code int) {
    72  	res := &models.ErrorResponse{Error: []*models.ErrorResponseErrorItems0{{
    73  		Message: err.Error(),
    74  	}}}
    75  
    76  	json, mErr := res.MarshalBinary()
    77  	if mErr != nil {
    78  		// fallback to text
    79  		w.Header().Add("content-type", "text/plain")
    80  		w.WriteHeader(code)
    81  		w.Write([]byte(err.Error()))
    82  	}
    83  
    84  	w.Header().Add("content-type", "application/json")
    85  	w.WriteHeader(code)
    86  	w.Write(json)
    87  }
    88  
    89  func (h *RESTHandlers) extractConcept(r *http.Request) string {
    90  	// cutoff leading slash, consider the rest the concept
    91  	return r.URL.String()[1:]
    92  }
    93  
    94  type Inspector interface {
    95  	GetWords(ctx context.Context, words string) (*models.C11yWordsResponse, error)
    96  }