oak
oak copied to clipboard
Access the original request (it's not `originalRequest`..)
Hi!
I want to serve an API with Oak that requires a Request and returns a Response. I need to wrap this in an Oak request.
I found that the types for Oak request/response's are also called Request
and Response
. This is confusing and might better be named OakRequest
and OakResponse
, but this is sematics.
I found the originalRequest
field on the Request
class of oak but this request is still not the basic Request
passed by the Deno HTTP server. How do I access that request?
gr,
Tom
I solved it with this:
import { Context as OakContext } from 'https://deno.land/x/[email protected]/mod.ts';
export async function wrapOakRequest(
ctx: OakContext,
fn: (request: Request) => Promise<Response>,
) {
const req = new Request(ctx.request.url.toString(), {
body: ctx.request.originalRequest.getBody().body,
headers: ctx.request.headers,
method: ctx.request.method,
});
const response = await fn(req);
ctx.response.status = response.status;
ctx.response.headers = response.headers;
ctx.response.body = response.body;
}
Hey thanks a lot @industrial 🙏 Can use oak now to serve Remix
Just modified it slightly so I can just
app.use(wrapOakRequest(remixHandler));
export function wrapOakRequest(
fn: (request: Request) => Promise<Response>,
) {
return async (ctx: OakContext) => {
const req = new Request(ctx.request.url.toString(), {
body: ctx.request.originalRequest.getBody().body,
headers: ctx.request.headers,
method: ctx.request.method,
});
const response = await fn(req);
ctx.response.status = response.status;
ctx.response.headers = response.headers;
ctx.response.body = response.body;
};
}
This essentially sounds like the inverse of Application.prototype.handle()
where you have some sort of function that you want to use as middleware, but is expecting a fetch standard Request
and returns a fetch standard Response
.
I want to do the same, but using two simple functions. I have the following to convert an Oak Request
to a web-standard Request
:
function toWebRequest(oakRequest: OakRequest): Request {
return new Request(oakRequest.url, {
...oakRequest,
body: oakRequest.originalRequest.getBody().body,
});
}
How would I do toOakResponse(response: Response): OakResponse
?
This essentially sounds like the inverse of
Application.prototype.handle()
where you have some sort of function that you want to use as middleware, but is expecting a fetch standardRequest
and returns a fetch standardResponse
.
Another example use case would be migrating from an application that was using "Serve" (supabase functions in my case).
I have a bunch of functions that accept/return stdlib Request/Response. I now want to introduce Oak for routing & middleware, but have to refactor a bunch of types needlessly
Ok, I have added a few features. There is new middleware called serve()
and route()
which make it easier to deal with using Fetch API "handlers" as middleware.
An example of using serve()
with Application.prototype.use()
:
import { Application, serve } from "https://deno.land/x/oak/mod.ts";
const app = new Application();
app.use(serve((req, ctx) => {
console.log(req.url);
return new Response("Hello world!");
}));
app.listen();
And a similar solution works with route()
where the context contains the information about the router, like the params:
import { Application, route, Router } from "https://deno.land/x/oak/mod.ts";
const app = new Application;
const router = new Router();
router.get("/books/:id", route((req, ctx)) => {
console.log(ctx.params.id);
return Response.json({ title: "hello world", id: ctx.params.id });
});
app.use(router.routes());
app.listen();
In addition I added ctx.request.source
which will be set to the original Request
and people can use ctx.response.with()
to supply a web standard Response
instead of having to do other things. This should give a lot of flexibility for people to use and adapt code without a huge amount of rewriting.
[!NOTE] A new version of oak needs to be published for these to be available which should be in a little while after I make sure everything is good to go.