this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(api) add list endpoint handler

eagleusb 2fb65059 7ac2bc7c

+84
+84
internal/handlers/list.go
··· 1 + package handlers 2 + 3 + import ( 4 + "encoding/json" 5 + "log/slog" 6 + "net/http" 7 + "strconv" 8 + 9 + "github.com/eagleusb/proxycon/internal/types" 10 + ) 11 + 12 + // listEndpoint is the handler function for `/list` 13 + func (h *HttpServer) listEndpoint(w http.ResponseWriter, r *http.Request) { 14 + cursor := 0 15 + 16 + if c := r.URL.Query().Get("cursor"); c != "" { 17 + parsed, err := strconv.Atoi(c) 18 + if err != nil || parsed < 0 { 19 + http.Error(w, "invalid cursor", http.StatusBadRequest) 20 + return 21 + } 22 + cursor = parsed 23 + } 24 + 25 + prices := h.datasource.GetPrices() 26 + total := len(prices) 27 + 28 + if cursor >= total { 29 + w.Header().Set("Content-Type", "application/json") 30 + json.NewEncoder(w).Encode(types.ListResponse{Data: []types.Entry{}}) 31 + return 32 + } 33 + 34 + end := cursor + h.pageSize 35 + if end > total { 36 + end = total 37 + } 38 + 39 + page := prices[cursor:end] 40 + resp := buildListResponse(page) 41 + 42 + if end < total { 43 + next := end 44 + resp.NextCursor = &next 45 + } 46 + 47 + w.Header().Set("Content-Type", "application/json") 48 + if err := json.NewEncoder(w).Encode(resp); err != nil { 49 + slog.Error("encode list response", "error", err) 50 + } 51 + } 52 + 53 + // buildListResponse format the api response from a slice of bitcoin prices 54 + func buildListResponse(page []types.Price) types.ListResponse { 55 + if len(page) == 0 { 56 + return types.ListResponse{Data: []types.Entry{}} 57 + } 58 + 59 + minVal, _ := strconv.ParseInt(page[0].Price, 10, 64) 60 + maxVal := minVal 61 + 62 + entries := make([]types.Entry, len(page)) 63 + for i, p := range page { 64 + entries[i] = types.Entry{ 65 + Amount: p.Price, 66 + Timestamp: p.Timestamp, 67 + } 68 + val, _ := strconv.ParseInt(p.Price, 10, 64) 69 + if val < minVal { 70 + minVal = val 71 + } 72 + if val > maxVal { 73 + maxVal = val 74 + } 75 + } 76 + 77 + return types.ListResponse{ 78 + Start: entries[0].Timestamp, 79 + End: entries[len(entries)-1].Timestamp, 80 + Min: strconv.FormatInt(minVal, 10), 81 + Max: strconv.FormatInt(maxVal, 10), 82 + Data: entries, 83 + } 84 + }