Closed dremekie closed 1 year ago
A node http request+response pair have almost no overlap with the JS-standard http request+response pair. There is no host
or hostname
field on the Node request, so it is not possible to construct a fully qualified url with new URL
from a node request object. I think something like this will get you closer to using an itty handler:
const MY_HOST_NAME = ...; // I don't know your host name, but I bet you do!
const response = ittyRouter.handle(new Request(new URL(req.url, MY_HOST_NAME), request)); // this is async, should
// now be sure to use node `res`! Unlike service workers or CF workers, you have to manually write to the response instead of just resolving
Is it possible to convert this into a discussion? I started a similar thread here: https://github.com/kwhitley/itty-router/discussions/107
Instead of using itty with a node http server, I am using itty inside a service worker. Service workers have unique requirements about responding to events synchronously which itty cannot do.
I wonder if the itty README examples can show some platform-specific nuances for each use-case?
I was considering using itty-router for a hybrid Cloudflare worker/node server app but looks like it's not supported. I need my code to run either on Cloudflare or locally depending on a use case.
There's h3 router.
Will check out h3, thank you!
Miniflare is a better place for this issue.
If you want to use itty in a normal node environment (Node 18+) you can do something like this:
import http from 'http'
import { Router } from 'itty-router'
const HOST = 'localhost'
const PORT = 8000
const baseRouter = Router()
// healthcheck endpoint
baseRouter.get('/ok', () => new Response('🎉🎉🎉'))
// some json
baseRouter.get('/json', () => new Response(JSON.stringify({ status: 'ok' }), { headers: { 'content-type': 'application/json' } }))
// any other route is an error (should instead throw custom errors, with error codes and so on)
baseRouter.all('*', () => { throw new Error('💥💀💥') })
// start a regular node server
http.createServer(async (req, res) => {
const resp = await baseRouter.handle(
// ******************** 🙋♂️ ADAPTER STUFF : START ***********************
// create a Request (requires node 18+) object from node's IncomingMessage,
// which can be accepted by itty - router
new Request(
new URL(req.url, 'http://' + req.headers.host),
{
// should also map headers, body....
method: req.method
}
)
// *********************** ADAPTER STUFF : END ***********************
).catch(err => new Response(err.message, { status: 500 }))
// ******************** 🙋♂️ ADAPTER STUFF : START ***********************
// map the Response to node's expected ServerResponse
res.writeHead(resp.status, resp.statusText, resp.headers)
res.end(await resp.text() + '\n')
// *********************** ADAPTER STUFF : END ***********************
}).listen(PORT, HOST, err => {
if (err) throw err
console.log('Server listening on ' + HOST + ':' + PORT)
})
Haven't run any mem or perf benchmarks. I love itty in CF, but I'm not sure how this version with adapter in node compares to using h3
, polka
or other routers.
Or ... you could just add this line before calling handle
if (req.url && req.url[0] === '/') req.url = `http://${req.headers.host}${req.url}`
Could you share a snippet of how I would use Node to create a local http server that uses itty-router?
Something like:
With the above,
GET http://127.0.0.1:4444/about
throwsTypeError [ERR_INVALID_URL]: Invalid URL