[HN Gopher] Hyper - A fast and correct HTTP implementation for Rust
___________________________________________________________________
Hyper - A fast and correct HTTP implementation for Rust
Author : belter
Score : 71 points
Date : 2023-05-12 19:07 UTC (3 hours ago)
(HTM) web link (crates.io)
(TXT) w3m dump (crates.io)
| infogulch wrote:
| Any recommendations for rust template engines? I'd like something
| that can easily render labeled fragments of a template instead of
| requiring me to split a page into a dozen little files. Kinda
| like inline {{block}} definitions in Go's html/template. Speed is
| also nice.
|
| From template-benchmark-rs [0] I found sailfish [1] (fast, but no
| fragments(?)). render-rs [2] and syn-rsx [3] both let you write
| html in rust macros which is cool (maybe that can substitute for
| fragments?). Then there's gtmpl-rust [4] which is just Go
| templates reimplemented in rust.
|
| [0]: https://github.com/rosetta-rs/template-benchmarks-rs
|
| [1]: https://github.com/rust-sailfish/sailfish
|
| [2]: https://github.com/render-rs/render.rs last updated Jul 2020
|
| [3]: https://github.com/stoically/syn-rsx last updated Nov 2022
|
| [4]: https://github.com/fiji-flo/gtmpl-rust
| tomjakubowski wrote:
| tera is fairly standard. Jinja2-like syntax. I'm not sure what
| you mean about rendering labeled fragments, do you have an
| example?
| infogulch wrote:
| Sure. They're called 'partials' sometimes. Useful if you want
| to rerender just part of a page. This is a pattern used by
| HTMX, a 'js framework' that accepts fragments of html in an
| http response and injects it into the page. This is good
| because it avoids the flash and state loss of a whole page
| reload. See the HTMX essay on template fragments for a more
| complete argument [0].
|
| This is a go template for an interactive todos app [1] that
| I'm experimenting with. The html content of the entire page
| is present in one template definition which is split into 6
| inline {{block}} definitions / "fragments". The page supports
| 5 interactions indicated by {{define}} definitions, each of
| which reuse various block fragments relevant to that
| interaction. I'm in the process of converting it to use
| embedded cozodb [2] queries which act as a server side data
| store. The idea here is that the entire 'app', including all
| html fragments, styles, http requests and responses, db
| schema, and queries are embedded into this single 100-line
| file.
|
| [0]: https://htmx.org/essays/template-fragments/
|
| [1]: https://github.com/infogulch/go-
| htmx/blob/master/templates/t...
|
| [2]: https://github.com/cozodb/cozo
| prussian wrote:
| https://maud.lambda.xyz/
|
| Maybe this?
| renewiltord wrote:
| Appears to have heavy use of `async`, etc. Has anyone gone about
| creating JNI bindings for an `async` API? I imagine you start the
| pool in a context object and then access the APIs through that
| via some callback mechanism? I'd love to read someone's example
| code if you're willing to share.
| subarctic wrote:
| I'm not really familiar with JNI and not sure if it's different
| on Android vs server-side Java, but this forum thread might be
| interesting reading for you: https://users.rust-
| lang.org/t/rust-jni-android-async-callbac...
|
| EDIT: also maybe take a look at this?
| https://github.com/rousan/AndroidWithRust
|
| "tokio jni" is the search term that turned these up for me
| Animats wrote:
| Hyper is still at version 0.x.
|
| I currently use "ureq" client side, due to async contamination in
| Hyper.
| timeon wrote:
| "ureq" is bit different from Hyper. Hyper is lower level. In
| same category as "ureq" - there is "reqwest" which is built on
| top of Hyper and has also "blocking" option (aka without
| async).
| satvikpendem wrote:
| If you want to build a backend in Rust, Axum (which uses hyper
| underneath) is pretty recommended these days, as it's all in the
| tokio ecosystem. Actix Web is good too, but it has its own
| ecosystem of libraries. I read the book Zero To Production in
| Rust [0] which was a great overview on not just Rust but scalable
| backend architectures as a whole.
|
| Interestingly, Cloudflare wanted to use hyper but found that it
| was _too_ correct, so they had to build their own [1].
|
| [0] https://www.zero2prod.com
|
| [1] https://blog.cloudflare.com/how-we-built-pingora-the-
| proxy-t...
| tele_ski wrote:
| We interestingly ran into issues with actix and the AWS lb. The
| lb takes some liberty with how it handled connections and actix
| seems to be "to the spec" so we were seeing a lot of dropped
| connections. Placing nginx between the two resolved the issue
| but it's fairly disappointing that we need that layer when it
| should be unnecessary overhead. I'd love to give axum a try if
| we could find time and see if it behaves better.
| infogulch wrote:
| > lb takes some liberty with how it handled connections
|
| Interesting, I'm curious about the details here. Does the lb
| reuse connections for multiple requests or something?
| scottlamb wrote:
| > Interesting, I'm curious about the details here. Does the
| lb reuse connections for multiple requests or something?
|
| I'm curious too. There must be more to it than that because
| LBs reusing backhaul connections is standard practice. It's
| not only an optimization but in many cases you'll quickly
| hit ephemeral port exhaustion if you don't. TCP connections
| are distinguished by (src_ip, src_port, dst_ip, dst_port)
| tuple. For this leg you're probably only varying the
| src_port portion, and all of the valid options are cooling
| in time_wait state.
| cschneid wrote:
| What's the current state of database access? Last I looked a
| while back Diesel was really cool, but didn't play nice w/
| Async.
| phaer wrote:
| Haven't used it myself, but https://github.com/SeaQL/sea-orm
| seems to be popular in some communities and async
| lwhsiao wrote:
| SQLx [1] is commonly recommended. It has the nice feature
| that your queries can be verified at compile time.
|
| [1]: https://github.com/launchbadge/sqlx
| redman25 wrote:
| Async is not necessarily as useful for database connections
| since connection counts will generally be in the 10s and
| handled with a thread pool. It's pretty low overhead to just
| use pooling.
| unshavedyak wrote:
| Yea but you still want a good async interface if you're
| already using async, even if it's mocked over an underlying
| threadpool. Otherwise you have to wrap all your DB clients
| in your own adhoc async wrappers which feels kinda bad,
| imo.
| satvikpendem wrote:
| I use Prisma Client Rust [0], coming from the Node.js world,
| it works great. Some people like to use sqlx though, I'm not
| too big into writing SQL for every little thing.
|
| [0] https://github.com/Brendonovich/prisma-client-rust
| Spartan-S63 wrote:
| Diesel now has an official async adapter:
| https://crates.io/crates/diesel-async
| skywal_l wrote:
| I tried warp [0] and I am unimpressed so far. Pretty complex,
| limited documentation, buggy. The builder paradigm they used
| feels pretty constrained and, in my opinion, achieve the
| opposite of the simplicity it is supposed to bring. I was
| surprised it is so popular.
|
| Maybe I need more time or a favorable comparison to another
| framework to appreciate it.
|
| [0] https://github.com/seanmonstar/warp
| dcormier wrote:
| We used warp originally, and ended up refactoring to axum.
| We've been much happier with it.
| sdfghswe wrote:
| Why is it that "it's correct" is something worth mentioning?
| Presumably if it's not correct it's either not an implementation,
| or not known that it's not correct.
| epgui wrote:
| I don't know if it's what is being referred to here, but
| "provably correct software" is a whole thing. It takes the idea
| of software tests to the next level, and is very important in
| some contexts.
| satvikpendem wrote:
| The implementation could be incorrect (in certain cases) but
| still be useful. Cloudflare has such an implementation:
| https://blog.cloudflare.com/how-we-built-pingora-the-proxy-t...
| cmckn wrote:
| Share the same general sentiment, but in the case of HTTP, many
| implementations are forgiving of conventional usage that may
| not match the specs; so I guess it's worth mentioning that this
| impl is strictly by-the-book.
| rickstanley wrote:
| This "book" would be the RFC?
| chlorion wrote:
| Yes, "by the book" is a very commonly used metaphor in
| English, even when no book is involved.
|
| It's roughly equal to saying that you are doing something
| strictly by the rules (and the rules don't have to be
| contained in a book or even exist in text form).
|
| Some uses would be like: "My boss insists on doing
| everything by the book".
| sophacles wrote:
| It's a good question with an unsatisfying answer. Networking is
| kind of difficult.
|
| Sitting down with an RFC and coding up what it says is nowhere
| near as simple as it seems like it should be:
|
| * RFCs are often ambiguous, I've seen teams implement a
| protocol in a way that certainly seems to follow the RFC but
| won't be widely interoperable.
|
| * RFCs are often incomplete, many protocols are specified
| across a lot of different RFCs, and by different authors, so
| it's easy to miss important details or even whole RFCs
| exacerbating the above point.
|
| * RFCs are regularly released as protocols evolve and
| invalidate older versions of the protocol (or early
| experimental versions of the protocol, etc) often. Sometimes
| the newest RFC does a lot of work to disambiguate what would be
| allowed by older versions see for example this recent RFC
| https://httpwg.org/specs/rfc9110.html
|
| * Independent of what the RFC says, there's what Cisco does (or
| MS or Google or other large influential imlementors).
|
| * A lot of protocol implementations don't implement the full
| protocol (that is various extensions or rarely used features).
|
| * A lot of protocol implementations implement what the RFC says
| in the most commonly aggreed on way, plus a compatibility
| options for other commonly used implementations, plus some
| oddball interpretations of the RFC that the authors like.
|
| * There's vendor-specific extensions.
|
| * There's common but unspecified behaviors that implementations
| tend to converge on, but which aren't easy to intuit.
|
| * There's implementations that handle mixtures of versions
| (e.g. implementations of http 1.1 that handle 1.0 or 0.9 just
| fine are common).
|
| And so on. So to answer the question "is 'it's correct' worth
| mentioning?" - yes, something along these lines tends to be
| important.
|
| Of course "what does correct mean" is a giant can of worms....
|
| In the case of hyper I think it means: an attempt to be
| extremely precise in what is allowed (and as close to the
| disambiguated RFCs as possible), and strict as well - not being
| particularly loose in what it accepts as input. That's my
| interpretation anway.
| vp8989 wrote:
| "Sitting down with an RFC and coding up what it says is
| nowhere near as simple as it seems like it should be"
|
| I learned this for myself when I tried coding an IRC server
| for fun. Quickly found that I made more progress, faster by
| just using Wireshark to see what an established server was
| doing and copying that.
| tux3 wrote:
| For HTTP, being pedantically correct is a tradeoff. On the plus
| side, you prevent weird potentially unexpected behaviors by
| cleanly rejecting off-spec behavior instead of accepting
| potentially broken input and seeing what happens.
|
| But you also can't interact with everyone else anymore, because
| a whole lot of people run slightly off-spec software,
| successfully, and sometimes without knowing it.
| timeon wrote:
| Also: https://crates.io/crates/arti-hyper
| loeg wrote:
| Any particular reason to highlight Hyper now? This crate has been
| around for years, I think?
| belter wrote:
| The daily 10,000 ? - https://xkcd.com/1053/
| charcircuit wrote:
| That doesn't explain why Hyper. There is millions of things
| people don't know that you could choose from.
| mcdonje wrote:
| Go ahead and post one of those millions of other things.
| simonhamp wrote:
| How does this compare to Rocket (https://rocket.rs/) - I've just
| started using Rocket and it seems to provide everything that
| Hyper does and a lot more out of the box too
|
| When would I use Hyper instead of Rocket?
| paavohtl wrote:
| Hyper is a relatively low level HTTP library, while Rocket is a
| web server framework. So Hyper doesn't concern itself with
| things like routing, authentication, state management, template
| rendering, static file hosting and so on, which Rocket
| provides. Hyper is only focused on being a good implementation
| of the HTTP protocol and serving as a base for higher level
| libraries and applications. You could use Hyper to build a
| framework like Rocket - though AFAIK Rocket uses its own HTTP
| implementation.
|
| It's kind of like that difference between Photoshop and libpng.
| sam0x17 wrote:
| Rocket uses hyper for it's HTTP
| [deleted]
| darrell_roberts wrote:
| It is built using hyper.
|
| Hyper is a dependency:
|
| https://github.com/SergioBenitez/Rocket/blob/v0.5-rc/core/ht...
| satvikpendem wrote:
| Others have explained the difference, but I wouldn't use Rocket
| at all, to be honest. It's barely maintained, the maintainer
| left for some time without telling anyone and without giving
| any repository access to other contributors, and it has a bus
| factor of one. I'd recommend Axum since it's backed by the
| Tokio contributors which makes it much less likely to be
| unmaintained later on.
| simonhamp wrote:
| There was a release just a couple of months ago - that
| doesn't seem to be "barely maintained"
| satvikpendem wrote:
| The 0.5 release is literally years in the making and
| there's no indication that it'll be done any time soon. The
| creator said they finished most of it in a 2020 comment and
| it's still not done.
| donpdonp wrote:
| I cant speak to 'correctness' but ureq has been great to work
| with. Simple and small. https://crates.io/crates/ureq
| benatkin wrote:
| It's what Deno uses.
| https://crates.io/crates/deno_http/0.99.0/dependencies
|
| "A fast an correct HTTP implementation" makes sense for Deno, as
| Deno is founded by the same person who founded Node.js and the
| correctness of Node's HTTP server was different from that of
| other scripting languages.
| tomjakubowski wrote:
| In what ways was Node's HTTP server different? Is it still a
| problem with today's Node versions?
| benatkin wrote:
| Oh I mean Deno's HTTP server is excellent in the same way
| Node's is. That isn't cited as one of the primary reasons for
| creating Deno. However Deno is built on a different platform
| (Rust rather than C) so it uses a different HTTP library.
|
| I'm pretty sure Deno is contributing significantly to Hyper.
|
| Deno's HTTP server is more balanced when it comes to
| tradeoffs than node's I think. Node is optimized for IO-bound
| programs is what I have heard.
___________________________________________________________________
(page generated 2023-05-12 23:01 UTC)