From a9b61f84070cc7ca0d6e26f187c745619a91422a Mon Sep 17 00:00:00 2001 From: Philipp Tanlak Date: Thu, 27 Jul 2023 19:03:41 +0200 Subject: init --- api/api.go | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 api/api.go (limited to 'api/api.go') diff --git a/api/api.go b/api/api.go new file mode 100644 index 0000000..893dd00 --- /dev/null +++ b/api/api.go @@ -0,0 +1,84 @@ +package api + +import ( + "encoding/json" + "net/http" + + "github.com/alexedwards/flow" +) + +type ScrapeRequest struct { + URL string `json:"url"` + Data map[string]any `json:"data"` +} + +type ScrapeResponse struct { + URL string `json:"url"` + Data any `json:"data"` +} + +//go:generate moq -out api_service_mock_test.go . Service +type Service interface { + ScrapeURL(url string, params map[string]any) (any, error) +} + +func NewHandler(svc Service) http.Handler { + h := &Handler{ + router: flow.New(), + svc: svc, + } + h.routes() + return h +} + +type Handler struct { + router *flow.Mux + svc Service +} + +func (h *Handler) routes() { + h.router.HandleFunc("/scrape", h.handleScrape, "POST") +} + +func (h *Handler) handleScrape(w http.ResponseWriter, r *http.Request) { + var req ScrapeRequest + if err := decodeRequest(r, &req); err != nil { + respondErr(w, http.StatusBadRequest, err) + return + } + + result, err := h.svc.ScrapeURL(req.URL, req.Data) + if err != nil { + respondErr(w, http.StatusInternalServerError, err) + return + } + + respond(w, ScrapeResponse{ + URL: req.URL, + Data: result, + }) +} + +func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + h.router.ServeHTTP(w, r) +} + +func decodeRequest(r *http.Request, v any) error { + return json.NewDecoder(r.Body).Decode(v) +} + +func respond(w http.ResponseWriter, v any) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + json.NewEncoder(w).Encode(v) +} + +func respondErr(w http.ResponseWriter, statusCode int, err error) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(statusCode) + json.NewEncoder(w).Encode(struct { + Error string `json:"error"` + }{ + Error: err.Error(), + }) +} -- cgit v1.2.3