Worker to Worker fetch
# workers-help
m
Hi there, I would like to ask for some help with my cloudflare worker. When i make a request to another cloudflare worker of mine that holds a variable with data in it from another cloudflare worker. The data returned is empty, however i make the data request from my browser or api tester, it returns the correct data. It is specifcally when I request the data from a cloudflare worker.
Copy code
js
import { Router } from 'itty-router'; const router = Router()

order_data = [];

//admin only
router.get("/order", async (req) => {
   return new Response(JSON.stringify(order_data));
});
m
Apparently you can't do workers-to-workers fetch. You have to use service binding: https://developers.cloudflare.com/workers/configuration/bindings/about-service-bindings/
e
That's correct, the Workers either have to be on separate Cloudflare zones (e.g. example.com, example.net and example.workers.dev are all separate zones) or use Service Bindings
Service Bindings is the recommended solution
m
my workers are on seperate cloudflare zones, however it still cannot return the information correctly
e
What do you get back exactly?
m
a json containing order data
@Erisa | Support Engineer
its here in the code I provided
thats the cloudflare worker that hold the data
Copy code
js
export const order_management = {
    async postData(data) {
        return await(await fetch(
            `https://server.syntaxrecoveriesorders.workers.dev/order/${encodeURIComponent(JSON.stringify(data))}`, { method: "POST" }
        )).text();
    },
    async getData(id) {
        return await(await fetch(
            `https://server.syntaxrecoveriesorders.workers.dev/order/${encodeURIComponent(id)}`
        )).text();
    }
}
this is how i get data from it
@Erisa | Support Engineer
k
What URL is the Worker that has this code?
m
the one i sent now? @kian
@kian
anyone?
m
server.syntaxrecoveriesorders.workers.dev
and
server.syntaxrecoveriesorders.workers.dev
Are both on the same zone, so you can't make requests between them. You have to use service binding
m
@McSneaky
bro
ready
their not the same
@Erisa | Support Engineer
can u both read
their not
.syntaxrecoveriesorders
.syntaxrecoveries
m
Aah, I was looking at your code example..
I assume everything under workers.dev need to use service binding tho But that would be security issue, if they are all the same and can bind like that
Try to put one under your custom domain and keep other under workers.dev
m
Can u help me with how service bindings work?
@McSneaky
how do i communicate to server
m
Worker 1 called `"MY_SERVICE_TO_CALL"`:
Copy code
ts
import { Router } from 'itty-router'; const router = Router()

order_data = [];

