Open radu-matei opened 1 year ago
This is because of how itty-router
works. The first parameter passed to itty-router
is of type RequestLike
which does not contain a body field (only method
& url
).
https://github.com/kwhitley/itty-router/blob/ab002f2e43964874ad60e91e8610c76c4c347268/src/itty-router.ts#L5
The first parameter passed to the route handling function is of type IRequest
which does not contain the body field either.
https://github.com/kwhitley/itty-router/blob/v3.x/src/itty-router.ts#L5
I will look into this to see if there are any easy ways of bypassing this issue.
Ok, that is good to know. Ideally, we want to document this behavior and make it clear how it should be used.
I just hit a similar issue while migrating over to the new JS router. Thanks @radu-matei for the workaround.
It appears there's some middleware in itty-router-extras that will allow users to safely parse and embed request bodies. Is that something we can integrate with here?
https://www.npmjs.com/package/itty-router-extras#withcontent
The last time I looked at it, It did not run properly due to missing functions in the runtime I think. I will take a look again and see if it is a quick fix.
Yeah, I just tested this locally by attempting to bypass spin's builtin router and use itty-router directly. You get a stack trace as soon as you call req.json()
.
code snippet:
import { HandleRequest, HttpRequest, HttpResponse } from "@fermyon/spin-sdk";
import { Router } from "itty-router";
const router = Router();
router.post("/", async req => {
console.log("Parsing body");
let content = req.json();
return {
status: 200,
body: JSON.stringify(content)
}
}
export const handleRequest: HandleRequest = async function (request: HttpRequest): Promise<HttpResponse> {
return await router.handle({
url: request.uri,
method: request.method
});
};
Log output from a POST request:
Parsing body
Handler returned an error: Uncaught TypeError: not a function
For others, here's a full example showing how to read the request body using the Spin router:
import { HandleRequest, HttpRequest, HttpResponse } from "@fermyon/spin-sdk";
const router = utils.Router();
let decoder = new TextDecoder();
router.post("/", async (_, body) => {
let message = decoder.decode(body);
return {
status: 200,
body: message,
};
});
export const handleRequest: HandleRequest = async function (request: HttpRequest): Promise<HttpResponse> {
return await router.handleRequest(request, request.body);
};
@bacongobbler, The error you ran into might be due to the function not existing on the body. There was a bug with the typing fixed by the following
https://github.com/fermyon/spin-js-sdk/commit/7ff233a81145dc03815b5b3333b89e73aa1fd3ed
But excluding that, I also notice that you are not using the itty-router-extras
middleware. itty-router
by default does not take in a body. The first example you tried also seems broken because the entire request is not even being passed.
I seem to be unable to access the request body when using the router. If I parse the body in
handleRequest
(the commented line), I can access it and everything works well. When I pass the request to the router, I can't access the body anymore.For example:
This results in:
I am able to pass it as an extra argument:
However, I think it should be part of the request object passed by default.