Skip to content

Commit c4e3703

Browse files
authored
Paginate (#136)
1 parent 47d2e58 commit c4e3703

19 files changed

Lines changed: 533 additions & 384 deletions

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Running changelog of releases since `2.0.0-rc.4`
2020
- Update Readme to show how to access `RequestExecutor` (Fixes #83)
2121
- Fixes Cache EOF (Fixes #103 and Fixes #36)
2222
- Update all enum objects to `type string` (Fixes #95)
23+
- Implement Pagination
2324

2425
## v2.0.0-rc.4
2526
- Updated Resource Executor to handle nil pointer dereference (#125, fix suggested by @johanbrandhorst)

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,20 @@ client.GetRequestExecutor().RefreshNext()
150150
appUserList, _, _ = client.Application.ListApplicationUsers(context.TODO(), appId, nil)
151151
```
152152

153+
### Pagination
154+
If your request comes back with more than the default or set limit, you can request the next page.
155+
156+
Exmaple of listing users 1 at a time:
157+
```go
158+
query := query.NewQueryParams(query.WithLimit(1))
159+
users, resp, err := client.User.ListUsers(ctx, query)
160+
// Do something with your users until you run out of users to iterate.
161+
if resp.HasNextPage() {
162+
var nextUserSet []*okta.User
163+
resp, err = resp.Next(ctx, &nextUserSet)
164+
}
165+
```
166+
153167
## Usage guide
154168

155169
These examples will help you understand how to use this library. You can also browse the full [API reference documentation][sdkapiref].

okta/okta.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package okta
2020

2121
import (
22+
"context"
2223
"fmt"
2324
"io/ioutil"
2425
"os/user"
@@ -60,7 +61,10 @@ type resource struct {
6061
client *Client
6162
}
6263

63-
func NewClient(conf ...ConfigSetter) (*Client, error) {
64+
type clientContextKey struct {
65+
}
66+
67+
func NewClient(ctx context.Context, conf ...ConfigSetter) (context.Context, *Client, error) {
6468
config := &config{}
6569

6670
setConfigDefaults(config)
@@ -113,7 +117,15 @@ func NewClient(conf ...ConfigSetter) (*Client, error) {
113117
c.TrustedOrigin = (*TrustedOriginResource)(&c.resource)
114118
c.User = (*UserResource)(&c.resource)
115119
c.UserFactor = (*UserFactorResource)(&c.resource)
116-
return c, nil
120+
121+
contextReturn := context.WithValue(ctx, clientContextKey{}, c)
122+
123+
return contextReturn, c, nil
124+
}
125+
126+
func ClientFromContext(ctx context.Context) (*Client, bool) {
127+
u, ok := ctx.Value(clientContextKey{}).(*Client)
128+
return u, ok
117129
}
118130

119131
func (c *Client) GetConfig() *config {

okta/requestExecutor.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,10 +340,51 @@ func Get429BackoffTime(ctx context.Context, response *http.Response) int64 {
340340

341341
type Response struct {
342342
*http.Response
343+
Self string
344+
NextPage string
345+
}
346+
347+
func (r *Response) Next(ctx context.Context, v interface{}) (*Response, error) {
348+
client, _ := ClientFromContext(ctx)
349+
350+
req, err := client.requestExecutor.WithAccept("application/json").WithContentType("application/json").NewRequest("GET", r.NextPage, nil)
351+
if err != nil {
352+
return nil, err
353+
}
354+
355+
return client.requestExecutor.Do(ctx, req, v)
356+
357+
}
358+
359+
func (r *Response) HasNextPage() bool {
360+
return r.NextPage != ""
343361
}
344362

345363
func newResponse(r *http.Response) *Response {
346364
response := &Response{Response: r}
365+
links := r.Header["Link"]
366+
367+
if len(links) > 0 {
368+
for _, link := range links {
369+
splitLinkHeader := strings.Split(link, ";")
370+
if len(splitLinkHeader) < 2 {
371+
continue
372+
}
373+
rawLink := strings.TrimRight(strings.TrimLeft(splitLinkHeader[0], "<"), ">")
374+
rawUrl, _ := url.Parse(rawLink)
375+
rawUrl.Scheme = ""
376+
rawUrl.Host = ""
377+
378+
if strings.Contains(link, `rel="self"`) {
379+
response.Self = rawUrl.String()
380+
}
381+
382+
if strings.Contains(link, `rel="next"`) {
383+
response.NextPage = rawUrl.String()
384+
}
385+
}
386+
}
387+
347388
return response
348389
}
349390

openapi/generator/templates/okta.go.hbs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
package okta
44

55
import (
6+
"context"
67
"fmt"
78
"io/ioutil"
89
"os/user"
@@ -29,7 +30,10 @@ type resource struct {
2930
client *Client
3031
}
3132

32-
func NewClient(conf ...ConfigSetter) (*Client, error) {
33+
type clientContextKey struct {
34+
}
35+
36+
func NewClient(ctx context.Context, conf ...ConfigSetter) (context.Context, *Client, error) {
3337
config := &config{}
3438

3539
setConfigDefaults(config)
@@ -67,7 +71,15 @@ func NewClient(conf ...ConfigSetter) (*Client, error) {
6771
c.resource.client = c
6872

6973
{{{getNewClientTagProps operations}}}
70-
return c, nil
74+
75+
contextReturn := context.WithValue(ctx, clientContextKey{}, c)
76+
77+
return contextReturn, c, nil
78+
}
79+
80+
func ClientFromContext(ctx context.Context) (*Client, bool) {
81+
u, ok := ctx.Value(clientContextKey{}).(*Client)
82+
return u, ok
7183
}
7284

7385
func (c *Client) GetConfig() *config {

0 commit comments

Comments
 (0)