Skip to content

Instantly share code, notes, and snippets.

@kabece
Last active October 4, 2021 07:56
Show Gist options
  • Save kabece/1cb2a209982c42af714db21d8a744d42 to your computer and use it in GitHub Desktop.
Save kabece/1cb2a209982c42af714db21d8a744d42 to your computer and use it in GitHub Desktop.
func (r *chatRoomResolver) MessagesConnection(ctx context.Context, obj *model.ChatRoom,
first *int, after *string) (*model.MessagesConnection, error) {
// The cursor is base64 encoded by convention, so we need to decode it first
var decodedCursor string
if after != nil {
b, err := base64.StdEncoding.DecodeString(*after)
if err != nil {
return nil, err
}
decodedCursor = string(b)
}
// Here we could query the DB to get data, e.g.
// SELECT * FROM messages WHERE chat_room_id = obj.ID AND timestamp < decodedCursor
edges := make([]*model.MessagesEdge, *first)
count := 0
currentPage := false
// If no cursor present start from the top
if decodedCursor == "" {
currentPage = true
}
hasNextPage := false
// Iterating over the mocked messages to find the current page
// In real world use-case you should fetch only the required
// part of data from the database
for i, v := range r.Messages[obj.ID] {
if v.ID == decodedCursor {
currentPage = true
}
if currentPage && count < *first {
edges[count] = &model.MessagesEdge{
Cursor: base64.StdEncoding.EncodeToString([]byte(v.ID)),
Node: &v,
}
count++
}
// If there are any elements left after the current page
// we indicate that in the response
if count == *first && i < len(r.Messages[obj.ID]) {
hasNextPage = true
}
}
pageInfo := model.PageInfo{
StartCursor: base64.StdEncoding.EncodeToString([]byte(edges[0].Node.ID)),
EndCursor: base64.StdEncoding.EncodeToString([]byte(edges[count-1].Node.ID)),
HasNextPage: &hasNextPage,
}
mc := model.MessagesConnection{
Edges: edges[:count],
PageInfo: &pageInfo,
}
return &mc, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment