This will let you have just one [dependencies] block, which is a bit nicer looking. I've been changing examples to use it instead of that older style; they're equivalent if you prefer it though.
(Life will be easier for you in future if you avoid * constraints, by using things like `router = "0.1"` instead. This means authors can make breaking changes to their crates without breaking you, e.g. router might make a major change and release 0.2.0, but you'll still be able to run `cargo update` without risking picking that up.)
For many projects (that aren't depended on by other projects), adding versions in Cargo.toml is just more work without payoff. Specifically, if one is already shipping Cargo.lock (in a way that it is used), `cargo update --precise` (in some form) allows the same granular control.
I'd also note that while theoretically restricting versions works, in practice having multiple versions of a single crate within a rust project often leads to build failures due to crate A having a public API that uses types from crate B, and crate C using both, but not getting the same version of B that A got. This leads to type errors at build time.
With `cargo add` its even easier than adding them with "*" dependencies. Just `cargo install cargo-extras` to get `cargo add`, and then `cargo add my_dependency` and it will add the dependency with the most recent version as the requirement.
Yeah, the Cargo.lock file means that * constraints aren't a problem until you need to update a library, e.g. to get an emergency bug fix. And, you are right that cargo update's --precise option allows manually getting the same benefits of explicit requirements, but even doing this once seems like more work than just including the right version, especially with the risk of `update`ing wrong (although, again, Cargo.lock can save you here, if you're tracking it in version control). The combination of `cargo search` (built-in) and `cargo add` (external, others have linked it) makes it pretty easy to just add the right versions at the outset.
> I'd also note that while theoretically restricting versions works, in practice having multiple versions of a single crate within a rust project often leads to build failures due to crate A having a public API that uses types from crate B, and crate C using both, but not getting the same version of B that A got. This leads to type errors at build time.
This is a problem, yes, but focusing on it by itself is somewhat of a red-herring: if A doesn't restrict B's version there's no guarantee that A compiles against whatever version of B that happens to be chosen, i.e. you don't even get to the point where there could be problematic interactions.
In any case, there has been serious discussion about how cargo can solve the problem of crates exposing other crates in their API, and the current proposed solution is to make cargo more strict about allowing multiple versions of such crates. #2064 is the relevant issue.
I use Rust for web as REST API and I'm absolutely in love with this language. Maybe first steps were little bit steep, but it's worth it :)
// cargo run!