Skip to content

Commit

Permalink
attempt to abstract the pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
displague committed Apr 26, 2018
1 parent 5108358 commit c736b2f
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 41 deletions.
68 changes: 68 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"log"
"net/http"
"os"
"strconv"

"github.com/go-resty/resty"
)
Expand Down Expand Up @@ -144,3 +145,70 @@ func NewClient(codeAPIKey *string, transport http.RoundTripper) (*Client, error)
Managed: resources[managedName],
}, nil
}

type PagedResponse struct {
ListResponse
*PageOptions
}

type ListResponse interface {
Endpoint(*Client) string
AppendData(*resty.Response)
SetResult(*resty.Request)
ListHelper(*resty.Request, *ListOptions) error
}

// ListHelper abstracts fetching and pagination for GETmany endpoints
func (c *Client) ListHelper(i interface{}, opts *ListOptions) error {
req := c.R()
if opts != nil {
req.SetQueryParam("page", strconv.Itoa(opts.Page))
}

var (
err error
e string
pages int
results int
r *resty.Response
)

switch v := i.(type) {
case LinodeKernelsPagedResponse:
e = v.Endpoint(c)
req.SetResult(v) // Can I just set PagedResponse instead of specific type?
r, err = req.Get(e)
if err != nil {
return err
}

pages = r.Result().(*LinodeKernelsPagedResponse).Pages
results = r.Result().(*LinodeKernelsPagedResponse).Results
v.AppendData(r.Result().(*LinodeKernelsPagedResponse))
case LinodeTypesPagedResponse:
e = v.Endpoint(c)
req.SetResult(v) // Can I just set PagedResponse instead of specific type?
r, err = req.Get(e)
if err != nil {
return err
}

pages = r.Result().(*LinodeTypesPagedResponse).Pages
results = r.Result().(*LinodeTypesPagedResponse).Results
v.AppendData(r.Result().(*LinodeTypesPagedResponse))

default:
panic("what")
}

if opts == nil {
for page := 2; page <= pages; page = page + 1 {
c.ListHelper(i, &ListOptions{PageOptions: &PageOptions{Page: page}})
}
} else {
opts.Results = results
opts.Pages = pages
}

return nil
}
2 changes: 1 addition & 1 deletion example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func main() {
}
linodeClient.SetDebug(true)

types, err := linodeClient.ListTypes()
types, err := linodeClient.ListTypes(nil)
if err != nil {
log.Fatal(err)
}
Expand Down
44 changes: 17 additions & 27 deletions kernels.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ package golinode

import (
"fmt"
"strconv"

"github.com/go-resty/resty"
)

// LinodeKernel represents a linode kernel object
Expand All @@ -18,42 +19,31 @@ type LinodeKernel struct {

// LinodeKernelsPagedResponse represents a linode kernels API response for listing
type LinodeKernelsPagedResponse struct {
*PageOptions
*PagedResponse
Data []*LinodeKernel
}

// ListKernels lists linode kernels
func (c *Client) ListKernels(opts *ListOptions) ([]*LinodeKernel, error) {
e, err := c.Kernels.Endpoint()
if err != nil {
return nil, err
}
req := c.R().SetResult(&LinodeKernelsPagedResponse{})

if opts != nil {
req.SetQueryParam("page", strconv.Itoa(opts.Page))
}
response := LinodeKernelsPagedResponse{}
err := c.ListHelper(response, opts)
return response.Data, err
}

r, err := req.Get(e)
func (LinodeKernelsPagedResponse) Endpoint(c *Client) string {
endpoint, err := c.Kernels.Endpoint()
if err != nil {
return nil, err
panic(err)
}
return endpoint
}

data := r.Result().(*LinodeKernelsPagedResponse).Data
pages := r.Result().(*LinodeKernelsPagedResponse).Pages
results := r.Result().(*LinodeKernelsPagedResponse).Results

if opts == nil {
for page := 2; page <= pages; page = page + 1 {
next, _ := c.ListKernels(&ListOptions{PageOptions: &PageOptions{Page: page}})
data = append(data, next...)
}
} else {
opts.Results = results
opts.Pages = pages
}
func (resp *LinodeKernelsPagedResponse) AppendData(r *LinodeKernelsPagedResponse) {
(*resp).Data = append(resp.Data, r.Data...)
}

return data, nil
func (LinodeKernelsPagedResponse) SetResult(r *resty.Request) {
r.SetResult(LinodeKernelsPagedResponse{})
}

// GetKernel gets the kernel with the provided ID
Expand Down
37 changes: 24 additions & 13 deletions types.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package golinode

import "fmt"
import (
"fmt"

"github.com/go-resty/resty"
)

// LinodeType represents a linode type object
type LinodeType struct {
Expand Down Expand Up @@ -38,20 +42,27 @@ type LinodeTypesPagedResponse struct {
Data []*LinodeType
}

// ListTypes lists linode types
func (c *Client) ListTypes() ([]*LinodeType, error) {
e, err := c.Types.Endpoint()
if err != nil {
return nil, err
}
r, err := c.R().
SetResult(&LinodeTypesPagedResponse{}).
Get(e)
func (LinodeTypesPagedResponse) Endpoint(c *Client) string {
endpoint, err := c.Types.Endpoint()
if err != nil {
return nil, err
panic(err)
}
l := r.Result().(*LinodeTypesPagedResponse).Data
return l, nil
return endpoint
}

func (resp *LinodeTypesPagedResponse) AppendData(r *LinodeTypesPagedResponse) {
(*resp).Data = append(resp.Data, r.Data...)
}

func (LinodeTypesPagedResponse) SetResult(r *resty.Request) {
r.SetResult(LinodeTypesPagedResponse{})
}

// ListTypes lists linode types
func (c *Client) ListTypes(opts *ListOptions) ([]*LinodeType, error) {
response := LinodeTypesPagedResponse{}
err := c.ListHelper(response, opts)
return response.Data, err
}

// GetType gets the type with the provided ID
Expand Down

0 comments on commit c736b2f

Please sign in to comment.