How do you use the API to bind an instance of a KV Namespace to access its data in a Worker?

I want to use the API to programmatically create a new KV Namespace binding to a worker.

I looked through the API v4 documentation but so far I haven’t found it.

The issue you’ll face if you try to do it with a single Worker is that your Worker needs to reload to have a binding to the new KV namespace and you’ll loose the request payload upon the Worker reloading which would require the client-side to resend.

There is a hacky way to do this but it requires Worker to Worker back through the Cloudflare front-door, (i.e. not worker services) because one Worker needs to accept the user inbound request & create the new namespace on the 2nd Worker, then handover the users request payload to that 2nd Worker which is now bound to the new KV namespace to save the data. That in itself is hacky but you also need to do it on a single account for the creating of a binding so it involves another hack to make sure both workers are untrusted so that when one Worker communicates to the other Worker that the request goes through the Cloudflare front-door. I believe these are bugs and may not continue to work in the future, I raised these as bug reports 2 weeks ago but yet to hear anything back.

Would you elaborate more details as to why you need this and maybe we can think of a better solution.

It maybe better to use some methods of virtually creating a namespace inside an already bound namespace. Or you could try using Durable Objects. As to what is the best solution for you is unknown until more details can be known.

Thanks for your thoughtful reply. But actually most of the concerns you have don’t really apply to me. I just want to make a worker that can delete all the keys in a namespace by just deleting the namespace, then recreate the namespace and all its bindings. It doesn’t need to have a binding to the namespace itself at least not after the namespace is deleted and recreated.

What I need and still haven’t found is the exact API call that does the binding. I found one that deletes the namespace (which I presume also deletes all the bindings) and I found one that creates a namespace which I presume doesn’t restore the bindings and I will need to do that with further calls to the API.

Ok, that make a little more sense now. I’m still not understanding why you’d want to accomplish the truncation of your namespace by this method rather than building in isolates and garbage collection into your application logic but nevertheless I’ll show you how you can do this with the Cloudflare API.

The Cloudflare API for updating a Worker is whats relevant to your question.
Cloudflare API v4 Documentation
PUT accounts/:account_identifier/workers/scripts/:script_name

What the documentation does not say is anything about the metadata when you PUT a Worker script.

The metadata is where your binding are, so you first want to GET your metadata bindings and then after you’ve deleted old namespace, and created the new namespace, finally you can then amend your metadata and send off your PUT request to bound that new namespace to your Worker script.
,

How To Specify Metadata on a Worker PUT ?
Instead of using Content-Type: application/javascript you want to use Content-Type: multipart/form-data; boundary=----MyBoundaryXXXXX

The first of your payload needs to be the Workers script and the second of your payload is the metadata.

To keep consistent with the Cloudflare API documentation I’ll show you an example here using cURL, but you’d obviously need to write the equivalent in your Worker.

curl -vX PUT "https://api.cloudflare.com/client/v4/accounts/:account_identifier/workers/scripts/:script_name" \
    -H "X-Auth-Email: [email protected]" \
    -H "X-Auth-Key: c2547eb745079dac9320b638f5e225cf483cc5cfdda41" \
    -H 'Content-Type: multipart/form-data; boundary=----MyBoundaryXXXXXXXXXXXXXXXX' \
    --data-raw $'------MyBoundaryXXXXXXXXXXXXXXXX\r\nContent-Disposition: form-data; name="script"; filename="blob"\r\nContent-Type: application/javascript\r\n\r\naddEventListener("fetch",a=>{a.respondWith(handleRequest(a.request))});async function handleRequest(){return new Response("Hello world")}\r\n------MyBoundaryXXXXXXXXXXXXXXXX\r\nContent-Disposition: form-data; name="metadata"; filename="blob"\r\nContent-Type: application/json\r\n\r\n{"bindings":[{"name":"SECRET","text":"xxxxxxxxxxxxxxxxxxx","type":"plain_text"},{"name":"KVDump","type":"kv_namespace","namespace_id":"2d8f2a41cc49416695300add1d7f32dd"},{"name":"MY_NEW_KV_BINDING","type":"kv_namespace","namespace_id":"1850f3a5be2d478bb4dd41be2554262c"}],"body_part":"script"}\r\n------MyBoundaryXXXXXXXXXXXXXXXX--\r\n'

Here is a video demo of this working:

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.