3 ms·
> What's weird to me is that it's coupling the request and response format to the logic. It does not though? It lets you do it for your personal convenience. I
by masklinn 4y ago
> What's weird to me is that it's coupling the request and response format to the logic.
It does not though? It lets you do it for your personal convenience. If you define a JSON API, you can just tell the framework that it takes JSON data, and it'll do the deserialisation for you.
> What if a client wants to post this as a form body? Write a separate endpoint? What if some old clients put the arguments in the query string?
Take a raw body and query strings and do the dispatching internally. Hell, you can ask for the request (https://docs.rs/http/latest/http/request/struct.Request.html https://docs.rs/http/latest/http/request/struct.Request.html) itself:
async fn handler(request: Request<Body>) {
// ...
}
There you go, knock yourself out.
I think Warp would actually let you write different handlers for each of those cases, because it routes on the entire thing e.g.
let some_route = path!("foo" / usize / "bar");
some_route.and(json()).map(handler_json)
.or(some_route.and(form()).map(handler_form)
.or(some_route.and(query()).map(handler_query)
or you could tell it to unify these three filters and pass the data from whatever source it got to the same handler:
path!("foo" / usize / "bar").and(
json().or(form()).or(query())
).map(handler)
I'm sure this wouldn't work as-is and would require some tuning up or `unify()` calls, but you get the gist.
IIRC Axum only routes on the URL, so it can't do that, that's both why it doesn't build types as giantic as warp, and why you have to specify the extractors in the function where warp doesn't need that (you'd just tell it that `payload: CreateUser).
- zemo 4y agosure you can get the underlying request, but if that’s the answer to everything that the framework author didn’t think of, that’s just an admission that the abstraction is wrong, which is kinda what I’m getting at. The entire conceptual model that views the Json<T> type as a handler argument type and then parsing the body based off of that is what Rocket does too. I think the entire strategy is conceptually incorrect. Axum may do Rocket better than Rocket, but if it’s using the same conceptual model, it seems like a lateral move. I’m looking for a new abstraction and conceptual model, not a better implementation of the same concepts or the same concepts with a larger pool of maintainers.
- infogulch 4y agoThat's not a wrong abstraction, it's just not the abstraction level that you want to work at for this problem. So... create multiple endpoints that all call the same function to perform the behavior you want? Maybe call it a "controller".
- zemo 4y agoI spent ten years writing Go HTTP servers and the abstraction used in net/http has served me well for a decade straight. I’ve been writing http servers in rust for 3 months. Rocket provides an abstraction with a lot of holes that makes me jump through a lot of hoops to do things that have been trivial and common in http programming for over a decade. I’ve written stuff using only Hyper, it’s very manual. Warp has the problems the article describes. With Go, I used the standard library HTTP implementation for a decade and was happy the whole time. I also wasn’t experienced with Go going into it, it was how I learned Go. Axum and Rocket have the same general thrust, the abstraction being that you define types to see a thing that’s not an HTTP request. That’s the abstraction that I think is incorrect. That design strategy is actively making things complicated for me on a daily basis at my dayjob writing services in Rust. I want something higher level than Hyper but with a different theory of abstraction than Rocket or Hyper want to provide. The theory of Rocket’s abstraction is that the framework handles the http request and response for you, what you see is something else. That’s not the toolkit I’m looking for. The toolkit I’m looking for makes it easy to interact with http request and response streams instead of making it easy to hide their existence.
- infogulch 4y agoYou don't want to use request guards / automatic deserialization into strict types because it's not flexible enough. You're not willing to use the tiniest abstraction (a function) to perform the same behavior for different strictly encoded requests. (Well, you didn't really respond to the content of my comment at all, but nevermind.) You rejected ancestor's suggestion of using Request<Body>... which is exactly what is provided by Go. I can't tell what you want, all of these opinions stacked together are incoherent. > The toolkit I’m looking for makes it easy to interact with http request and response streams > I want something higher level than Hyper So higher level than hyper, but no higher level than hyper. Crystal clear.