gocql icon indicating copy to clipboard operation
gocql copied to clipboard

How should paging be used in rest APIs

Open dancb10 opened this issue 2 years ago • 6 comments

While there are some examples here and here on how paging should work in theory, these examples do not clearly show on how you would use the paging state in a Json rest API. So the theory is that you execute a select statement, save the current paging state, return it to the user in string format and then use it the next time the user requests the next page.

I've tried using the examples you've posted such as: I have a struct that contains the paging state parameter

type MessagesRestDetails struct {
  PageState string `form:"pagestate" binding:"omitempty"`
}

And when a request is sent I bind it to a struct variable

var messagesRestDetails structs.MessagesRestDetails        
if err := c.BindQuery(&messagesRestDetails); err != nil {
  c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  return
}

I then execute the query as

var pageState []byte
if messagesRestDetails.PageState != "" {
  ps, err := base64.StdEncoding.DecodeString(messagesRestDetails.PageState)
  if err != nil {
      c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
      return
  }
  pageState = ps
}

iter := session.Query("SELECT * FROM messages.messages WHERE gid = ?", messagesGid.GID).PageSize(3).PageState(pageState).Iter()
nextPageState := iter.PageState()

And then the nextPageState I encode it to string and return it to the client

encodedStr := base64.StdEncoding.EncodeToString([]byte(nextPageState))

So while the first time I request this it works and the first three elements are returned in the API, when using the received page state value and send it in a new request I get"error": "illegal base64 data at input byte 165". That's because the encoded string contains a '\' character. So the question is how to properly send and receive the paging state in these requests?

dancb10 avatar Feb 13 '23 21:02 dancb10

Hello, do you have any suggestions on this?

dancb10 avatar Feb 15 '23 11:02 dancb10

@avelanarius - can you see if we have an idea for the above?

mykaul avatar Feb 15 '23 11:02 mykaul

Seems like it's a similar issues as this one but I've encoded the token and when trying to decode it I get the above mentioned error

dancb10 avatar Feb 15 '23 21:02 dancb10

And note that because this is sent in a GET request as parameter, the path will look something like: /messages/437407911753331250?cid=437407628419707442&pagestate=AAAAAKAAAAAUAAAAAQAAAAgAAAAGEfwtogCyMgEUAAAAAQAAAAgAAAAGM/dzTQACBPz///9/Q/VGQ2HTULAGFFSvSjmaAQAAADkAAAABGQAAABQAAAABAAAACAAAAN8XVqPvcUfIAQEZAAAAFAAAAAEAAAAIAAAA3xdWo+9xR8gBAQEAAAB8Tb0sWJ38vDUywrbsuBSiAQAAAAAA/////wAAAAA="

So I'm curious how can we pass the PageState from one request to another because even if you base64 encode it, it still doesn't work

dancb10 avatar Feb 15 '23 21:02 dancb10

I made it work by using hex encode/decode .e.g encodedStr := hex.EncodeToString(nextPageState)

dancb10 avatar Feb 15 '23 21:02 dancb10

The StdEncoding will not work, the URLEncoding will work @dancb10.

mmatczuk avatar Feb 16 '23 09:02 mmatczuk