From ded6a0e401b5e67b74d958faf63d2203dc926fc2 Mon Sep 17 00:00:00 2001 From: Jacob Bednarz Date: Fri, 21 Oct 2022 16:13:22 +1100 Subject: [PATCH 1/3] workers_kv: modernise all methods - Updates the methods to make the experimental client method signatures for consistency - Renames some methods to be clearer about what they do - Automatically paginate List* requests --- workers_kv.go | 203 +++++++++++++++++++------------------ workers_kv_example_test.go | 106 ++++++++++--------- workers_kv_test.go | 95 +++++++++-------- 3 files changed, 210 insertions(+), 194 deletions(-) diff --git a/workers_kv.go b/workers_kv.go index 14ca55a42..f7a01bc06 100644 --- a/workers_kv.go +++ b/workers_kv.go @@ -6,16 +6,18 @@ import ( "fmt" "net/http" "net/url" - "strconv" - - "errors" ) -// WorkersKVNamespaceRequest provides parameters for creating and updating storage namespaces. -type WorkersKVNamespaceRequest struct { +// CreateWorkersKVNamespaceParams provides parameters for creating and updating storage namespaces. +type CreateWorkersKVNamespaceParams struct { Title string `json:"title"` } +type UpdateWorkersKVNamespaceParams struct { + NamespaceID string `json:"-"` + Title string `json:"title"` +} + // WorkersKVPair is used in an array in the request to the bulk KV api. type WorkersKVPair struct { Key string `json:"key"` @@ -26,9 +28,6 @@ type WorkersKVPair struct { Base64 bool `json:"base64,omitempty"` } -// WorkersKVBulkWriteRequest is the request to the bulk KV api. -type WorkersKVBulkWriteRequest []*WorkersKVPair - // WorkersKVNamespaceResponse is the response received when creating storage namespaces. type WorkersKVNamespaceResponse struct { Response @@ -56,13 +55,6 @@ type StorageKey struct { Metadata interface{} `json:"metadata"` } -// ListWorkersKVsOptions contains optional parameters for listing a namespace's keys. -type ListWorkersKVsOptions struct { - Limit *int - Cursor *string - Prefix *string -} - // ListStorageKeysResponse contains a slice of keys belonging to a storage namespace, // pagination information, and an embedded response struct. type ListStorageKeysResponse struct { @@ -71,14 +63,51 @@ type ListStorageKeysResponse struct { ResultInfo `json:"result_info"` } +type ListWorkersKVNamespacesParams struct { + ResultInfo +} + +type WriteWorkersKVEntryParams struct { + NamespaceID string + Key string + Value []byte +} + +type WriteWorkersKVEntriesParams struct { + NamespaceID string + KVs []*WorkersKVPair +} + +type GetWorkersKVParams struct { + NamespaceID string + Key string +} + +type DeleteWorkersKVEntryParams struct { + NamespaceID string + Key string +} + +type DeleteWorkersKVEntriesParams struct { + NamespaceID string + Keys []string +} + +type ListWorkersKVsParams struct { + NamespaceID string `url:"-"` + Limit int `url:"limit,omitempty"` + Cursor string `url:"cursor,omitempty"` + Prefix string `url:"prefix,omitempty"` +} + // CreateWorkersKVNamespace creates a namespace under the given title. // A 400 is returned if the account already owns a namespace with this title. // A namespace must be explicitly deleted to be replaced. // // API reference: https://api.cloudflare.com/#workers-kv-namespace-create-a-namespace -func (api *API) CreateWorkersKVNamespace(ctx context.Context, req *WorkersKVNamespaceRequest) (WorkersKVNamespaceResponse, error) { - uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces", api.AccountID) - res, err := api.makeRequestContext(ctx, http.MethodPost, uri, req) +func (api *API) CreateWorkersKVNamespace(ctx context.Context, rc *ResourceContainer, params CreateWorkersKVNamespaceParams) (WorkersKVNamespaceResponse, error) { + uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces", rc.Identifier) + res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params) if err != nil { return WorkersKVNamespaceResponse{}, err } @@ -91,49 +120,52 @@ func (api *API) CreateWorkersKVNamespace(ctx context.Context, req *WorkersKVName return result, err } -// ListWorkersKVNamespaces lists storage namespaces +// ListWorkersKVNamespaces lists storage namespaces. // // API reference: https://api.cloudflare.com/#workers-kv-namespace-list-namespaces -func (api *API) ListWorkersKVNamespaces(ctx context.Context) ([]WorkersKVNamespace, error) { - v := url.Values{} - v.Set("per_page", "100") +func (api *API) ListWorkersKVNamespaces(ctx context.Context, rc *ResourceContainer, params ListWorkersKVNamespacesParams) ([]WorkersKVNamespace, *ResultInfo, error) { + autoPaginate := true + if params.PerPage >= 1 || params.Page >= 1 { + autoPaginate = false + } + if params.PerPage < 1 { + params.PerPage = 50 + } + if params.Page < 1 { + params.Page = 1 + } var namespaces []WorkersKVNamespace - page := 1 - + var nsResponse ListWorkersKVNamespacesResponse for { - v.Set("page", strconv.Itoa(page)) - uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces?%s", api.AccountID, v.Encode()) + uri := buildURI(fmt.Sprintf("/accounts/%s/storage/kv/namespaces", rc.Identifier), params) + res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) if err != nil { - return []WorkersKVNamespace{}, err + return []WorkersKVNamespace{}, &ResultInfo{}, err } - var p ListWorkersKVNamespacesResponse - if err := json.Unmarshal(res, &p); err != nil { - return []WorkersKVNamespace{}, fmt.Errorf("%s: %w", errUnmarshalError, err) + err = json.Unmarshal(res, &nsResponse) + if err != nil { + return []WorkersKVNamespace{}, &ResultInfo{}, fmt.Errorf("failed to unmarshal workers KV namespaces JSON data: %w", err) } - if !p.Success { - return []WorkersKVNamespace{}, errors.New(errRequestNotSuccessful) - } + namespaces = append(namespaces, nsResponse.Result...) + params.ResultInfo = nsResponse.ResultInfo.Next() - namespaces = append(namespaces, p.Result...) - if p.ResultInfo.Page >= p.ResultInfo.TotalPages { + if params.ResultInfo.Done() || !autoPaginate { break } - - page++ } - return namespaces, nil + return namespaces, &nsResponse.ResultInfo, nil } -// DeleteWorkersKVNamespace deletes the namespace corresponding to the given ID +// DeleteWorkersKVNamespace deletes the namespace corresponding to the given ID. // // API reference: https://api.cloudflare.com/#workers-kv-namespace-remove-a-namespace -func (api *API) DeleteWorkersKVNamespace(ctx context.Context, namespaceID string) (Response, error) { - uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces/%s", api.AccountID, namespaceID) +func (api *API) DeleteWorkersKVNamespace(ctx context.Context, rc *ResourceContainer, namespaceID string) (Response, error) { + uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces/%s", rc.Identifier, namespaceID) res, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil) if err != nil { return Response{}, err @@ -147,12 +179,12 @@ func (api *API) DeleteWorkersKVNamespace(ctx context.Context, namespaceID string return result, err } -// UpdateWorkersKVNamespace modifies a namespace's title +// UpdateWorkersKVNamespace modifies a KV namespace based on the ID. // // API reference: https://api.cloudflare.com/#workers-kv-namespace-rename-a-namespace -func (api *API) UpdateWorkersKVNamespace(ctx context.Context, namespaceID string, req *WorkersKVNamespaceRequest) (Response, error) { - uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces/%s", api.AccountID, namespaceID) - res, err := api.makeRequestContext(ctx, http.MethodPut, uri, req) +func (api *API) UpdateWorkersKVNamespace(ctx context.Context, rc *ResourceContainer, params UpdateWorkersKVNamespaceParams) (Response, error) { + uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces/%s", rc.Identifier, params.NamespaceID) + res, err := api.makeRequestContext(ctx, http.MethodPut, uri, params) if err != nil { return Response{}, err } @@ -165,14 +197,13 @@ func (api *API) UpdateWorkersKVNamespace(ctx context.Context, namespaceID string return result, err } -// WriteWorkersKV writes a value identified by a key. +// WriteWorkersKVEntry writes a single KV value based on the key. // // API reference: https://api.cloudflare.com/#workers-kv-namespace-write-key-value-pair -func (api *API) WriteWorkersKV(ctx context.Context, namespaceID, key string, value []byte) (Response, error) { - key = url.PathEscape(key) - uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces/%s/values/%s", api.AccountID, namespaceID, key) +func (api *API) WriteWorkersKVEntry(ctx context.Context, rc *ResourceContainer, params WriteWorkersKVEntryParams) (Response, error) { + uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces/%s/values/%s", rc.Identifier, params.NamespaceID, url.PathEscape(params.Key)) res, err := api.makeRequestContextWithHeaders( - ctx, http.MethodPut, uri, value, http.Header{"Content-Type": []string{"application/octet-stream"}}, + ctx, http.MethodPut, uri, params.Value, http.Header{"Content-Type": []string{"application/octet-stream"}}, ) if err != nil { return Response{}, err @@ -186,13 +217,13 @@ func (api *API) WriteWorkersKV(ctx context.Context, namespaceID, key string, val return result, err } -// WriteWorkersKVBulk writes multiple KVs at once. +// WriteWorkersKVEntries writes multiple KVs at once. // // API reference: https://api.cloudflare.com/#workers-kv-namespace-write-multiple-key-value-pairs -func (api *API) WriteWorkersKVBulk(ctx context.Context, namespaceID string, kvs WorkersKVBulkWriteRequest) (Response, error) { - uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces/%s/bulk", api.AccountID, namespaceID) +func (api *API) WriteWorkersKVEntries(ctx context.Context, rc *ResourceContainer, params WriteWorkersKVEntriesParams) (Response, error) { + uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces/%s/bulk", rc.Identifier, params.NamespaceID) res, err := api.makeRequestContextWithHeaders( - ctx, http.MethodPut, uri, kvs, http.Header{"Content-Type": []string{"application/json"}}, + ctx, http.MethodPut, uri, params.KVs, http.Header{"Content-Type": []string{"application/json"}}, ) if err != nil { return Response{}, err @@ -206,12 +237,12 @@ func (api *API) WriteWorkersKVBulk(ctx context.Context, namespaceID string, kvs return result, err } -// ReadWorkersKV returns the value associated with the given key in the given namespace +// GetWorkersKV returns the value associated with the given key in the +// given namespace. // // API reference: https://api.cloudflare.com/#workers-kv-namespace-read-key-value-pair -func (api API) ReadWorkersKV(ctx context.Context, namespaceID, key string) ([]byte, error) { - key = url.PathEscape(key) - uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces/%s/values/%s", api.AccountID, namespaceID, key) +func (api API) GetWorkersKV(ctx context.Context, rc *ResourceContainer, params GetWorkersKVParams) ([]byte, error) { + uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces/%s/values/%s", rc.Identifier, params.NamespaceID, url.PathEscape(params.Key)) res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) if err != nil { return nil, err @@ -219,12 +250,11 @@ func (api API) ReadWorkersKV(ctx context.Context, namespaceID, key string) ([]by return res, nil } -// DeleteWorkersKV deletes a key and value for a provided storage namespace +// DeleteWorkersKVEntry deletes a key and value for a provided storage namespace. // // API reference: https://api.cloudflare.com/#workers-kv-namespace-delete-key-value-pair -func (api API) DeleteWorkersKV(ctx context.Context, namespaceID, key string) (Response, error) { - key = url.PathEscape(key) - uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces/%s/values/%s", api.AccountID, namespaceID, key) +func (api API) DeleteWorkersKVEntry(ctx context.Context, rc *ResourceContainer, params DeleteWorkersKVEntryParams) (Response, error) { + uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces/%s/values/%s", rc.Identifier, params.NamespaceID, url.PathEscape(params.Key)) res, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil) if err != nil { return Response{}, err @@ -237,13 +267,13 @@ func (api API) DeleteWorkersKV(ctx context.Context, namespaceID, key string) (Re return result, err } -// DeleteWorkersKVBulk deletes multiple KVs at once. +// DeleteWorkersKVEntries deletes multiple KVs at once. // // API reference: https://api.cloudflare.com/#workers-kv-namespace-delete-multiple-key-value-pairs -func (api *API) DeleteWorkersKVBulk(ctx context.Context, namespaceID string, keys []string) (Response, error) { - uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces/%s/bulk", api.AccountID, namespaceID) +func (api *API) DeleteWorkersKVEntries(ctx context.Context, rc *ResourceContainer, params DeleteWorkersKVEntriesParams) (Response, error) { + uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces/%s/bulk", rc.Identifier, params.NamespaceID) res, err := api.makeRequestContextWithHeaders( - ctx, http.MethodDelete, uri, keys, http.Header{"Content-Type": []string{"application/json"}}, + ctx, http.MethodDelete, uri, params.Keys, http.Header{"Content-Type": []string{"application/json"}}, ) if err != nil { return Response{}, err @@ -257,43 +287,14 @@ func (api *API) DeleteWorkersKVBulk(ctx context.Context, namespaceID string, key return result, err } -// ListWorkersKVs lists a namespace's keys -// -// API Reference: https://api.cloudflare.com/#workers-kv-namespace-list-a-namespace-s-keys -func (api API) ListWorkersKVs(ctx context.Context, namespaceID string) (ListStorageKeysResponse, error) { - uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces/%s/keys", api.AccountID, namespaceID) - res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) - if err != nil { - return ListStorageKeysResponse{}, err - } - - result := ListStorageKeysResponse{} - if err := json.Unmarshal(res, &result); err != nil { - return result, fmt.Errorf("%s: %w", errUnmarshalError, err) - } - return result, err -} - -// encode encodes non-nil fields into URL encoded form. -func (o ListWorkersKVsOptions) encode() string { - v := url.Values{} - if o.Limit != nil { - v.Set("limit", strconv.Itoa(*o.Limit)) - } - if o.Cursor != nil { - v.Set("cursor", *o.Cursor) - } - if o.Prefix != nil { - v.Set("prefix", *o.Prefix) - } - return v.Encode() -} - -// ListWorkersKVsWithOptions lists a namespace's keys with optional parameters +// ListWorkersKVKeys lists a namespace's keys. // // API Reference: https://api.cloudflare.com/#workers-kv-namespace-list-a-namespace-s-keys -func (api API) ListWorkersKVsWithOptions(ctx context.Context, namespaceID string, o ListWorkersKVsOptions) (ListStorageKeysResponse, error) { - uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces/%s/keys?%s", api.AccountID, namespaceID, o.encode()) +func (api API) ListWorkersKVKeys(ctx context.Context, rc *ResourceContainer, params ListWorkersKVsParams) (ListStorageKeysResponse, error) { + uri := buildURI( + fmt.Sprintf("/accounts/%s/storage/kv/namespaces/%s/keys", rc.Identifier, params.NamespaceID), + params, + ) res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) if err != nil { return ListStorageKeysResponse{}, err diff --git a/workers_kv_example_test.go b/workers_kv_example_test.go index 23b4a7807..233adbc66 100644 --- a/workers_kv_example_test.go +++ b/workers_kv_example_test.go @@ -15,13 +15,13 @@ const ( ) func ExampleAPI_CreateWorkersKVNamespace() { - api, err := cloudflare.New(apiKey, user, cloudflare.UsingAccount(accountID)) + api, err := cloudflare.New(apiKey, user) if err != nil { log.Fatal(err) } - req := &cloudflare.WorkersKVNamespaceRequest{Title: "test_namespace2"} - response, err := api.CreateWorkersKVNamespace(context.Background(), req) + req := cloudflare.CreateWorkersKVNamespaceParams{Title: "test_namespace2"} + response, err := api.CreateWorkersKVNamespace(context.Background(), cloudflare.AccountIdentifier(accountID), req) if err != nil { log.Fatal(err) } @@ -30,26 +30,35 @@ func ExampleAPI_CreateWorkersKVNamespace() { } func ExampleAPI_ListWorkersKVNamespaces() { - api, err := cloudflare.New(apiKey, user, cloudflare.UsingAccount(accountID)) + api, err := cloudflare.New(apiKey, user) if err != nil { log.Fatal(err) } - lsr, err := api.ListWorkersKVNamespaces(context.Background()) + lsr, _, err := api.ListWorkersKVNamespaces(context.Background(), cloudflare.AccountIdentifier(accountID), cloudflare.ListWorkersKVNamespacesParams{}) if err != nil { log.Fatal(err) } fmt.Println(lsr) + + resp, _, err := api.ListWorkersKVNamespaces(context.Background(), cloudflare.AccountIdentifier(accountID), cloudflare.ListWorkersKVNamespacesParams{ResultInfo: cloudflare.ResultInfo{ + PerPage: 10, + }}) + if err != nil { + log.Fatal(err) + } + + fmt.Println(resp) } func ExampleAPI_DeleteWorkersKVNamespace() { - api, err := cloudflare.New(apiKey, user, cloudflare.UsingAccount(accountID)) + api, err := cloudflare.New(apiKey, user) if err != nil { log.Fatal(err) } - response, err := api.DeleteWorkersKVNamespace(context.Background(), namespace) + response, err := api.DeleteWorkersKVNamespace(context.Background(), cloudflare.AccountIdentifier(accountID), namespace) if err != nil { log.Fatal(err) } @@ -58,12 +67,15 @@ func ExampleAPI_DeleteWorkersKVNamespace() { } func ExampleAPI_UpdateWorkersKVNamespace() { - api, err := cloudflare.New(apiKey, user, cloudflare.UsingAccount(accountID)) + api, err := cloudflare.New(apiKey, user) if err != nil { log.Fatal(err) } - resp, err := api.UpdateWorkersKVNamespace(context.Background(), namespace, &cloudflare.WorkersKVNamespaceRequest{Title: "test_title"}) + resp, err := api.UpdateWorkersKVNamespace(context.Background(), cloudflare.AccountIdentifier(accountID), cloudflare.UpdateWorkersKVNamespaceParams{ + NamespaceID: namespace, + Title: "test_title", + }) if err != nil { log.Fatal(err) } @@ -71,8 +83,8 @@ func ExampleAPI_UpdateWorkersKVNamespace() { fmt.Println(resp) } -func ExampleAPI_WriteWorkersKV() { - api, err := cloudflare.New(apiKey, user, cloudflare.UsingAccount(accountID)) +func ExampleAPI_WriteWorkersKVEntry() { + api, err := cloudflare.New(apiKey, user) if err != nil { log.Fatal(err) } @@ -80,7 +92,11 @@ func ExampleAPI_WriteWorkersKV() { payload := []byte("test payload") key := "test_key" - resp, err := api.WriteWorkersKV(context.Background(), namespace, key, payload) + resp, err := api.WriteWorkersKVEntry(context.Background(), cloudflare.AccountIdentifier(accountID), cloudflare.WriteWorkersKVEntryParams{ + NamespaceID: namespace, + Key: key, + Value: payload, + }) if err != nil { log.Fatal(err) } @@ -88,13 +104,13 @@ func ExampleAPI_WriteWorkersKV() { fmt.Println(resp) } -func ExampleAPI_WriteWorkersKVBulk() { - api, err := cloudflare.New(apiKey, user, cloudflare.UsingAccount(accountID)) +func ExampleAPI_WriteWorkersKVEntries() { + api, err := cloudflare.New(apiKey, user) if err != nil { log.Fatal(err) } - payload := cloudflare.WorkersKVBulkWriteRequest{ + payload := []*cloudflare.WorkersKVPair{ { Key: "key1", Value: "value1", @@ -107,7 +123,10 @@ func ExampleAPI_WriteWorkersKVBulk() { }, } - resp, err := api.WriteWorkersKVBulk(context.Background(), namespace, payload) + resp, err := api.WriteWorkersKVEntries(context.Background(), cloudflare.AccountIdentifier(accountID), cloudflare.WriteWorkersKVEntriesParams{ + NamespaceID: namespace, + KVs: payload, + }) if err != nil { log.Fatal(err) } @@ -115,14 +134,14 @@ func ExampleAPI_WriteWorkersKVBulk() { fmt.Println(resp) } -func ExampleAPI_ReadWorkersKV() { - api, err := cloudflare.New(apiKey, user, cloudflare.UsingAccount(accountID)) +func ExampleAPI_GetWorkersKV() { + api, err := cloudflare.New(apiKey, user) if err != nil { log.Fatal(err) } key := "test_key" - resp, err := api.ReadWorkersKV(context.Background(), namespace, key) + resp, err := api.GetWorkersKV(context.Background(), cloudflare.AccountIdentifier(accountID), cloudflare.GetWorkersKVParams{NamespaceID: namespace, Key: key}) if err != nil { log.Fatal(err) } @@ -130,14 +149,17 @@ func ExampleAPI_ReadWorkersKV() { fmt.Printf("%s\n", resp) } -func ExampleAPI_DeleteWorkersKV() { - api, err := cloudflare.New(apiKey, user, cloudflare.UsingAccount(accountID)) +func ExampleAPI_DeleteWorkersKVEntry() { + api, err := cloudflare.New(apiKey, user) if err != nil { log.Fatal(err) } key := "test_key" - resp, err := api.DeleteWorkersKV(context.Background(), namespace, key) + resp, err := api.DeleteWorkersKVEntry(context.Background(), cloudflare.AccountIdentifier(accountID), cloudflare.DeleteWorkersKVEntryParams{ + NamespaceID: namespace, + Key: key, + }) if err != nil { log.Fatal(err) } @@ -145,15 +167,18 @@ func ExampleAPI_DeleteWorkersKV() { fmt.Printf("%+v\n", resp) } -func ExampleAPI_DeleteWorkersKVBulk() { - api, err := cloudflare.New(apiKey, user, cloudflare.UsingAccount(accountID)) +func ExampleAPI_DeleteWorkersKVEntries() { + api, err := cloudflare.New(apiKey, user) if err != nil { log.Fatal(err) } keys := []string{"key1", "key2", "key3"} - resp, err := api.DeleteWorkersKVBulk(context.Background(), namespace, keys) + resp, err := api.DeleteWorkersKVEntries(context.Background(), cloudflare.AccountIdentifier(accountID), cloudflare.DeleteWorkersKVEntriesParams{ + NamespaceID: namespace, + Keys: keys, + }) if err != nil { log.Fatal(err) } @@ -161,22 +186,8 @@ func ExampleAPI_DeleteWorkersKVBulk() { fmt.Println(resp) } -func ExampleAPI_ListWorkersKVs() { - api, err := cloudflare.New(apiKey, user, cloudflare.UsingAccount(accountID)) - if err != nil { - log.Fatal(err) - } - - resp, err := api.ListWorkersKVs(context.Background(), namespace) - if err != nil { - log.Fatal(err) - } - - fmt.Println(resp) -} - -func ExampleAPI_ListWorkersKVsWithOptions() { - api, err := cloudflare.New(apiKey, user, cloudflare.UsingAccount(accountID)) +func ExampleAPI_ListWorkersKVKeys() { + api, err := cloudflare.New(apiKey, user) if err != nil { log.Fatal(err) } @@ -185,13 +196,12 @@ func ExampleAPI_ListWorkersKVsWithOptions() { prefix := "my-prefix" cursor := "AArAbNSOuYcr4HmzGH02-cfDN8Ck9ejOwkn_Ai5rsn7S9NEqVJBenU9-gYRlrsziyjKLx48hNDLvtYzBAmkPsLGdye8ECr5PqFYcIOfUITdhkyTc1x6bV8nmyjz5DO-XaZH4kYY1KfqT8NRBIe5sic6yYt3FUDttGjafy0ivi-Up-TkVdRB0OxCf3O3OB-svG6DXheV5XTdDNrNx1o_CVqy2l2j0F4iKV1qFe_KhdkjC7Y6QjhUZ1MOb3J_uznNYVCoxZ-bVAAsJmXA" - options := cloudflare.ListWorkersKVsOptions{ - Limit: &limit, - Prefix: &prefix, - Cursor: &cursor, - } - - resp, err := api.ListWorkersKVsWithOptions(context.Background(), namespace, options) + resp, err := api.ListWorkersKVKeys(context.Background(), cloudflare.AccountIdentifier(accountID), cloudflare.ListWorkersKVsParams{ + NamespaceID: namespace, + Prefix: prefix, + Limit: limit, + Cursor: cursor, + }) if err != nil { log.Fatal(err) } diff --git a/workers_kv_test.go b/workers_kv_test.go index ee64fb273..1ad7ae091 100644 --- a/workers_kv_test.go +++ b/workers_kv_test.go @@ -13,7 +13,7 @@ import ( ) func TestWorkersKV_CreateWorkersKVNamespace(t *testing.T) { - setup(UsingAccount("foo")) + setup() defer teardown() response := `{ @@ -26,13 +26,13 @@ func TestWorkersKV_CreateWorkersKVNamespace(t *testing.T) { "messages": [] }` - mux.HandleFunc("/accounts/foo/storage/kv/namespaces", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/accounts/"+testAccountID+"/storage/kv/namespaces", func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, http.MethodPost, r.Method, "Expected method 'POST', got %s", r.Method) w.Header().Set("content-type", "application/javascript") fmt.Fprintf(w, response) //nolint }) - res, err := client.CreateWorkersKVNamespace(context.Background(), &WorkersKVNamespaceRequest{Title: "Namespace"}) + res, err := client.CreateWorkersKVNamespace(context.Background(), AccountIdentifier(testAccountID), CreateWorkersKVNamespaceParams{Title: "Namespace"}) want := WorkersKVNamespaceResponse{ successResponse, WorkersKVNamespace{ @@ -47,7 +47,7 @@ func TestWorkersKV_CreateWorkersKVNamespace(t *testing.T) { } func TestWorkersKV_DeleteWorkersKVNamespace(t *testing.T) { - setup(UsingAccount("foo")) + setup() defer teardown() namespace := "3aeaxxxxee014exxxx4cf66xxxxc0448" @@ -57,13 +57,13 @@ func TestWorkersKV_DeleteWorkersKVNamespace(t *testing.T) { "messages": [] }` - mux.HandleFunc(fmt.Sprintf("/accounts/foo/storage/kv/namespaces/%s", namespace), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc(fmt.Sprintf("/accounts/"+testAccountID+"/storage/kv/namespaces/%s", namespace), func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, http.MethodDelete, r.Method, "Expected method 'DELETE', got %s", r.Method) w.Header().Set("content-type", "application/javascript") fmt.Fprintf(w, response) //nolint }) - res, err := client.DeleteWorkersKVNamespace(context.Background(), namespace) + res, err := client.DeleteWorkersKVNamespace(context.Background(), AccountIdentifier(testAccountID), namespace) want := successResponse if assert.NoError(t, err) { @@ -71,8 +71,8 @@ func TestWorkersKV_DeleteWorkersKVNamespace(t *testing.T) { } } -func TestWorkersKV_ListWorkersKVNamespace(t *testing.T) { - setup(UsingAccount("foo")) +func TestWorkersKV_ListWorkersKVNamespaces(t *testing.T) { + setup() defer teardown() response := `{ @@ -96,13 +96,13 @@ func TestWorkersKV_ListWorkersKVNamespace(t *testing.T) { } }` - mux.HandleFunc("/accounts/foo/storage/kv/namespaces", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/accounts/"+testAccountID+"/storage/kv/namespaces", func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method) w.Header().Set("content-type", "application/javascript") fmt.Fprintf(w, response) //nolint }) - res, err := client.ListWorkersKVNamespaces(context.Background()) + res, _, err := client.ListWorkersKVNamespaces(context.Background(), AccountIdentifier(testAccountID), ListWorkersKVNamespacesParams{}) want := []WorkersKVNamespace{ { ID: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", @@ -126,7 +126,7 @@ func TestWorkersKV_ListWorkersKVNamespace(t *testing.T) { } func TestWorkersKV_ListWorkersKVNamespaceMultiplePages(t *testing.T) { - setup(UsingAccount("foo")) + setup() defer teardown() response1 := `{ @@ -165,7 +165,7 @@ func TestWorkersKV_ListWorkersKVNamespaceMultiplePages(t *testing.T) { } }` - mux.HandleFunc("/accounts/foo/storage/kv/namespaces", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/accounts/"+testAccountID+"/storage/kv/namespaces", func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method) w.Header().Set("content-type", "application/javascript") @@ -180,7 +180,7 @@ func TestWorkersKV_ListWorkersKVNamespaceMultiplePages(t *testing.T) { } }) - res, err := client.ListWorkersKVNamespaces(context.Background()) + res, _, err := client.ListWorkersKVNamespaces(context.Background(), AccountIdentifier(testAccountID), ListWorkersKVNamespacesParams{}) want := []WorkersKVNamespace{ { ID: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", @@ -204,7 +204,7 @@ func TestWorkersKV_ListWorkersKVNamespaceMultiplePages(t *testing.T) { } func TestWorkersKV_UpdateWorkersKVNamespace(t *testing.T) { - setup(UsingAccount("foo")) + setup() defer teardown() namespace := "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" @@ -215,13 +215,13 @@ func TestWorkersKV_UpdateWorkersKVNamespace(t *testing.T) { "messages": [] }` - mux.HandleFunc(fmt.Sprintf("/accounts/foo/storage/kv/namespaces/%s", namespace), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc(fmt.Sprintf("/accounts/"+testAccountID+"/storage/kv/namespaces/%s", namespace), func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, http.MethodPut, r.Method, "Expected method 'PUT', got %s", r.Method) w.Header().Set("content-type", "application/javascript") fmt.Fprintf(w, response) //nolint }) - res, err := client.UpdateWorkersKVNamespace(context.Background(), namespace, &WorkersKVNamespaceRequest{Title: "Namespace"}) + res, err := client.UpdateWorkersKVNamespace(context.Background(), AccountIdentifier(testAccountID), UpdateWorkersKVNamespaceParams{Title: "Namespace", NamespaceID: namespace}) want := successResponse if assert.NoError(t, err) { @@ -229,8 +229,8 @@ func TestWorkersKV_UpdateWorkersKVNamespace(t *testing.T) { } } -func TestWorkersKV_WriteWorkersKV(t *testing.T) { - setup(UsingAccount("foo")) +func TestWorkersKV_WriteWorkersKVEntry(t *testing.T) { + setup() defer teardown() key := "test_key" @@ -243,25 +243,29 @@ func TestWorkersKV_WriteWorkersKV(t *testing.T) { "messages": [] }` - mux.HandleFunc(fmt.Sprintf("/accounts/foo/storage/kv/namespaces/%s/values/%s", namespace, key), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc(fmt.Sprintf("/accounts/"+testAccountID+"/storage/kv/namespaces/%s/values/%s", namespace, key), func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, http.MethodPut, r.Method, "Expected method 'PUT', got %s", r.Method) w.Header().Set("content-type", "application/octet-stream") fmt.Fprintf(w, response) //nolint }) want := successResponse - res, err := client.WriteWorkersKV(context.Background(), namespace, key, value) + res, err := client.WriteWorkersKVEntry(context.Background(), AccountIdentifier(testAccountID), WriteWorkersKVEntryParams{NamespaceID: namespace, Key: key, Value: value}) if assert.NoError(t, err) { assert.Equal(t, want, res) } } -func TestWorkersKV_WriteWorkersKVBulk(t *testing.T) { - setup(UsingAccount("foo")) +func TestWorkersKV_WriteWorkersKVEntries(t *testing.T) { + setup() defer teardown() - kvs := WorkersKVBulkWriteRequest{{Key: "key1", Value: "value1"}, {Key: "key2", Value: "value2"}, {Key: "key3", Value: "value3", Metadata: "meta3", Base64: true}} + kvs := []*WorkersKVPair{ + {Key: "key1", Value: "value1"}, + {Key: "key2", Value: "value2"}, + {Key: "key3", Value: "value3", Metadata: "meta3", Base64: true}, + } namespace := "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" response := `{ @@ -271,32 +275,32 @@ func TestWorkersKV_WriteWorkersKVBulk(t *testing.T) { "messages": [] }` - mux.HandleFunc(fmt.Sprintf("/accounts/foo/storage/kv/namespaces/%s/bulk", namespace), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc(fmt.Sprintf("/accounts/"+testAccountID+"/storage/kv/namespaces/%s/bulk", namespace), func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, http.MethodPut, r.Method, "Expected method 'PUT', got %s", r.Method) w.Header().Set("content-type", "application/json") fmt.Fprintf(w, response) //nolint }) want := successResponse - res, err := client.WriteWorkersKVBulk(context.Background(), namespace, kvs) + res, err := client.WriteWorkersKVEntries(context.Background(), AccountIdentifier(testAccountID), WriteWorkersKVEntriesParams{NamespaceID: namespace, KVs: kvs}) require.NoError(t, err) assert.Equal(t, want, res) } func TestWorkersKV_ReadWorkersKV(t *testing.T) { - setup(UsingAccount("foo")) + setup() defer teardown() key := "test_key" namespace := "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - mux.HandleFunc(fmt.Sprintf("/accounts/foo/storage/kv/namespaces/%s/values/%s", namespace, key), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc(fmt.Sprintf("/accounts/"+testAccountID+"/storage/kv/namespaces/%s/values/%s", namespace, key), func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method) w.Header().Set("content-type", "text/plain") fmt.Fprintf(w, "test_value") }) - res, err := client.ReadWorkersKV(context.Background(), namespace, key) + res, err := client.GetWorkersKV(context.Background(), AccountIdentifier(testAccountID), GetWorkersKVParams{NamespaceID: namespace, Key: key}) want := []byte("test_value") if assert.NoError(t, err) { @@ -304,8 +308,8 @@ func TestWorkersKV_ReadWorkersKV(t *testing.T) { } } -func TestWorkersKV_DeleteWorkersKV(t *testing.T) { - setup(UsingAccount("foo")) +func TestWorkersKV_DeleteWorkersKVEntry(t *testing.T) { + setup() defer teardown() key := "test_key" @@ -317,13 +321,13 @@ func TestWorkersKV_DeleteWorkersKV(t *testing.T) { "messages": [] }` - mux.HandleFunc(fmt.Sprintf("/accounts/foo/storage/kv/namespaces/%s/values/%s", namespace, key), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc(fmt.Sprintf("/accounts/"+testAccountID+"/storage/kv/namespaces/%s/values/%s", namespace, key), func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, http.MethodDelete, r.Method, "Expected method 'DELETE', got %s", r.Method) w.Header().Set("content-type", "application/javascript") fmt.Fprintf(w, response) //nolint }) - res, err := client.DeleteWorkersKV(context.Background(), namespace, key) + res, err := client.DeleteWorkersKVEntry(context.Background(), AccountIdentifier(testAccountID), DeleteWorkersKVEntryParams{NamespaceID: namespace, Key: key}) want := successResponse if assert.NoError(t, err) { @@ -332,7 +336,7 @@ func TestWorkersKV_DeleteWorkersKV(t *testing.T) { } func TestWorkersKV_DeleteWorkersKVBulk(t *testing.T) { - setup(UsingAccount("foo")) + setup() defer teardown() keys := []string{"key1", "key2", "key3"} @@ -345,20 +349,20 @@ func TestWorkersKV_DeleteWorkersKVBulk(t *testing.T) { "messages": [] }` - mux.HandleFunc(fmt.Sprintf("/accounts/foo/storage/kv/namespaces/%s/bulk", namespace), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc(fmt.Sprintf("/accounts/"+testAccountID+"/storage/kv/namespaces/%s/bulk", namespace), func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, http.MethodDelete, r.Method, "Expected method 'DELETE', got %s", r.Method) w.Header().Set("content-type", "application/json") fmt.Fprintf(w, response) //nolint }) want := successResponse - res, err := client.DeleteWorkersKVBulk(context.Background(), namespace, keys) + res, err := client.DeleteWorkersKVEntries(context.Background(), AccountIdentifier(testAccountID), DeleteWorkersKVEntriesParams{NamespaceID: namespace, Keys: keys}) require.NoError(t, err) assert.Equal(t, want, res) } -func TestWorkersKV_ListStorageKeys(t *testing.T) { - setup(UsingAccount("foo")) +func TestWorkersKV_ListKeys(t *testing.T) { + setup() defer teardown() namespace := "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" @@ -379,13 +383,13 @@ func TestWorkersKV_ListStorageKeys(t *testing.T) { } }` - mux.HandleFunc(fmt.Sprintf("/accounts/foo/storage/kv/namespaces/%s/keys", namespace), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc(fmt.Sprintf("/accounts/"+testAccountID+"/storage/kv/namespaces/%s/keys", namespace), func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method) w.Header().Set("content-type", "application/javascript") fmt.Fprintf(w, response) //nolint }) - res, err := client.ListWorkersKVs(context.Background(), namespace) + res, err := client.ListWorkersKVKeys(context.Background(), AccountIdentifier(testAccountID), ListWorkersKVsParams{NamespaceID: namespace}) want := ListStorageKeysResponse{ successResponse, @@ -417,8 +421,8 @@ func TestWorkersKV_ListStorageKeys(t *testing.T) { } } -func TestWorkersKV_ListStorageKeysWithOptions(t *testing.T) { - setup(UsingAccount("foo")) +func TestWorkersKV_ListKeysWithParameters(t *testing.T) { + setup() defer teardown() cursor := "AArAbNSOuYcr4HmzGH02-cfDN8Ck9ejOwkn_Ai5rsn7S9NEqVJBenU9-gYRlrsziyjKLx48hNDLvtYzBAmkPsLGdye8ECr5PqFYcIOfUITdhkyTc1x6bV8nmyjz5DO-XaZH4kYY1KfqT8NRBIe5sic6yYt3FUDttGjafy0ivi-Up-TkVdRB0OxCf3O3OB-svG6DXheV5XTdDNrNx1o_CVqy2l2j0F4iKV1qFe_KhdkjC7Y6QjhUZ1MOb3J_uznNYVCoxZ-bVAAsJmXA" @@ -449,16 +453,17 @@ func TestWorkersKV_ListStorageKeysWithOptions(t *testing.T) { } }` - mux.HandleFunc(fmt.Sprintf("/accounts/foo/storage/kv/namespaces/%s/keys", namespace), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc(fmt.Sprintf("/accounts/"+testAccountID+"/storage/kv/namespaces/%s/keys", namespace), func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method) w.Header().Set("content-type", "application/javascript") fmt.Fprintf(w, response) //nolint }) limit, prefix := 25, "test-prefix" - res, err := client.ListWorkersKVsWithOptions(context.Background(), namespace, ListWorkersKVsOptions{ - Limit: &limit, - Prefix: &prefix, + res, err := client.ListWorkersKVKeys(context.Background(), AccountIdentifier(testAccountID), ListWorkersKVsParams{ + NamespaceID: namespace, + Limit: limit, + Prefix: prefix, }) want := ListStorageKeysResponse{ From 649ec950c0ebe8a2396d2e14ca30efb4efdaace4 Mon Sep 17 00:00:00 2001 From: Jacob Bednarz Date: Tue, 15 Nov 2022 13:16:28 +1100 Subject: [PATCH 2/3] remove extra errors --- workers_kv.go | 1 - 1 file changed, 1 deletion(-) diff --git a/workers_kv.go b/workers_kv.go index 8d46e854c..f7a01bc06 100644 --- a/workers_kv.go +++ b/workers_kv.go @@ -3,7 +3,6 @@ package cloudflare import ( "context" "encoding/json" - "errors" "fmt" "net/http" "net/url" From e3a2edf2c338133b2e216aff6b7c61f954fed557 Mon Sep 17 00:00:00 2001 From: Jacob Bednarz Date: Tue, 15 Nov 2022 13:24:17 +1100 Subject: [PATCH 3/3] add CHANGELOG --- .changelog/1115.txt | 47 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 .changelog/1115.txt diff --git a/.changelog/1115.txt b/.changelog/1115.txt new file mode 100644 index 000000000..b77fa0e55 --- /dev/null +++ b/.changelog/1115.txt @@ -0,0 +1,47 @@ +```release-note:breaking-change +workers_kv: `CreateWorkersKVNamespace` has been updated to match the experimental client method signatures (https://github.com/cloudflare/cloudflare-go/blob/master/docs/experimental.md). +``` + +```release-note:breaking-change +workers_kv: `ListWorkersKVNamespaces` has been updated to match the experimental client method signatures (https://github.com/cloudflare/cloudflare-go/blob/master/docs/experimental.md). +``` + +```release-note:enhancement +workers_kv: `ListWorkersKVNamespaces` automatically paginates all results unless `PerPage` is defined. +``` + +```release-note:breaking-change +workers_kv: `DeleteWorkersKVNamespace` has been updated to match the experimental client method signatures (https://github.com/cloudflare/cloudflare-go/blob/master/docs/experimental.md). +``` + +```release-note:breaking-change +workers_kv: `UpdateWorkersKVNamespace` has been updated to match the experimental client method signatures (https://github.com/cloudflare/cloudflare-go/blob/master/docs/experimental.md). +``` + +```release-note:breaking-change +workers_kv: `WriteWorkersKV` has been renamed to `WriteWorkersKVEntry`. +``` + +```release-note:breaking-change +workers_kv: `WriteWorkersKVBulk` has been renamed to `WriteWorkersKVEntries`. +``` + +```release-note:breaking-change +workers_kv: `ReadWorkersKV` has been renamed to `GetWorkersKV`. +``` + +```release-note:breaking-change +workers_kv: `DeleteWorkersKV` has been renamed to `DeleteWorkersKVEntry`. +``` + +```release-note:breaking-change +workers_kv: `DeleteWorkersKVBulk` has been renamed to `DeleteWorkersKVEntries`. +``` + +```release-note:breaking-change +workers_kv: `ListWorkersKVs` has been renamed to `ListWorkersKVKeys`. +``` + +```release-note:breaking-change +workers_kv: `ListWorkersKVsWithOptions` has been removed. Use `ListWorkersKVKeys` instead and pass in the options. +```