
Show HN: Rocket – Web Framework for Rust - sbenitez
https://rocket.rs
======
eveith
I am not a web development guy, so this question might seem ridiculous: To me,
it always seems that there are a lot of hazards in any web development
project, security-wise: A number of attacks, be it injections, XSS, etc. When
seeing a new web development framework, I always ask myself: Are the basic
security concerns known today addressed? How can I make sure that choosing
cool web framework in language X doesn't lead me to an unsafe webapp? Perhaps
somebody with more knowledge in web development could chime in here and help
me; I would really appreciate that.

~~~
peller
The canonical resource I'm aware of is the OWASP project.[0-3] Basically
though, always escape user-supplied data (and make sure you're correctly
escaping it for the contexts of where it ends up[4]), don't roll your own
crypto/authentication, and stick to using battle-tested libraries. (If
security matters that much to your app, stick to "boring established framework
X" and let other people choose "cool new framework Y".)

[0]
[https://www.owasp.org/index.php/Category:Popular](https://www.owasp.org/index.php/Category:Popular)

[1]
[https://www.owasp.org/index.php/SQL_Injection_Prevention_Che...](https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet)

[2]
[https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_P...](https://www.owasp.org/index.php/XSS_\(Cross_Site_Scripting\)_Prevention_Cheat_Sheet)

[3] [https://www.owasp.org/index.php/Cross-
Site_Request_Forgery_(...](https://www.owasp.org/index.php/Cross-
Site_Request_Forgery_\(CSRF\)_Prevention_Cheat_Sheet)

[4] A good framework, used correctly, should take care of most (all?) escaping
for you. For SQL injection, it's the ORM's job. For XSS, anything using a
virtual DOM should escape stuff for you (I know React does). CSRF is more to
do with session management, which is where using battle-tested auth code comes
into play.

~~~
andrewstuart2
Virtual DOM doesn't really have anything to do with preventing XSS. It's done
in angular 1 as well.

Really, it's about taint checking [1]. Distrust all sources of content by
default that might have seen user input (or that you know have seen user
input), and require explicit trust declarations from the developers to remove
taints.

When you're about to use the data (e.g. appending to the DOM), you simply
check for tainted data and escape is for the context you're in. Most times in
the browser, that just means escaping content that might be valid HTML, but
there are probably other contexts that require escaping as well.

[1][https://en.wikipedia.org/wiki/Taint_checking](https://en.wikipedia.org/wiki/Taint_checking)

~~~
peller
Ah, thanks for the clarification! Today I learned :)

------
EugeneOZ
Syntax is amazing! Hope (so much) to see it possible on beta soon. Maybe for
somebody it's not a new thing, but for me this:

    
    
      struct Message {
         contents: String,
      } 
          
      #[put("/<id>", data = "<message>")]
      fn update(id: ID, message: JSON<Message>)
    

where message is auto-decoded - it's awesome!

~~~
aaron-lebo
Edit: should preface this by saying the framework looks really impressive.
I've been looking for a Rust web framework to settle on and this is the most
appealing.

It's funny to note how much something small like this matters. It's syntax
sugar and presentation, but the difference a comment like this has at the top
of an HN post vs an ambiguous but detailed discussion about feature
x...massive in effect.

It doesn't seem to be the case, but the entire framework under that could be
bad yet it's caught mindshare on the basis of routing syntax (one of the
smallest worries in a production web application). Wonder how many frameworks
have failed just on the basis of not making a similar decisive first
impression?

Syntax matters?

~~~
steveklabnik
We're in the process of addressing discoverability of the crates.io ecosystem,
which led to this RFC: [https://github.com/rust-
lang/rfcs/pull/1824](https://github.com/rust-lang/rfcs/pull/1824)

A quote from it:

> By far, the most common attribute people said they considered in the survey
> was whether a crate had good documentation. Frequently mentioned when
> discussing documentation was the desire to quickly find an example of how to
> use the crate.

Open source projects, in a sense, are like startups: if you want to acquire
users, your users have to be able to understand the product! A deeply
impressive technical project is, well, impressive, but if nobody can figure
out how to use it, it's not going to see nearly as much uptake as a technology
that's got a clear and easy way to use it.

There's secondary effects too: a project with a slick website like this makes
people take it more seriously. It's less likely that someone who put this much
effort in is just going to drop it immediately, though of course, that's not
an absolute rule.

TL;DR: developers are users too. Developer marketing matters!

~~~
CorvusCrypto
Can I just say, I cannot applaud you enough (nor other contributors to rust)
for how much you care about developer opinions and ease of their introduction
to the language and subsequent use! I freaking love you guys.

------
johnwheeler
One of my influences, Armin Ronacher, has been doing a lot of Rust work
lately, so I've been thinking about looking at it more closely since I
appreciate his Python tastes.

Is Rust simple and elegant in the sense that Python is? I've also heard it's
for systems programming, which makes me think of C and has kept me away from
it. I like how I can bang out scripts quickly in Python. Is the same true of
Rust?

edit: found this [http://lucumr.pocoo.org/2015/5/27/rust-for-
pythonistas/](http://lucumr.pocoo.org/2015/5/27/rust-for-pythonistas/)

~~~
Manishearth
> I've also heard it's for systems programming, which makes me think of C and
> has kept me away from it.

One of its major goals is making systems programming more accessible. So you
shouldn't dismiss it because "systems programming = C", it's trying to change
that! :)

That's not to say it won't involve learning some systemsy concepts. But it
won't be as scary as C.

You can't necessarily bang out scripts quickly. A type system tends to make
this task verbose. However, larger applications benefit a lot from that type
system.

We've often had feedback from Python/JS shops using Rust that learning Rust
had the side effect of teaching them systems programming. I think that's
pretty awesome.

~~~
johnwheeler
I guess I'm contrasting Python with my Java experience so far as banging out
prototypes quickly.

In Java, I don't think the type system gets in the way so much as its
classpath. It's been a long time since I've done Java, but you'd have to get
your jars in order and write an ant or maven script to do the compile/run
steps (or at least a bash script).

I like that with Python I can just do pip install whatever and begin using the
module immediately in my main method. In Java, It's not standard practice to
copy jars into the system classpath IIRC, so you'd have to copy them around
every time you want to do something new.

I need to investigate Rust's command line interface. Obviously, the more it
can get close to

python main.py

vs.

javac -cp foo/Bar.jar:baz/Quux.jar Main.java; java --classpath
foo/Bar.jar:baz/Quux.jar Main

the better it will be for this use case I mention.

Thanks to both of you for responding!

~~~
Cyph0n
I believe Rust's package manager, Cargo, is quite similar to pip in
functionality. I haven't used it myself, so I could be wrong.

~~~
steveklabnik
In some ways. It's also got the features of
[https://github.com/pypa/pipfile](https://github.com/pypa/pipfile)

------
eigenrick
This demonstrates the brilliance of Rust's syntax extensions. Not only is the
code more readable and ergonomic, but also type safe.

Errors or mismatches in implementations are caught at compile time, saving
minutes (or potentially hours or days) in frustrating debugging.

Nice work! This looks fantastic.

~~~
Manishearth
> This demonstrates the brilliance of Rust's syntax extensions.

Sadly this functionality currently requires nightly or using a code generating
build script via syntex :(

(Rocket currently only works with nightly, but someone could pretty easily add
a syntex port since the APIs are the same)

With macros 1.1, some of this functionality is available on stable, but not
the functionality needed by this. I don't know if we plan a "macros 1.2" that
stabilizes tokentree expansion for all decorators (not just type item
decorators). ("Macros 2.0" is the final polished version of Rust procedural
and regular macros, for which there are concrete plans but it will take time
to get to)

~~~
erickt
For those not watching the compiler development traffic, macros 1.1 (which
will enable things like #[derive(FromForm))]) could land in stable as soon as
6 weeks from now. We haven't really started thinking about a "macros 1.2" yet,
so syntex will still have some use.

If you want to know more about our glorious macros 1.1 future, David Tolnay
just have a great meetup talk all about this a few weeks ago:

[https://air.mozilla.org/rust-meetup-
december-2016-12-15/](https://air.mozilla.org/rust-meetup-
december-2016-12-15/)

~~~
steveklabnik
The plan is for macros 1.1 to land in the next release, I wrote about it
yesterday:
[https://news.ycombinator.com/item?id=13239774](https://news.ycombinator.com/item?id=13239774)

------
halestock
Are dynamic params enforced at compile time? I.e. will the compiler ensure
that the route "/<id>" has a matching id parameter?

~~~
sbenitez
Yes! Here's what happens when you don't do the right thing:

    
    
      error: 'id' is declared as an argument...
       --> src/main.rs:8:9
        |
      8 | #[get("/<id>")]
        |         ^^^^
    
      error: ...but isn't in the function signature.
        --> src/main.rs:9:1
         |
      9  |   fn hello() -> &'static str {
         |  _^ starting here...
      10 | |     "Hello, world!"
      11 | | }
         | |_^ ...ending here

~~~
jtmarmon
that is some truly incredible developer ux

------
bfrog
Fantastic work! Taking full use of syntax extensions for code generation is a
clear winner in terms of dealing with what would normally end up being a bunch
of copy pasta code.

------
jonaf
edit: see replies to my comment. I mistook the Hyper pull request being merged
for being in the latest release, but it isn't.

Rocket uses Hyper for its HTTP server. So I checked to see if the Hyper HTTP
server was really production-ready. Particularly, if it could handle async IO
/ solve the C10K problem[0]. It looks like Hyper implemented async IO[1], so
it should be adequate for production use in this regard. This is great news
for users of Rocket because it means you don't need a separate HTTP framework
to run your web service, as you would with, say, Django + gunicorn.

Sure, it's a dependency, but in this case, having a production-ready HTTP
server out of the box is really nice!

Having said that, is there any literature on Rocket/hyper for security? The
production-ready HTTP server is great, but it also means it has to be prepared
to deal with certain security issues, like listening on 0.0.0.0 and handling
file uploads. You _could_ put HAproxy/nginx/whatever in front of it, but I
think Rust has the potential to supply / manage all of this within one unit
and simplify the stack / attack surface area.

[0]: [http://www.kegel.com/c10k.html](http://www.kegel.com/c10k.html)

[1]:
[https://github.com/hyperium/hyper/pull/778](https://github.com/hyperium/hyper/pull/778)

~~~
tatterdemalion
Hyper is not yet async, the preliminary work in the PR you linked to is for a
version which has not been pushed to crates.io and is not finished yet.

~~~
bbatha
Hyper 0.9 is async. It does not use futures/tokio ecosystem so it's ergonomics
are weak in places, particularly on the client side. I believe the tokio
branch of hyper is basically complete and only waiting on tokio to release.

------
chias
Being very excited about another Rust web framework, I've been trying to use
this for the last few days. While the basics seem very interesting, there's a
few large stumbling blocks ready for anyone who might want to "get serious"
with it.

Documentation is very sparse. Indeed, the linked to page seems to be the
primary documentation repository. This is particularly painful for a brand new
project, because googling is wholly useless at this point (the only relevant
results being the linked-to page). You can try to infer things from the API,
but there's a lot that I would refer to as "hidden gotchas" which you'll only
learn about through experimentation or by reading the source.

For example, consider the FromForm functionality. Does it decode url-encoded
values? Turns out the answer is: maybe. If your struct defines the field as a
String then the input will be url-decoded, but if you define the field as a
str then it won't be. FromForm only works at all if the submission is of
content-type 'application/x-www-form-urlencoded', failing entirely
'multipart/form-data' for example -- I have no idea how you're meant to go
about parsing a multipart form besides doing it manually using just the raw
post-data string as input. Also, good luck parsing anything with a checkbox
(as their code example does) -- if the checkbox is checked, no problem, the
field is populated with 'true'. But if the checkbox is left unchecked, then
you get a parse failure because you're "missing" a field. There may be a way
to work around this but if there is it isn't well documented and I haven't
read through that part of the rocket source yet.

------
jay-anderson
I didn't see it in the docs, but does there exist a concept similar to java's
servlet filters. For instance to check apikeys globally, perform compression,
input validation, etc. Really any common operation across multiple routes.

------
rubyfan
I suppose this an advance for those already using Rust but the core message on
the front page doesn't speak to me as a non-Rust person.

FTA: Rocket is a web framework for Rust that makes it simple to write fast web
applications _without sacrificing flexibility or type safety_. All with
minimal code.

I'm at a total loss for why I really care about this major part of their
message (type safety). If I have already switched to Rust then I care about
type safety already and you don't need to sell me on Rust, you should focus on
differentiating this web framework from the ones that came before it. But if I
haven't switched to Rust then I am essentially unswayed by their messaging. I
can't see why it's particularly important or different over other
language/frameworks for web development.

Before learning Ruby I watched the Rails blog video sometime around version
0.14.3. Immediately you could the value of the framework and the ease of a
language I was unfamiliar with. The win I could see was productivity and it
was enough for me and a lot of other people to learn Ruby. I don't see that
with this framework or really anything in the Rust world.

~~~
ekidd
> I'm at a total loss for why I really care about this major part of their
> message (type safety).

Honestly, you might not care about type safety. It depends a lot on the kinds
of programs you write.

In general, a language with a _good_ type system[1] brings several major
advantages to the table:

1\. If your program compiles, there's typically a 90% chance it will work
correctly on the first try, even if you just changed hundreds of lines of
code.

2\. Big refactorings are much less stressful.

3\. Emacs or Visual Studio Code (for example) can provide pop-up completions
of names and methods.

4\. Problems like mysterious nulls or data races can be prevented almost
entirely at compile time.

One big downside is that it gets harder to do certain kinds of (runtime)
metaprogramming and you need to use macros to get similar effects.

At this point, having worked professionally with Rust, I would recommend Rust
to people who are really enthusiastic about the above benefits. But if you
look at that list and say, "Meh, not worth it," then you might not want to
adopt a younger language like Rust. Well, unless you need to get reasonably
close to the metal without sacrificing safety, which is where Rust really
shines. I just wrote a fast CSV sanitizer in Rust for processing gigabytes of
input, and the compiler caught a subtle memory error when one CSV line spanned
two buffer reads.

[1] For the sake of argument, a "good" type system in this context includes
the ability to define custom collections with type parameters, it only allows
NULL to appear where explicitly permitted, and it supports tagged unions with
a nice "match" construct. This seems to be roughly the minimum feature set to
get the full effect described above. Examples include Haskell, Elm, Rust, ML
and (to a surprising extent) TypeScript.

~~~
chrismorgan
The state of completion in the JavaScript world is fairly impressive these
days, considering what it is.

------
aaron-lebo
It's my understanding that the current Rust web framework landscape is dealing
with moving over to futures (example:
[https://github.com/hyperium/hyper/issues/934](https://github.com/hyperium/hyper/issues/934)).

The framework seems to nail the API, but what's it doing down at the bottom of
the stack? Any benchmarks?

Apologies if they are somewhere obvious, but didn't see it on the site.

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

Today, it's built on top of hyper, which is still synchronous. It's also only
using the lowest parts of hyper, apparently.

There's a branch for tokio integration, but needs the tokio 0.1 release, which
is coming soon but not _quite_ out yet.

------
Manishearth
This looks very much like Flask, and Flask is one of my favorite ways of
writing webapps because it's just so easy to do the simple things.

~~~
ergo14
Flask still unfortunately uses globals everywhere :(

~~~
lukasm
What do you mean by globals?

~~~
fredsir
the ´g` object is one core item, for example.

------
sidlls
I'm not sure the syntax extension specific items are good if the intent is to
present this as an argument for moving to Rust from some other language for
building such a framework. I'm a bit biased: I'd avoid using syntax extensions
that aren't part of the standard, because it adds a point of friction for
novice and seasoned Rust developers alike.

~~~
adamnemecek
Are you talking about the route specification syntax? It doesn't seem much
worse than say flask.

~~~
sidlls
In this specific case, yes those particularly would be an example.

But I don't mean in comparison to other languages or frameworks, I mean in
generally, as in, I'd avoid creating syntax extensions or using them in any
project.

~~~
jtmarmon
i understand your argument but if you look at
<[https://news.ycombinator.com/item?id=13246361>](https://news.ycombinator.com/item?id=13246361>),
it seems clear to me the use of syntax extensions created an awesome developer
experience that would be otherwise impossible (sure you could use the built in
typesystem but then you wouldn't have human readable routes in the source)

------
FLUX-YOU
Just a comment on the pastebin example (
[https://rocket.rs/guide/pastebin/#uploading](https://rocket.rs/guide/pastebin/#uploading)
):

UUIDs seem like it would be easier to use for demonstration :
[https://doc.rust-lang.org/uuid/uuid/index.html](https://doc.rust-
lang.org/uuid/uuid/index.html)

And Cargo.toml declaration might need an extra sentence or two to explain the
"features" part but that shouldn't be too bad:

    
    
        [dependencies]
        uuid = { version = "*", features = ["v4"] }

------
kev009
This looks pretty nice, it reminds me of Play! framework for Scala. I am
curious to see if Rust or Swift will prevail for this kind of thing. Both have
the opportunity to reach fairly deep into systems programming all the way up
to UI and webapps.

------
callumjones
Unrelated to the project but to the website: when I opened this on Safari my
tab became consuming 52% CPU - is there something resource intensive on this
site? Safari points to the clouds being a source of a lot of work.

------
amelius
I'd like to use it, but I need a solution which allows to use the same
language on client and server.

~~~
chrismorgan
Wait for a few months and that will start to become viable, though it probably
won’t be _reasonable_ for two or three years.

Rust 1.14, released a couple of days ago, introduced experimental support for
WASM/asm.js backends. There are experiments like [https://github.com/tcr/rust-
todomvc](https://github.com/tcr/rust-todomvc) which show off the
possibilities. At the moment it produces a rather massive blob (over 1MB as
JavaScript, not sure as WASM), but that will improve, and for some situations
that doesn’t matter so much anyway.

------
bronz
as someone who knows nothing about web development, does this framework
emphasize security as much as rust itself does? how does this framework
compare to other rust web frameworks?

~~~
steveklabnik
This is still very much a 0.1 release. Two relevant bugs to your question:

[https://github.com/SergioBenitez/Rocket/issues/20](https://github.com/SergioBenitez/Rocket/issues/20)

[https://github.com/SergioBenitez/Rocket/issues/14](https://github.com/SergioBenitez/Rocket/issues/14)

------
nnutter
What color theme is that which is used in the code samples?

~~~
anonova
It seems to be Atom's One Dark: [https://github.com/atom/one-dark-
syntax](https://github.com/atom/one-dark-syntax)

------
Halienja
Very impressive. Certainly going to check it out soon.

------
dom0
Anyone up for writing a new web framework in another language called, say,
_artillery_? ;)

(The counter would be _missile_ , I guess, and then _icbm_... followed by
_planetary-defense-cannon_?)

------
architbhise
Incredible! I'm excited to use this.

------
wildchild
Single threaded? Why not use futures?

