TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Magical Handler Functions in Rust

112 pointsby bkolobaraover 2 years ago

13 comments

mckirkover 2 years ago
To me, this kind of &#x27;magic&#x27; is definitely a double-edged sword. For the people that are familiar with the framework, I assume it makes it much nicer to write code and to reason over it (at the above-framework level), since there&#x27;s no boilerplate to write or understand.<p>But as someone who often has to jump into unknown codebases and get up-to-speed quickly, I&#x27;ve certainly been confused by framework magic before, which makes it almost impossible to reason &#x27;up&#x27; from the concrete implementation of e.g. a request handler. Since the keywords to grep for aren&#x27;t explicitly mentioned in the handler anywhere and the &#x27;dispatch&#x27; side of things is hidden under mountains of abstraction, you usually have to resort to tutorials to understand what the hell is going on, and even then the codebase might use some extra-magical properties of the framework that aren&#x27;t clear to anyone that isn&#x27;t at home within it.<p>So it could be argued that this magic saves you code in exchange for a need for more documentation, at which point you might just be better off being more explicit in your code -- at least explicit enough so things remain greppable.
评论 #33237374 未加载
评论 #33238235 未加载
kibwenover 2 years ago
<i>&gt; Rust developers generally like these properties, predictability and explicitness, instead of magic. That’s why I’m quite surprised that most Rust web frameworks went another route.</i><p>Ecosystems are rarely monoliths, and I assume that the people writing web frameworks in Rust are likely to have experience with (or at least be inspired by) more magical frameworks in other (usually more dynamic) languages, whereas the libraries that eschew magic are presumably written by people with prior experience in low-level languages. The fact that Rust has some amount of appeal to both of these crowds (not to mention the functional programming folks) makes it a bit of a melting pot.
评论 #33238325 未加载
losvedirover 2 years ago
As a relative newbie in Rust who recently dabbled with Axum, I wholeheartedly agree that the handlers and extractors are magical and hard for first-time users. Another issue I ran into that&#x27;s not mentioned in the post, is the compile-time type errors are pretty cryptic, if you get it wrong. I was trying to use the new state extractor, and didn&#x27;t have my state properly wrapped in an Arc and it was complaining to me in a way that was totally unhelpful. The docs mention there&#x27;s an `axum-macros` crate which can help here, but I feel like if you need macros to get around confusing type errors, you&#x27;re going against the grain pretty hard.<p>On the whole I still found experience pretty compelling, though, as I did eventually get a little web app running with great performance and very low memory usage.
评论 #33239941 未加载
kubotaover 2 years ago
This was an interesting read for a Java &#x2F; JVM language developer that has recently begun learning and using Rust in personal projects.I was curious how the magic was working begind the scenes. In the Java world, our most popular framework (Spring Boot) takes Magic to another level, since Java allows reflection, lots of magic is possible.
评论 #33238346 未加载
dathinabover 2 years ago
While extractors are sometimes doing copies, it is basically never in situations where it matters.<p>For example extractors on the json body will always _move the body out of the request_ (independent of the position the extractor is in).<p>Sure there is some copying for e.g. request parameters, but you very often do that anyway as you e.g. do some urldecoding, parsing and similar on the parameters, e.g. extracting a Uuid type from a `&#x2F;user&#x2F;9313ba53-955e-4ce1-8b53-de8f92656196&#x2F;bar` path.<p>Similar if the extractor doesn&#x27;t return the error type you want you can wrap it an map the error when extracting. Sure with actix-web and warp there are some error handling situations which they don&#x27;t handle well, but that got improved on in axume.<p>Application state is shared across threads (or at least across time) so it&#x27;s anyway in a `Arc` or `Rc` so you are just cloning the reference pointer but not the data behind it.<p>Lastly if you have a very special situation you can decide to just accept a `Request` moving (not copying) it into the handle and do the rest yourself by hand.<p>Without question the system has potential for improvements, but for now it has become the de-facto standard due to it being very convenient, does work well for many use cases and does not add a relevant performance overhead for a lot of use cases.<p>Now their solution is targeting backend WASM so they probably use will focus in single threaded WASM with some snapshot mechanics to easily sandbox each request so their requirements are anyway a bit different but looking into history routing macros where common in the past as far as I remember, and they are pretty much all gone by now.<p>But then they probably will go through a bunch of revisions of their system, so it&#x27;s not like they can&#x27;t add it back in later one.<p>EDIT: Just to be clear their solution is a fully valid reasonable approach.
mleonhardover 2 years ago
I also wanted a Rust web server with no magic, that uses async internally, and lets me write threaded request handlers. None existed, so I wrote one:<p><a href="https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;servlin" rel="nofollow">https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;servlin</a><p>Servlin contains no unsafe code. I picked dependencies to have as little unsafe code as possible. I wrote some unsafe-free deps: safina (async runtime), safe-regex, fixed-buffer, permit, temp-dir, and temp-file. I plan to replace other unsafe deps: url, async-net, and serde. Eventually Servlin&#x27;s only unsafe will be in the standard library and `polling` crate.<p>Servlin supports single-file webapp deployments by including web assets in the binary. I plan to develop Servlin until it is as strong as nginx and can run reliably with no load balancer. And someday a good Rust unikernel will exist and we will run Servlin binaries directly on hardware. That will be the world&#x27;s shortest, most secure, and most performant web stack.<p>Please contact me if you would like to help improve Servlin.
brundolfover 2 years ago
I agree with most of the criticisms of the &quot;magic&quot; functions, although I really have to disagree that the macro approach (with a totally custom DSL) for routing&#x2F;authorization is <i>less</i> magical than the alternative. It also cripples IDE support. With a builder-pattern you can get smooth autocompletion and clear error messages, while macros usually sabotage error messaging and completely sabotage autocomplete.<p>Bigger picture: I think the reason so many Rust frameworks favor this kind of magic is to lower the bar (accessibility, but also development velocity). Being lower-level, Rust starts off with a disadvantage when it comes to quickly building out high-level application logic like you would on a typical web server, so when people are trying to expand its reach into areas like that, they try to close the gap by making their libraries as easy-to-use and boilerplate-free as they can. Rust&#x27;s macro and type systems are the mechanisms it provides for eliminating boilerplate and generally making it act like a higher-level language, so that&#x27;s what people use. And that makes well enough sense, even though it comes with trade-offs.
SevenNationover 2 years ago
&gt; ... I don’t know the “official” name for it, so I just stole the name from a recent reddit post (magical handler functions).<p>What&#x27;s the difference between programming &quot;magic&quot; and &quot;using the language to its fullest&quot;?<p>Wikipedia has an article dedicated to the concept of magical programming. It starts with:<p>&gt; In the context of computer programming, magic is an informal term for abstraction; it is used to describe code that handles complex tasks while hiding that complexity to present a simple interface. The term is somewhat tongue-in-cheek, and often carries bad connotations, implying that the true behavior of the code is not immediately apparent. For example, Perl&#x27;s polymorphic typing and closure mechanisms are often called &quot;magic&quot;. The term implies that the hidden complexity is at least in principle understandable, in contrast to black magic and deep magic (see Variants), which describe arcane techniques that are deliberately hidden or extremely difficult to understand. However, the term can also be applied endearingly, suggesting a &quot;charm&quot; about the code. The action of such abstractions is described as being done &quot;automagically&quot;, a portmanteau of &quot;automatically&quot; and &quot;magically&quot;.<p><a href="https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Magic_(programming)" rel="nofollow">https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Magic_(programming)</a><p>I think that &quot;true behavior of the code is not immediately apparent&quot; is the key. The harder it is to figure out how something works, the more likely it is to be viewed as &quot;magic.&quot;<p>Do the magical handlers in this article fit the bill? I&#x27;m not so sure. All that&#x27;s going on is generics applied to functions. True, it&#x27;s not as common as generics applied to other types. But it&#x27;s also not fringe.<p>Maybe as a technique becomes more established, it starts to seem less magical. The author notes:<p>&gt; Exploring this pattern was an interesting journey. I still can’t tell why it’s more popular than the alternative that contains less magic and gives more flexibility to developers. I can only assume that even Rust developers long for some magic and coolness in their tooling.<p>Maybe it&#x27;s more popular because it&#x27;s now widely used across Rust web frameworks and therefore expected as a convention?
chrismorganover 2 years ago
&gt; <i>I don’t know the “official” name for it, so I just stole the name from a recent reddit post (magical handler functions).</i><p>I’d want a term mentioning that it’s type- or signature-guided or -driven. “Magical” is way too non-specific. How about “signature-driven handler functions”? Seems both accurate and fairly clear.
insanitybitover 2 years ago
I&#x27;m in agreement that a simple macro can be just as readable as any other code.
efficaxover 2 years ago
someone explain to me the point of backend webassembly for a web framework? you&#x27;re running the compiler already, why not emit... actual assembly
评论 #33239226 未加载
评论 #33238306 未加载
评论 #33238665 未加载
评论 #33239786 未加载
评论 #33238338 未加载
gigatexalover 2 years ago
Dislike. Give me verbosity and pragmatism. I like simple functions that so one thing and are easy to reason about and test.
评论 #33242295 未加载
评论 #33255131 未加载
Dowwieover 2 years ago
Extractor types aren&#x27;t magical. You can clearly see the types involved. How and when are those types constructed? That&#x27;s up to you to research.