Creating Workers API?
# workers-help
j
Is there an API to create a worker? I wasn’t able to find it in the documentation. Specifically, I’m setting up a form to create redirects. * User visits my site and submits a form. * The values of the form’s input field are used in the creation of a new worker. * I would then attach this new worker to a route on my domain. I see the Worker Route API, but I don’t see a “create new worker” API. Am I missing something?
h
That’s two separate APIs. One to create a Worker, and one to bind it to a route. Though note you can also store the redirect in KV, which would mean you could use just a single Worker for all of your redirects
j
Thanks so much! Do you know what “create a worker” API is called? I really can’t find it in the documentation 😩😩
j
Thank you! Although I think your suggested architecture of using KV is 🔑
Just wasn’t sure if I were understanding the documentation correctly
s
Yeah I'd use KV or D1 or something instead of a new worker upload, you'd hit the limits pretty fast for the case of redirects
j
i'm getting some CORS related errors (i think).
Preflight response is not successful. Status code: 400
Fetch API cannot load https://api.cloudflare.com/client/v4/... due to access control checks.
the architecture right now is click button on form, and PUT the form's values into the KV. just running the page locally rn.
any sense of what i should google around to avoid this?
i'm guessing i should route it to a server-script? i think that way my API keys would remain hidden
s
Yeah, you shouldn't use the API client side
r
i has this samw question, how do i pass thru if i want it to be a MODULE type of worker or a paid worker ? usually its in the toml file but can u pass it as a param i that curl rquest u referenced?
h
Those aren’t mutually exclusive. And Workers are marked as paid if you pay for the Workers plan
You can’t manually mark/unmark them
I'm having trouble getting this guide to work here... I'm using node and trying to put together a fetch request that mimics the curl, do i need to ude formData and append the file? Can I pass the code in as a string into the parameters?
Copy code
curl --request PUT \
  --url https://api.cloudflare.com/client/v4/accounts/account_identifier/workers/scripts/script_name \
  --header 'Content-Type: multipart/form-data' \
  --header 'X-Auth-Email: ' \
  --form '"message"=' \
  --form '"second-file.js"=' \
  --form '"worker.js"=' \
  --form metadata=
Copy code
"worker.js"
string
Worker script.

Example:
@worker.js;type=application/javascript+module
metadata
string
Metadata for script such as bindings in JSON format. Main module needs to be specified with main_module.

Example:
{"main_module": "worker.js", "some_binding": "stuff"}
`
How do those work in regards into the curl request? is the file contents passed or just the file name? Sorry for the wall of text just been struggling on this for a few hours and want to get it squared away lol
h
You can use the https://developer.mozilla.org/en-US/docs/Web/API/FormData object to include all of the different necessary modules/metadata, and then use said FormData as your body
r
i know that
but im getting object isn't iterable
tons of errors non stop here , im just not understanding what isn't getting passed through right
u
Copy code
const scriptName = 'weather';
const formData = new FormData();
const filePath = './cfweather.js';
const metadata = { "main_module": "worker.js", "some_binding": "stuff" }
const message = 'initial commit';    
fs.readFile(filePath, 'utf8', (err, data) => {
        if (err) {
            console.error('Error reading file:', err);
            return;
        }
        formData.append('worker.js', data, {
            contentType: 'application/javascript+module',
            filename: 'worker.js'
        });
    });

    formData.append('message', JSON.stringify(message), {
        contentType: 'application/json'
    });
    formData.append('metadata',
        JSON.stringify(metadata), {
        contentType: 'application/json',
        filename: 'metadata.json'
    });
this is the code that @rd and I are using @HardAtWork
r
I found the updated code on the API docs
Copy code
js

var axios = require("axios").default;

var options = {
  method: 'PUT',
  url: 'https://api.cloudflare.com/client/v4/accounts/account_identifier/workers/scripts/script_name',
  headers: {
    'Content-Type': 'multipart/form-data; boundary=---011000010111000001101001',
    'X-Auth-Email': ''
  },
  data: '-----011000010111000001101001\r\nContent-Disposition: form-data; name=""message""\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=""second-file.js""\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=""worker.js""\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name="metadata"\r\n\r\n\r\n-----011000010111000001101001--\r\n\r\n'
};

axios.request(options).then(function (response) {
  console.log(response.data);
}).catch(function (error) {
  console.error(error);
});
I need to modify this to work with blob or fs Stream to load a js files contents into the form data right? or can i just paste the source code into the formdata as the file ?
h
You can do it like that, but Axios should support using FormData directly, so you don’t have to mess with the form headers yourself. And also, the Node-native fetch API should be available, which means you can remove the dependency on Axios entirely, if you want
r
we've been trying to do this for legit 4 hours, im gonna pass out its 4Am
Probably missing something stupid here i can't get it to work for the life of me
That code i pulled right from cloudflare API docs, so that code isn't good to use ?
I'm just trying to figure out hwat I'm missing here it's making me insane lol !
h
You can, it just makes it more complex than it needs to be
r
yeah this is driving me up a wall lol idk what im misisng
i cam't get formdata and Blob to work on node native fetch so thats why i went axios
I'm just trying to create a worker dynamically from a function by poiting it to a JS file but thats not working right .. Hm
Good monring i'll try this again today @HardAtWork
still can't seem to gte it to work, legit copy and pasting the Axios node request from the cloudflare site
I got this workign !
thanks all
Copy code
js
const axios = require('axios');
const fs = require('fs');

const accountId = 'ACCOUNT_ID';
const email = 'email@here';
const token = 'API TOKEN';
const headers = {
 'Authorization': `Bearer ${token}`,
  'Content-Type': 'application/javascript',
};


function deployWorker(script,name) {
    console.log(`Deploying ${name}...`)
    const workerScript = fs.readFileSync(`${script}`);
    const url = `https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/scripts/${name}`;
    axios({
  method: 'PUT',
  url: url,
  headers: headers,
  data: workerScript,
})
  .then((response) => {
    if (response.data.success) {
      console.log(`Success! Deployed ${name}!`);
      console.log(`Created on ${response.data.result.created_on}`);
      console.log(`Modified on ${response.data.result.modified_on}`);

    }
    else { 
        console.log(`Error: ${response.data.errors[0].message}`);
    }
  })
  .catch((error) => {
    console.error(error);
  });

}

deployWorker('worker_script.js','worker_name');
THis solved it!