Comments (5)
Thanks for the detailed write up! We've also been interested in something like WSGI/Rack/Servlet. Hopefully with the community's help, we can make something stellar.
In regards to T
having no bounds: This is actually a benefit!
First of all, by not having bounds on the body generic, this allows the crate to be used in both asynchronous frameworks and in synchronous. Requiring a trait bounds would likely hamper one of those sides. Likely, framework ecosystems will show up that do require a bounds. You could imagine a framework that behaves somewhat like hyper today, where T: Stream
is required.
Secondly, this allows for application writers to have these bounds at the borders, but to then map them into anything they want internally. So, if an framework receives Request<T> where T: Stream<Item=Vec<u8>, Error=io::Error>
, a user could map the request into something like a Request<Comment>
internally. Something like this:
fn framework_entrypoint<T>(req: Request<T>) -> BoxFuture<Response<T>, io::Error>
where T: Stream<Item=Vec<u8>, Error=io::Error> {
if req.method() == POST && req.uri().path() == "/article/comment" {
let (head, body) = req.into_parts();
body.concat2().map(move |vec| {
let comment = serde_json::from_slice(&vec)?;
let req = Request::from_parts(head, comment);
post_comment_for_article(req)
})
}
// ...
}
#[derive(Deserialize)]
struct Comment {
author: String,
body: String,
}
fn post_comment_for_article(req: Request<Comment>) -> Something {
// ...
}
Additionally, any sort of middleware that only adjusts headers can be made to work for any framework, since it can just put zero bounds on the body (since it won't look at the body anyways).
fn apply_cors<T>(res: &mut Response<T>, options: &CorsOptions) {
res.headers_mut().insert(name, value);
}
from http.
It looks like the discussion here came to a close.
from http.
We're discussing this issue right now in the Ruma project. We use an Endpoint trait for each API endpoint which converts between http
request and response types and our own concrete request and response types defined for each API endpoint. We have a crate (ruma-client-api) that implements these conversions, and a separate crate (ruma-client) that actually provides an HTTP client using Hyper. Notably, Ruma is only bound to Hyper at the level of ruma-client.
Our goal is to keep ruma-api and ruma-client-api agnostic to HTTP client implementations. Without the ability to constrain what type "body" is, and in the absence of any convention in the Rust HTTP ecosystem, there's no way to:
- Implement our
Endpoint
trait, because we need some knowledge of what the body is - Keep it interoperable with potential other HTTP clients.
To make item 1 possible, we'd need to add a restriction that the body is a Stream
whose items can be deref coerced into [u8]
. That would make it work with Hyper's Body
and Chunk
types. But we have no way of knowing whether or not such an interface would be compatible with other HTTP clients. Perhaps a convention will emerge in the ecosystem, but the unconstrained generic type in http
means that there's no real way to future proof this.
from http.
The HTTP crate specifically does not want to constrain request / response bodies to anything that resembles bytes. This would prevent storing a typed representation of the body.
from http.
Yep, I understand the reason it's designed the way it is. But the issue brought up here is a cost of this design. The crate offers types for everything except req/res bodies, and as a result req/res bodies cannot be interoperable between higher level crates that both use http
.
Perhaps a way of meeting in the middle would be to add traits to represent the most common scenarios: an async stream of bytes, and a sync collection of bytes. That way downstream crates could opt in to constraining the body types to one of these traits and be interoperable. Use cases that don't want this don't need to do anything different than they're doing now.
from http.
Related Issues (20)
- Clear contents of sensitive header values on drop HOT 2
- Why does canonical_reason() return a Option? HOT 3
- Rename 422 from "Unprocessable Entity" to "Unprocessable Content"
- const fn for `StatusCode::as_u16` HOT 1
- can't parse uri without scheme but having path HOT 4
- 1.0 vs 0.2 incompatibility HOT 1
- Allow customizing header casing
- Add a `Display` impl for `Request` and `Response` to reconstruct the raw HTTP message HOT 2
- impl std::error::Error for StatusCode HOT 1
- http::method::Method::FromStr implementation allows invalid methods, conflicting with from_str documentation HOT 2
- Invalid uri parse HOT 1
- `http::uri::Uri` is excessively large and makes unnecessary allocations HOT 2
- Failed to parse a valid url HOT 1
- Uri does not parse valid URIs with empty authority portion HOT 1
- Add 420 Enhance Your Calm status code
- How to append a queryparams string after using uri_mut().into_parts()? HOT 1
- `index out of bounds` when parsing a valid header value HOT 2
- Request headers containing Russian (and possibly other non-English) characters fail with `UTF-8 encoding error` HOT 1
- HeaderMap::try_with_capacity can panic when capacity is large
- RFC: Add `parts_mut() -> &mut Parts` to allow mutate parts directly HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from http.