add /buckets endpoint paging links

pull/10616/head
zhulongcheng 2018-12-09 23:25:35 +08:00
parent bce744f08d
commit cb8f7a1744
3 changed files with 62 additions and 20 deletions

View File

@ -75,12 +75,26 @@ type BucketFilter struct {
Organization *string Organization *string
} }
// FindOptions represents options passed to all find methods with multiple results. // QueryParams Converts BucketFilter fields to url query params.
type FindOptions struct { func (f BucketFilter) QueryParams() map[string][]string {
Limit int qp := map[string][]string{}
Offset int if f.ID != nil {
SortBy string qp["id"] = []string{f.ID.String()}
Descending bool }
if f.Name != nil {
qp["name"] = []string{*f.Name}
}
if f.OrganizationID != nil {
qp["orgID"] = []string{f.OrganizationID.String()}
}
if f.Organization != nil {
qp["org"] = []string{*f.Organization}
}
return qp
} }
// InternalBucketID returns the ID for an organization's specified internal bucket // InternalBucketID returns the ID for an organization's specified internal bucket

View File

@ -11,7 +11,7 @@ import (
"time" "time"
"github.com/influxdata/platform" "github.com/influxdata/platform"
errors "github.com/influxdata/platform/kit/errors" "github.com/influxdata/platform/kit/errors"
"github.com/julienschmidt/httprouter" "github.com/julienschmidt/httprouter"
) )
@ -195,8 +195,8 @@ func newBucketResponse(b *platform.Bucket) *bucketResponse {
} }
type bucketsResponse struct { type bucketsResponse struct {
Links map[string]string `json:"links"` Links *platform.PagingLinks `json:"links"`
Buckets []*bucketResponse `json:"buckets"` Buckets []*bucketResponse `json:"buckets"`
} }
func newBucketsResponse(opts platform.FindOptions, f platform.BucketFilter, bs []*platform.Bucket) *bucketsResponse { func newBucketsResponse(opts platform.FindOptions, f platform.BucketFilter, bs []*platform.Bucket) *bucketsResponse {
@ -205,10 +205,7 @@ func newBucketsResponse(opts platform.FindOptions, f platform.BucketFilter, bs [
rs = append(rs, newBucketResponse(b)) rs = append(rs, newBucketResponse(b))
} }
return &bucketsResponse{ return &bucketsResponse{
// TODO(desa): update links to include paging and filter information Links: newPagingLinks(bucketsPath, opts, f, len(bs)),
Links: map[string]string{
"self": "/api/v2/buckets",
},
Buckets: rs, Buckets: rs,
} }
} }
@ -357,14 +354,13 @@ func (h *BucketHandler) handleGetBuckets(w http.ResponseWriter, r *http.Request)
return return
} }
opts := platform.FindOptions{} bs, _, err := h.BucketService.FindBuckets(ctx, req.filter, req.opts)
bs, _, err := h.BucketService.FindBuckets(ctx, req.filter, opts)
if err != nil { if err != nil {
EncodeError(ctx, err, w) EncodeError(ctx, err, w)
return return
} }
if err := encodeResponse(ctx, w, http.StatusOK, newBucketsResponse(opts, req.filter, bs)); err != nil { if err := encodeResponse(ctx, w, http.StatusOK, newBucketsResponse(req.opts, req.filter, bs)); err != nil {
EncodeError(ctx, err, w) EncodeError(ctx, err, w)
return return
} }
@ -372,12 +368,20 @@ func (h *BucketHandler) handleGetBuckets(w http.ResponseWriter, r *http.Request)
type getBucketsRequest struct { type getBucketsRequest struct {
filter platform.BucketFilter filter platform.BucketFilter
opts platform.FindOptions
} }
func decodeGetBucketsRequest(ctx context.Context, r *http.Request) (*getBucketsRequest, error) { func decodeGetBucketsRequest(ctx context.Context, r *http.Request) (*getBucketsRequest, error) {
qp := r.URL.Query() qp := r.URL.Query()
req := &getBucketsRequest{} req := &getBucketsRequest{}
opts, err := decodeFindOptions(ctx, r)
if err != nil {
return nil, err
}
req.opts = *opts
if orgID := qp.Get("orgID"); orgID != "" { if orgID := qp.Get("orgID"); orgID != "" {
id, err := platform.IDFromString(orgID) id, err := platform.IDFromString(orgID)
if err != nil { if err != nil {

View File

@ -59,14 +59,26 @@ func TestService_handleGetBuckets(t *testing.T) {
}, },
}, },
}, },
args: args{}, args: args{
map[string][]string{
"limit": []string{"1"},
},
},
wants: wants{ wants: wants{
statusCode: http.StatusOK, statusCode: http.StatusOK,
contentType: "application/json; charset=utf-8", contentType: "application/json; charset=utf-8",
body: ` body: `
{ {
"links": { "links": {
"self": "/api/v2/buckets" "prev": {
"prev": ""
},
"self": {
"self": "/api/v2/buckets?descending=false&limit=1&offset=0"
},
"next": {
"next": "/api/v2/buckets?descending=false&limit=1&offset=1"
}
}, },
"buckets": [ "buckets": [
{ {
@ -105,14 +117,26 @@ func TestService_handleGetBuckets(t *testing.T) {
}, },
}, },
}, },
args: args{}, args: args{
map[string][]string{
"limit": []string{"1"},
},
},
wants: wants{ wants: wants{
statusCode: http.StatusOK, statusCode: http.StatusOK,
contentType: "application/json; charset=utf-8", contentType: "application/json; charset=utf-8",
body: ` body: `
{ {
"links": { "links": {
"self": "/api/v2/buckets" "prev": {
"prev": ""
},
"self": {
"self": "/api/v2/buckets?descending=false&limit=1&offset=0"
},
"next": {
"next": ""
}
}, },
"buckets": [] "buckets": []
}`, }`,