//admin only
router.get("/order", async (req) => {
   return new Response(JSON.stringify(order_data));
Worker 2:
Copy code
ts
router.get("/other-endpoint", async (req, env) => {
   return env.MY_BINDING.fetch(`http://MY_SERVICE_TO_CALL/order/${encodeURIComponent(id)}`, request)
}
And inside your
wrangler.toml
of Worker 2 define
BINDING
and
SERVICE
in
services
Copy code
toml
services = [
  { binding = "MY_BINDING", service = "MY_SERVICE_TO_CALL" },
]
That service has to be other worker name
m
@McSneaky
what is MY_SERVICE_TO_CALL
services = [ { binding = "server", service = "server.syntaxrecoveries.workers.dev" }, ]?
m
It's your worker name
m
server?
can i get an example?
m
Worker
m
no bro
example of the name
wym by name
please
m
What's the name of your other worker to call You can check it's name from other worker
wrangler.toml
or from CloudFlare dashboard
m
server
its called
server
m
Aah, thought you have literal server, like VPS ๐Ÿ˜…
m
Copy code
services = [
  { binding = "server", service = "server" },
]
m
Then yeah, "server" in your case ๐Ÿ‘
m
lol
๐Ÿซถ
m
Then
env.server.fetch('https://server/orders/10')
Something like this should work for you
m
how do you get env if its not a request?
like if i want to postData just as a function
not in a route
i need env still
m
Most likely need to pass it to that function
m
i dont think i can
its hard to explain
m
Copy code
ts
export const order_management = {
    async postData(data, env) {
      env.server.fetch(...)
    },
    async getData(id, env) {
    }
}
// And then use in your worker as 
router.get("/other-endpoint", async (req, env) => {
    await order_management.postData(data, env)
}
m
no
im not using router.get
like where do i get env from
without getting it from router
oh
wait
lmao
nvm
sorry
im dumb
also
error code: 1042
m
Replace all that
https://server.syntaxrecoveriesorders.workers.dev/order
With just
https://server/order
m
no something is wrong
can i show u in a screenshare?
i did
in my code
m
Hmm.. Then maybe it works differently in
workers.dev
๐Ÿค” I was using on actual domain
m
im getting error 1101
m
No idea what that is
m
internal service error
m
No idea what that is either ๐Ÿ˜„
m
on my manager worker
Copy code
js
router.get("/order/:id", async (req, env) => {
  return new Response(await order_management.getData(decodeURIComponent(req.params.id),env));
})
Copy code
js
export const order_management = {
    async postData(data) {
        return await(await fetch(
            `https://server.syntaxrecoveriesorders.workers.dev/order/${encodeURIComponent(JSON.stringify(data))}`, { method: "POST" }
        )).text();
    },
    async getData(id,env) {
        return await(await env.server.fetch(
            `http://server/order/${encodeURIComponent(id)}`
        )).text();
    }
}
๐Ÿฅบ
looks good to me
idk why its throwing an error
im using getData btw
just for now
m
Yeah, looks good
You can try to wrap some try-catches in there or .catch()'es where to log out errors
See maybe there's something more useful than just that error code
m
Copy code
js
router.get("/order/:id", async (req, env) => {
  try {
     return new Response(await order_management.getData(decodeURIComponent(req.params.id),env));
  } catch(error) {
     return new Response(error)
  }
})
Copy code
TypeError: Cannot read properties of undefined (reading 'order_server')
Copy code
js
export const order_management = {
    async postData(data) {
        return await(await fetch(
            `https://server.syntaxrecoveriesorders.workers.dev/order/${encodeURIComponent(JSON.stringify(data))}`, { method: "POST" }
        )).text();
    },
    async getData(id,env) {
        return await(await env.order_server.fetch(
            `http://order_server/order/${encodeURIComponent(id)}`
        )).text();
    }
}
m
env
is undefined?!
m
yerr lmao
m
Eeee ๐Ÿ˜…
How so ๐Ÿค”
m
idk
m
You are using that
itty-router
?
m
positive
m
No idea..
That's what I have Worker 1 called "edge-encoder":
Copy code
yml
// worker.toml
name = "edge-encoder"
main = "index.js"
compatibility_date = "2022-05-03"

services = [
  { binding = "collector", service = "edge-collector-dev" },
]
Copy code
ts
// .js
import { Router } from 'itty-router';

// Create a new router
const router = Router();

router.get('/edge/encoder/v1', async ({ query }, env) => {
  let base64 = btoa(JSON.stringify(query));
  return env.collector.fetch('https://edge-collector-dev/edge/collector/v1?encoded_object=' + base64)
})
Worker 2 called "edge-collector-dev":
Copy code
ts
// .js
import { Router } from 'itty-router';

// Create a new router
const router = Router();

router.get('/edge/collector/v1', async ({ query }, env) => {
  console.log(query)
  return new Response('OK')
})
Works perfectly ๐Ÿค”
No idea why env is undefined for you
And what are those odd error codes you got
m
^
m
Log out
env
in router to see if it exists there
m
what?
m
Copy code
ts
router.get("/order/:id", async (req, env) => {
  console.log(env) // What does it say?
  try {
     return new Response(await order_management.getData(decodeURIComponent(req.params.id),env));
  } catch(error) {
     return new Response(error)
  }
})
Aah, are you running on local with
dev
?
Service binding might work only in prod
Have to
wrangler deploy
and then test in prod ๐Ÿ˜‹
m
idk what ur saying
im new to cloudflare workers
m
How are you running your test env?
wrangler dev
?
npm run dev?
m
Copy code
PS E:\Desktop\Syntax Recoveries Manager> wrangler dev
 โ›…๏ธ wrangler 3.7.0 (update available 3.22.3)
------------------------------------------------------
wrangler dev now uses local mode by default, powered by ๐Ÿ”ฅ Miniflare and ๐Ÿ‘ท workerd.
To run an edge preview session for your Worker, use wrangler dev --remote
โ–ฒ [WARNING] Processing wrangler.toml configuration:

    - "services" fields are experimental and may change or break at any time.


โ–ฒ [WARNING] This worker is bound to live services: order_server (server)


โ–ฒ [WARNING] Enabling Node.js compatibility mode for built-ins and globals. This is experimental and has serious tradeoffs. Please see https://github.com/ionic-team/rollup-plugin-node-polyfills/ for more details.


Your worker has access to the following bindings:
- Services:
  - order_server: server
โ–ฒ [WARNING] โŽ” Support for service bindings in local mode is experimental and may change.


โŽ” Starting local server...
kj/async-io-win32.c++:982: warning: Bind address resolved to multiple addresses.  Only the first address will be used.  If this is incorrect, specify the address numerically.  This may be fixed in the future.; addrs[0].toString() = 127.0.0.1:63121
[mf:inf] Ready on http://0.0.0.0:8787 
[mf:inf] - http://10.0.0.6:8787
[mf:inf] - http://127.0.0.1:8787
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎโ”‚ [b] open a browser, [d] open Devtools, [l] turn off local mode, [c] clear console, [x] to exit                                                                                                            โ”‚โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
m
Yeah, I'm not sure if that that works You might need to deploy both workers with
wrangler deploy
and then test on production (real URL, not local)
m
i have been doing that
m
And then you get same error?
m
yes
m
Welp ๐Ÿ˜
Then I'm all outta ideas
m
TypeError: Cannot read properties of undefined (reading 'order_server')
TypeError: Cannot read properties of undefined (reading 'order_server')
TypeError: Cannot read properties of undefined (reading 'order_server')
TypeError: Cannot read properties of undefined (reading 'order_server')
so annoyinh
@McSneaky
Copy code
name = "manager"
main = "src/main.js"
compatibility_date = "2022-07-12"
node_compat = true

services = [
  { binding = "order_server", service = "server" },
]
Copy code
{
  "name": "Syntax Recoveries Manager",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "dependencies": {
        "crypto": "^1.0.1",
        "crypto-js": "^4.2.0",
        "cryptojs": "^2.5.3",
        "decode-uri-component": "^0.4.1",
        "itty-router": "^4.0.25",
        "urldecode": "^1.0.1"
      }
    },
    "node_modules/crypto": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz",
      "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==",
      "deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in."
    },
    "node_modules/crypto-js": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
      "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
    },
    "node_modules/cryptojs": {
      "version": "2.5.3",
      "resolved": "https://registry.npmjs.org/cryptojs/-/cryptojs-2.5.3.tgz",
      "integrity": "sha512-+rdPl1UCxE8s3R94NNn+zMKOiI4MJ7dyh3X0c5uBL3btDr4zQ6acd7f9mY7Wb5MrccZEi2Rrha3OEtLcc5XXog==",
      "engines": {
        "node": "*"
      }
    },
    "node_modules/decode-uri-component": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.4.1.tgz",
      "integrity": "sha512-+8VxcR21HhTy8nOt6jf20w0c9CADrw1O8d+VZ/YzzCt4bJ3uBjw+D1q2osAB8RnpwwaeYBxy0HyKQxD5JBMuuQ==",
      "engines": {
        "node": ">=14.16"
      }
    },
    "node_modules/itty-router": {
      "version": "4.0.25",
      "resolved": "https://registry.npmjs.org/itty-router/-/itty-router-4.0.25.tgz",
      "integrity": "sha512-WbH1x46QFKNAjp85GYZzDteriZl9nJ0flwGJDVfzC4HT0B/nb01/KOD7mEr+5cYmuqy9T7L/A3ifNzCpzQ1fcw=="
    },
    "node_modules/urldecode": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/urldecode/-/urldecode-1.0.1.tgz",
      "integrity": "sha512-h0S6hi8/2kC6ZTbnzRyRC86BKDp9rSV2BndvtedcPSFcWdqdXc2Bru1NuF4Oq89D4HKitpX3+EJDry0uOjfTyw=="
    }
  }
}
m
I have no idea..
env
is undefined for you for some reason, but I have no idea why
For me it worked outta box
ยฏ\_(ใƒ„)_/ยฏ
m
@McSneaky
m
Aah, but you don't have Node env. It's ctx env kinda thingy
m
@McSneaky
do both workers have to be binded?
m
Nope, only one
m
can i send u my full code?
can someone help
pls
anyone?
u
https://developers.cloudflare.com/workers/configuration/bindings/about-service-bindings/ This guide should help you understand service bindings and how to use them.
m
@Unsmart | Tech debt
The issue is that it doesnt work.
It literally doesnt work.
ive done all that
u
Did you follow the tutorial exactly in order to create one and understand how it works instead of trying to do it in your own project first?
It does indeed work many people use it. If you cant figure it out I highly suggest trying to pay a developer to either do it for you or support you through to understanding how it works ๐Ÿ™‚
m
Hey bro @Unsmart | Tech debt, yeah no i did read it, all is set up perfectly fine. All my code is in the above messages.
Like it really has no reason not to work.
Because the code of the binded worker is fine, i can sned a request to it on my browser perfectly fine. It just doesnt work with the worker that is binding with it.
The issue is my
env
is undefined...
We cant figure out why tho.