Skip to content

Commit 7b8ca2a

Browse files
committed
Add cursor and offset pagination. Add cursor for list ticket comments.
1 parent e68b545 commit 7b8ca2a

File tree

4 files changed

+89
-12
lines changed

4 files changed

+89
-12
lines changed

fixture/GET/ticket_comments.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,10 @@
2222
"attachments": [],
2323
"created_at": "2019-06-03T02:23:47Z"
2424
}
25-
]
25+
],
26+
"meta": {
27+
"has_more": true,
28+
"after_cursor": "xxx",
29+
"before_cursor": "yyy"
30+
}
2631
}

zendesk/ticket_comment.go

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
// TicketCommentAPI is an interface containing all ticket comment related API methods
1111
type TicketCommentAPI interface {
1212
CreateTicketComment(ctx context.Context, ticketID int64, ticketComment TicketComment) (TicketComment, error)
13-
ListTicketComments(ctx context.Context, ticketID int64) ([]TicketComment, error)
13+
ListTicketComments(ctx context.Context, ticketID int64, opts *CursorPagination) (*ListTicketCommentsResult, error)
1414
MakeCommentPrivate(ctx context.Context, ticketID int64, ticketCommentID int64) error
1515
}
1616

@@ -82,25 +82,37 @@ func (z *Client) CreateTicketComment(ctx context.Context, ticketID int64, ticket
8282
return result, err
8383
}
8484

85+
type ListTicketCommentsResult struct {
86+
TicketComments []TicketComment `json:"comments"`
87+
Meta CursorPaginationMeta `json:"meta"`
88+
}
89+
8590
// ListTicketComments gets a list of comment for a specified ticket
8691
//
8792
// ref: https://developer.zendesk.com/rest_api/docs/support/ticket_comments#list-comments
88-
func (z *Client) ListTicketComments(ctx context.Context, ticketID int64) ([]TicketComment, error) {
89-
var result struct {
90-
TicketComments []TicketComment `json:"comments"`
93+
func (z *Client) ListTicketComments(ctx context.Context, ticketID int64, opts *CursorPagination) (*ListTicketCommentsResult, error) {
94+
url := fmt.Sprintf("/tickets/%d/comments.json", ticketID)
95+
96+
var err error
97+
if opts != nil {
98+
url, err = addOptions(url, opts)
99+
if err != nil {
100+
return nil, err
101+
}
91102
}
92103

93-
body, err := z.get(ctx, fmt.Sprintf("/tickets/%d/comments.json", ticketID))
104+
body, err := z.get(ctx, url)
94105
if err != nil {
95-
return []TicketComment{}, err
106+
return nil, err
96107
}
97108

109+
var result ListTicketCommentsResult
98110
err = json.Unmarshal(body, &result)
99111
if err != nil {
100-
return []TicketComment{}, err
112+
return nil, err
101113
}
102114

103-
return result.TicketComments, err
115+
return &result, err
104116
}
105117

106118
// MakeCommentPrivate converts an existing ticket comment to an internal note that is not publicly viewable.

zendesk/ticket_comment_test.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,26 @@ func TestListTicketComments(t *testing.T) {
4343
client := newTestClient(mockAPI)
4444
defer mockAPI.Close()
4545

46-
ticketComments, err := client.ListTicketComments(ctx, 2)
46+
result, err := client.ListTicketComments(ctx, 2, nil)
4747
if err != nil {
4848
t.Fatalf("Failed to list ticket comments: %s", err)
4949
}
5050

5151
expectedLength := 2
52-
if len(ticketComments) != expectedLength {
53-
t.Fatalf("Returned ticket comments does not have the expected length %d. Ticket comments length is %d", expectedLength, len(ticketComments))
52+
if len(result.TicketComments) != expectedLength {
53+
t.Fatalf("Returned ticket comments does not have the expected length %d. Ticket comments length is %d", expectedLength, len(result.TicketComments))
54+
}
55+
56+
expectedPaginationMeta := CursorPaginationMeta{
57+
HasMore: true,
58+
AfterCursor: "xxx",
59+
BeforeCursor: "yyy",
60+
}
61+
62+
if result.Meta != expectedPaginationMeta {
63+
t.Fatalf(`Failed to return correct cursor options.
64+
Expected: %+v
65+
Received: %+v`, expectedPaginationMeta, result.Meta)
5466
}
5567
}
5668

zendesk/zendesk.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,54 @@ type (
4040
Put(ctx context.Context, path string, data interface{}) ([]byte, error)
4141
Delete(ctx context.Context, path string) error
4242
}
43+
44+
// OffsetPagination contains options for using offset pagination.
45+
// Many endpoints support cursor pagination, which is preferred as
46+
// it is more performant on large datasets.
47+
OffsetPagination struct {
48+
// Page is the page number to request.
49+
Page int `url:"page",omitempty`
50+
51+
// PerPage is the number of results desired on each page.
52+
// Most endpoints support up to 100 records per page.
53+
PerPage int `url:"per_page",omitempty`
54+
}
55+
56+
// OffsetPaginationMeta contains next and previous page pointers.
57+
OffsetPaginationMeta struct {
58+
// NextPage is a link to the next page of results, nil if none left.
59+
NextPage string `json:"next_page",omitempty`
60+
61+
// PreviousPage is a link to the previous page of results, nil if on first page.
62+
PreviousPage string `json:"previous_page",omitempty`
63+
}
64+
65+
// CursorPagination contains options for using cursor pagination.
66+
// Cursor pagination is preferred where possible.
67+
CursorPagination struct {
68+
// PageSize sets the number of results per page.
69+
// Most endpoints support up to 100 records per page.
70+
PageSize int `url:"page[size]",omitempty`
71+
72+
// PageAfter provides the "next" cursor.
73+
PageAfter string `url:"page[after]",omitempty`
74+
75+
// PageBefore provides the "previous" cursor.
76+
PageBefore string `url:"page[before]",omitempty`
77+
}
78+
79+
// CursorPaginationMeta contains information concerning how to fetch
80+
// next and previous results, and if next results exist.
81+
CursorPaginationMeta struct {
82+
// HasMore is true if more results exist in the endpoint.
83+
HasMore bool `json:"has_more",omitempty`
84+
85+
// AfterCursor contains the cursor of the next result set.
86+
AfterCursor string `json:"after_cursor",omitempty`
87+
88+
// BeforeCursor contains the cursor of the previous result set.
89+
BeforeCursor string `json:"before_cursor",omitempty`
90+
}
4391
)
4492

4593
// NewClient creates new Zendesk API client

0 commit comments

Comments
 (0)