sholladay / pogo

Server framework for Deno
Mozilla Public License 2.0
482 stars 33 forks source link

Automatic body parsing #41

Closed yereby closed 2 years ago

yereby commented 4 years ago

Hello, Is there a way to access the request payload like request.payload in hapi other than the one explained here https://github.com/sholladay/pogo#requestbody ?

sholladay commented 4 years ago

Not yet, I just haven't gotten around to adding automatic body parsing. It should be pretty easy to do though, if you'd like to make a PR.

yereby commented 4 years ago

Yes ! I just discover pogo, can you give we some insight ?

sholladay commented 4 years ago

Sure, well the first thing to do would be to write a test like the request tests that we have already. When we use server.inject() in those tests, we are basically making a fake ServerRequest object and giving it to the Pogo server as if it were a real HTTP request. You would do the same when making a test for request.payload.

The tests should check at least two cases:

In the tests, you would pass an object to server.inject() that has a body property that conforms to the Deno.Reader interface (because that's how the body of the ServerRequest class works). An example of something like that is a StringReader. Should look roughly like this...

const response = await server.inject({
    body : new StringReader(JSON.stringify({ foo : 'bar' }))
    // ...
});

After the tests are written, then the next step would be to add the automatic body parsing to the framework. I haven't thought too much about the architecture, but it would happen somewhere around this part of the code where we create our request object: https://github.com/sholladay/pogo/blob/5a72c718b8aca97733540cc8ba13085eb69db020/lib/server.ts#L50-L54

It would be good to look into how hapi does this internally.

sholladay commented 2 years ago

What should the TypeScript type be for request.payload? Could be something along the lines of FormData | URLSearchParams | string | number | boolean | { [key: string]: any } but I'm not sure if that's really helpful. Alternatively, it could be unknown, which would force you to assert its type when using it. Or we could use a generic type parameter, but I'm not sure exactly how it would work, I think you'd have to explicitly provide the expected type on the route handler or something.

sholladay commented 2 years ago

Until there is a concrete proposal for how to handle the TypeScript types, I am going to close this issue. Happy to reopen when it is more actionable.

FWIW, now that PR #68 has been merged, it is quite easy to parse the request body into various formats. For example, you can call await request.raw.json() to get the body as JSON. I'll probably add a shortcut in the future so you can skip the .raw and just do await request.json(), or similar for the other parsing methods.