
Rocket, Rust Web Framework, v0.3: Fairings, TLS, Private Cookies - sbenitez
https://rocket.rs/news/2017-07-14-version-0.3/
======
jamescostian
I actually really love the restrictions on fairings. I'm working on a project
right now that uses Node.js with Express, and there are all of these pieces of
middleware that won't compose at all, and I often find myself ripping things
out and putting them in new functions.

By having clear delineations between fairings, request guards, and data
guards, I think you can really avoid making a lot of design mistakes. I'm
going to try out Rust some more and definitely play around with this
framework! The only thing that bothers me is that Rocket says it requires a
nightly version of rust[0] - why is that necessary? I thought Rust was pretty
stable by now.

[0] [https://rocket.rs/guide/getting-started/#minimum-
nightly](https://rocket.rs/guide/getting-started/#minimum-nightly)

~~~
kibwen
_> Rocket says it requires a nightly version of rust[0] - why is that
necessary_

I often joke that Rocket deliberately uses every single unstable feature
solely to stymie the Rust developers' attempt to prioritize which features to
stabilize. :P I'm kidding of course (hi, sbenitez!), but it's true that I've
never seen any Rust project so taken with nightly features as Rocket is.

~~~
steveklabnik
For that list of features and the discussion around them,
[https://github.com/SergioBenitez/Rocket/issues/19](https://github.com/SergioBenitez/Rocket/issues/19)

~~~
legulere
i128 really surprises me. Why would a web framework need 128 bit integers?

~~~
fnord123
It appears u128s are used to intern strings. i.e. efficient uuids.

[https://github.com/SergioBenitez/Rocket/blob/master/codegen/...](https://github.com/SergioBenitez/Rocket/blob/master/codegen/src/utils/meta_item_ext.rs)

------
continuations
How is the performance of Rocket?

So far all the Rust web frameworks I've seen have pretty disappointing
performances.

I was expecting C++/Java/Go level of performance. Instead, Tokio & Iron turn
out to be slower than many frameworks in Ruby, Python, PHP, JS:

[https://www.techempower.com/benchmarks/#section=data-r14&hw=...](https://www.techempower.com/benchmarks/#section=data-r14&hw=ph&test=fortune)

[https://www.techempower.com/benchmarks/#section=data-r14&hw=...](https://www.techempower.com/benchmarks/#section=data-r14&hw=ph&test=query)

[https://www.techempower.com/benchmarks/#section=data-r14&hw=...](https://www.techempower.com/benchmarks/#section=data-r14&hw=ph&test=update)

~~~
steveklabnik
* iron isn't using async io which is very important for Techempower

* Tokio-minihttp is #4 overall on the plaintext benchmark there, which is sort of the "what is the max performance" benchmark

I don't know of anyone who is really actively looking at Techempower and
optimizing based on it, which is how you win benchmarks.

~~~
moomin
How is the async web server story looking? I keep thinking I'd like to port a
small tornado app to Rust, but I'd rather it was fairly easy for some to
verify it was behavioural similar.

(Literally, I don't care about the performance, I just want that style of
API.)

~~~
steveklabnik
I don't know now much about tornado's API, so I can't say for sure.

Right now, the async APIs are largely based on Futures. There's an
experimental branch of the compiler that implements coroutines and therefore
async/await on top of them though, so that syntax may or may not be coming in
the future.

------
Nelkins
I was just recently looking at the state of web frameworks[1] in Rust, and it
seems like the two most popular are this and Iron[2]. Can anyone comment on
some of the differences between the two? Also, can anyone point out a few
sites that were made using these frameworks?

[1] [http://www.arewewebyet.org/](http://www.arewewebyet.org/)

[2] [https://github.com/iron/iron](https://github.com/iron/iron)

~~~
steveklabnik
arewewebyet hasn't been updated since March, and there's been some big
developments since then.

Those probably are the two most popular, but there's a Cambrian Explosion
going on right now, with new frameworks like Susanoo and Cargonauts appearing
on the regular. Heck, I even have my own little half-baked one.

~~~
zanny
This is actually driving me a bit insane trying to do anything more than the
simplest Rust samples. There are... a lot of competing libraries implementing
the same concepts. Input validators, crypto, tls, http (there are I believe at
least 3 http/2 implementations, and hyper doesn't even support it yet) and
pretty much every concept under the sun (hell, hyper has its own
implementation of a url type independent from servo_url).

There are several Json types across all the various crates, multiple Url
types, multiple Http::Request or Hmac or SHA cipher types. They all use the
same names but are always distinct constructs that cannot interop.

It might be one of the most significant ergonomic issues with Rust going
forward. Having a dozen Url types in Python is fine since the typing usually
just coerces them all to Strings for interop anyway. _Most_ Url types are
(thankfully) serializiable and have a to_string, but in a statically typed
language the performance implications of having the compiler generate strings
from objects to be consumed by another object's constructor are dreadful.

~~~
steveklabnik
Yup, that's what early ecosystems are like! It'll settle down eventually.

~~~
wutwutwutwut
Some ecosystems stay like this for a long time (JavaScript).

------
bpicolo
Hey Sergio,

Regarding fairings, it seems a missing "middleware" case might be the sorts of
things that cause redirects on entry (e.g. redirect routes with/without
trailing slashes to the latter as a super trivial example). Is that something
you'd expect to support in some way? I think that's something that doesn't
feel like it maps either to guards or fairings well at the moment.

I did see where you mentioned your dislike of rails/sinatra/... style blunt
force middleware, fwiw.

~~~
sbenitez
This is actually possible with fairings! Because fairings can rewrite
requests, it's possible to create a fairing that rewrites a request URI of
`path/` to `path` or vice-versa as needed. Rocket will route the rewritten
request normally. In psuedocode, such a fairing might look like:

    
    
      on_request => |request, _| {
          if request.uri().path().ends_with('/') {
              let new_path = request.uri().path()[..-1];
              request.set_uri(URI::new(new_path));
          }
      }
    

You can also use a fairing If you want to return a 302 (or similar) so that
the browser does the redirect instead. In this case, you'd implement a
response fairing that rewrites failed responses to return a redirect to the
appropriate URI. Again, in pseudocode, this would look like:

    
    
      on_response => |request, response| {
          if response.status() == Status::NotFound && request.uri().path().ends_with('/') {
              response.set_status(Status::Found);
              response.set_header(Location(request.uri().path()[..-1]));
              response.take_body();
          }
      }
    

Take a look at the fairings guide [0] and fairings documentation [1] for more
ideas!

[0]: [https://rocket.rs/guide/fairings/](https://rocket.rs/guide/fairings/)

[1]:
[https://api.rocket.rs/rocket/fairing/trait.Fairing.html](https://api.rocket.rs/rocket/fairing/trait.Fairing.html)

------
pc2g4d
I'm a Rocket fan and glad to see this big slate of improvements. On the other
hand, I do want to register a bit of concern regarding the plan to add "first-
class database support" for 0.4. I hope that doesn't result in a close
coupling to any particular database, or to using a database in general.

~~~
StavrosK
Isn't Postgres worth coupling to? SQLite is a close favorite, for different
reasons.

~~~
yen223
Web servers and database management are two vastly different domains. I'm wary
of frameworks that attempt to impose an opinion on both.

~~~
StavrosK
Rocket isn't a web server, it's a web framework. That's what frameworks
_should_ do, impose opinions on things to get all the best practices sorted.

------
wyldfire
> Private Cookies #

> To encrypt private cookies, Rocket uses the 256-bit key specified in the
> secret_key configuration parameter. If one is not specified, Rocket
> automatically generates a fresh key at launch.

Seems like a pretty clever idea. Do other servers/middlewares offer a similar
feature? Seems like it would complicate deployment/scaling a bit if the secret
has to be sent to all the nodes. Especially if they could silently ignore it
if you accidentally don't configure the key for some nodes.

~~~
zimbatm
Rails had encrypted cookies for ages

~~~
wtetzner
I think wyldfire was referring to the part about generating a new key on
launch. Of course, Rails might do that too, for all I know.

~~~
floatboth
uhh generating a new key on launch means every time you restart the app,
everyone's cookies must be reset because the old ones can't be decrypted
anymore.

It's just a convenience feature for development.

------
dvnguyen
I don't have any experience in Rust. From what I read, Rust is a low level /
system programming language. Comparing to dynamic languages like Python, I
understand that Rust is much faster. However, Python is fast enough for most
web applications. So why should I use Rust in web development? Even if the
library ecosystem were mature enough, could I expect my productivity could
become nearly high as in Python?

~~~
kibwen
I'd say it's true that Python is fast enough for most web servers. Rather than
strictly considering performance, I'd guess that people seeking to do webdev
in Rust are looking to leverage Rust's static analysis to improve resilience,
trading off up-front productivity for long-term maintainability (which isn't
to denigrate Python, which I love, but fearless refactoring really is
something that compiled langs excel at). It's not the right tradeoff for
everyone or every application, certainly. And maybe other people just really
like Rust. :P

~~~
kevan
We also shouldn't discount it just because Python is usually fast enough (all
my personal projects are in Python). Developer time is cheaper than hardware
99% of the time. For the 1% that are running millions of requests per second
through their web stacks the value proposition is pretty compelling.

~~~
xfer
> Developer time is cheaper than hardware 99% of the time.

I find the exact opposite to be true in most cases.

~~~
mixedCase
In bare metal deployments or cloud? If the latter, then moving to the former
seems like an obvious choice.

------
eptcyka
It's really a shame they haven't jumped on tokio yet. Then again, I tried to
look at the code, and it didn't seem to be a simple dropin thing to move over
to tokio.

~~~
biokoda
It's far from clear if tokio is not a dead end.

~~~
mercurial
How so?

~~~
biokoda
Overly complicated

~~~
mercurial
I'm not sure it is an issue of complexity. From what I have seen, it is more a
problem of ergonomics. Currently, programming something fairly simple with a
few loops and if statements using Futures is painful, but I could see a
Futures-based async/await version take off.

------
shmerl
What's not clear from the front page. Is it its own Web server? Is it a
framework which uses another Web server? I think that would be useful to
clarify from the start.

~~~
kpcyrd
It's very similar to nodejs web frameworks. If you start it you have a working
webserver with your application in it.

~~~
shmerl
OK, that makes it clear, because for example Rails require existing Web server
in contrast.

~~~
bryanlarsen
I this is quite similar to Rails; by default Rails includes webbrick or puma.

~~~
shmerl
OK, browsing through their code, I see they use Hyper.

~~~
Tobu
But they're still on the previous, non-Tokio release.

Personally I'm more tempted by something like Susanoo:
[https://github.com/ubnt-intrepid/susanoo/](https://github.com/ubnt-
intrepid/susanoo/)

------
leshow
Rocket is great. Congrats on the new release!

------
lholden
Fantastic Sergio! I'm glad v0.3 has landed :D

------
Scarbutt
Since its async, do you have to develop in it using callbacks?

~~~
steveklabnik
Rocket is not yet async [https://github.com/SergioBenitez/Rocket#future-
improvements](https://github.com/SergioBenitez/Rocket#future-improvements)

