eintopf.info@v0.13.16/service/eventsearch/transport.go (about) 1 // Copyright (C) 2022 The Eintopf authors 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <https://www.gnu.org/licenses/>. 15 16 package eventsearch 17 18 import ( 19 "encoding/json" 20 "fmt" 21 "net/http" 22 23 "github.com/go-chi/chi/v5" 24 25 "eintopf.info/internal/xhttp" 26 ) 27 28 // Router returns an http router for the search service. 29 func Router(service Service) func(chi.Router) { 30 server := &server{service: service} 31 return func(r chi.Router) { 32 r.Options("/", xhttp.CorsHandler) 33 34 // swagger:route GET /eventsearch eventsearch eventsearch 35 // 36 // Perfomes an event search request. 37 // 38 // Responses: 39 // 200: eventsearchResult 40 // 304: 41 // 400: badRequest 42 // 500: internalError 43 // 503: serviceUnavailable 44 r.Get("/", server.search) 45 } 46 } 47 48 type server struct { 49 service Service 50 } 51 52 func (s *server) search(w http.ResponseWriter, r *http.Request) { 53 if xhttp.RequestIsNotModified(r, s.service.LastModified()) { 54 xhttp.WriteNotModified(w, s.service.LastModified()) 55 return 56 } 57 58 options, err := OptionsFromRequest(r) 59 if err != nil { 60 xhttp.WriteBadRequest(r.Context(), w, err) 61 return 62 } 63 64 result, err := s.service.Search(r.Context(), options) 65 if err != nil { 66 xhttp.WriteError(r.Context(), w, fmt.Errorf("failed to search: %s", err)) 67 return 68 } 69 data, err := json.Marshal(result) 70 if err != nil { 71 xhttp.WriteInternalError(r.Context(), w, err) 72 return 73 } 74 75 xhttp.WriteWithLastModified(w, data, s.service.LastModified()) 76 } 77 78 // OptionsFromRequest parses Options from a http.Request 79 func OptionsFromRequest(r *http.Request) (Options, error) { 80 query, err := xhttp.ReadQueryString(r, "query") 81 if err != nil { 82 return Options{}, fmt.Errorf("query: %s", err) 83 } 84 sort, err := xhttp.ReadQueryString(r, "sort") 85 if err != nil { 86 return Options{}, fmt.Errorf("sort: %s", err) 87 } 88 page, err := xhttp.ReadQueryInt(r, "page") 89 if err != nil { 90 return Options{}, fmt.Errorf("page: %s", err) 91 } 92 pageSize, err := xhttp.ReadQueryInt(r, "pageSize") 93 if err != nil { 94 return Options{}, fmt.Errorf("page: %s", err) 95 } 96 filters, err := filtersFromQuery(r.URL.Query(), "") 97 if err != nil { 98 return Options{}, err 99 } 100 aggregations, err := aggregationsFromQuery(r.URL.Query()) 101 if err != nil { 102 return Options{}, err 103 } 104 omit, err := xhttp.ReadQueryStringArray(r, "omit") 105 if err != nil { 106 return Options{}, fmt.Errorf("omit: %s", err) 107 } 108 109 return Options{ 110 Query: query, 111 Sort: sort, 112 Page: page, 113 PageSize: pageSize, 114 Filters: filters, 115 Aggregations: aggregations, 116 Omit: omit, 117 }, nil 118 }