From 76b8698b29d6fc45aa53ba2c9292bfadca39f7a5 Mon Sep 17 00:00:00 2001 From: Ian Bentley Date: Fri, 23 Feb 2024 11:30:20 -0500 Subject: [PATCH 1/2] add endpoint to support non numeric cursor. --- cmd/server/main.go | 1 + internal/pagination/service.go | 57 ++++++++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/cmd/server/main.go b/cmd/server/main.go index 102ac7d..3110260 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -35,6 +35,7 @@ func main() { r.HandleFunc("/pagination/limitoffset/offset", pagination.HandleLimitOffsetOffset).Methods(http.MethodGet, http.MethodPut) r.HandleFunc("/pagination/cursor", pagination.HandleCursor).Methods(http.MethodGet, http.MethodPut) r.HandleFunc("/pagination/url", pagination.HandleURL).Methods(http.MethodGet) + r.HandleFunc("/pagination/cursor_non_numeric", pagination.HandleNonNumericCursor).Methods(http.MethodGet) r.HandleFunc("/retries", retries.HandleRetries).Methods(http.MethodGet, http.MethodPost) r.HandleFunc("/retries/after", retries.HandleRetries).Methods(http.MethodGet) r.HandleFunc("/errors/{status_code}", errors.HandleErrors).Methods(http.MethodGet) diff --git a/internal/pagination/service.go b/internal/pagination/service.go index d30d8e5..207aecc 100644 --- a/internal/pagination/service.go +++ b/internal/pagination/service.go @@ -18,10 +18,27 @@ type CursorRequest struct { Cursor int `json:"cursor"` } +type NonNumericCursorRequest struct { + Cursor string `json:"cursor"` +} + type PaginationResponse struct { +<<<<<<< HEAD NumPages int `json:"numPages"` ResultArray []int `json:"resultArray"` Next *string `json:"next,omitempty"` +======= + NumPages int `json:"numPages"` + ResultArray []interface{} `json:"resultArray"` +} + +// Insecure reversable hashing for string cursors +func hash(s string) (int, error) { + return strconv.Atoi(s) +} +func unhash(h int) string { + return strconv.Itoa(h) +>>>>>>> cf9ad59 (add endpoint to support non numeric cursor.) } const total = 20 @@ -45,7 +62,7 @@ func HandleLimitOffsetPage(w http.ResponseWriter, r *http.Request) { res := PaginationResponse{ NumPages: int(math.Ceil(float64(total) / float64(limit))), - ResultArray: make([]int, 0), + ResultArray: make([]interface{}, 0), } for i := start; i < total && len(res.ResultArray) < limit; i++ { @@ -77,7 +94,7 @@ func HandleLimitOffsetOffset(w http.ResponseWriter, r *http.Request) { res := PaginationResponse{ NumPages: int(math.Ceil(float64(total) / float64(limit))), - ResultArray: make([]int, 0), + ResultArray: make([]interface{}, 0), } for i := offset; i < total && len(res.ResultArray) < limit; i++ { @@ -104,7 +121,7 @@ func HandleCursor(w http.ResponseWriter, r *http.Request) { res := PaginationResponse{ NumPages: 0, - ResultArray: make([]int, 0), + ResultArray: make([]interface{}, 0), } for i := cursor + 1; i < total && len(res.ResultArray) < 15; i++ { @@ -160,6 +177,32 @@ func HandleURL(w http.ResponseWriter, r *http.Request) { } } +func HandleNonNumericCursor(w http.ResponseWriter, r *http.Request) { + queryCursor := r.FormValue("cursor") + var pagination NonNumericCursorRequest + hasBody := true + if err := json.NewDecoder(r.Body).Decode(&pagination); err != nil { + hasBody = false + } + + cursor := getNonNumericValue(queryCursor, hasBody, pagination.Cursor) + + res := PaginationResponse{ + NumPages: 0, + ResultArray: make([]interface{}, 0), + } + var cursorI, _ = hash(cursor) + for i := cursorI + 1; i < total && len(res.ResultArray) < 15; i++ { + res.ResultArray = append(res.ResultArray, unhash(i)) + } + + w.Header().Set("Content-Type", "application/json") + err := json.NewEncoder(w).Encode(res) + if err != nil { + w.WriteHeader(500) + } +} + func getValue(queryValue string, hasBody bool, paginationValue int) int { if hasBody { return paginationValue @@ -171,3 +214,11 @@ func getValue(queryValue string, hasBody bool, paginationValue int) int { return value } } + +func getNonNumericValue(queryValue string, hasBody bool, paginationValue string) string { + if hasBody { + return paginationValue + } else { + return queryValue + } +} From 22920de3b6be443f8536bed6d0a1126d2c30ecc1 Mon Sep 17 00:00:00 2001 From: Ian Bentley Date: Fri, 23 Feb 2024 12:01:09 -0500 Subject: [PATCH 2/2] iter --- internal/pagination/service.go | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/internal/pagination/service.go b/internal/pagination/service.go index 207aecc..e12b6c9 100644 --- a/internal/pagination/service.go +++ b/internal/pagination/service.go @@ -23,13 +23,9 @@ type NonNumericCursorRequest struct { } type PaginationResponse struct { -<<<<<<< HEAD - NumPages int `json:"numPages"` - ResultArray []int `json:"resultArray"` - Next *string `json:"next,omitempty"` -======= NumPages int `json:"numPages"` ResultArray []interface{} `json:"resultArray"` + Next *string `json:"next,omitempty"` } // Insecure reversable hashing for string cursors @@ -38,7 +34,6 @@ func hash(s string) (int, error) { } func unhash(h int) string { return strconv.Itoa(h) ->>>>>>> cf9ad59 (add endpoint to support non numeric cursor.) } const total = 20 @@ -151,7 +146,7 @@ func HandleURL(w http.ResponseWriter, r *http.Request) { res := PaginationResponse{ NumPages: 0, - ResultArray: make([]int, 0), + ResultArray: make([]interface{}, 0), } if attempts > 1 { @@ -184,7 +179,6 @@ func HandleNonNumericCursor(w http.ResponseWriter, r *http.Request) { if err := json.NewDecoder(r.Body).Decode(&pagination); err != nil { hasBody = false } - cursor := getNonNumericValue(queryCursor, hasBody, pagination.Cursor) res := PaginationResponse{ @@ -219,6 +213,10 @@ func getNonNumericValue(queryValue string, hasBody bool, paginationValue string) if hasBody { return paginationValue } else { - return queryValue + if queryValue == "" { + return "-1" + } else { + return queryValue + } } }