REST API with Rust & Mongodb

louis030195
4 min readOct 24, 2019

Rust is becoming popular for it’s performance and quality of code, some believe it could replace C++ which is “dying of ugliness”.

I was working on building a REST API with Rust and Mongodb and couldn’t find a decent tutorial so I decided to experiment and build one myself, I hope it will help other Rustaceans that were in the same case than me.

In this tutorial we will use:

In this tutorial we will assume that the reader is familiar with Rust and Linux, otherwise you should at least try the official Rust tutorial which is great, additionally you could quickly try the Rocket getting started.

First, let’s install VSCode, Rust and Mongodb

sudo apt update \
&& sudo apt install code \
&& curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh \
&& sudo apt install mongodb-org

Check that everything is alright

service mongodb status
You should have a similar output
which code \
&& which cargo \
&& which rustup

If you have any errors, google them ;)

Also, for Rocket you have to switch to nightly build:

rustup default nightly

Rustup is a version manager like Conda, Nvm … If you need to go back to stable replace nightly by stable in the previous command.

Be free to install Rust extensions on your VSCode, it helps a lot.

Create the Rust project

cargo new --name rustlang-rocket-mongodb
code rustlang-rocket-mongodb

You’ll notice a Cargo.toml file in your project, it contains the dependencies, as in other languages requirements.txt in Python, package.json in JavaScript …

Edit this file and add Rocket dependencies

[package]
name = "rustlang-rocket-mongodb"
version = "0.1.0"
[dependencies]
mongodb = "0.3.11"
dotenv = "0.13.0"
r2d2 = "0.8.3"
r2d2-mongodb = "*"
rocket = "0.4"
rocket_codegen = "0.4"
serde = { version = "1", features = ["derive"] }
serde_derive = "1"
serde_json = "1"
# Benches
criterion = "0.3"
[dependencies.rocket_contrib]
default-features = false
features = ["json"]
version = "0.4"
[[bench]]
name = "my_benchmark"
harness = false
  • dotenv is used to work with environment variables
  • r2d2 is used to hold pool of connections to database, useful if you want your app to scale (if you’re not familiar with pool design pattern you should google it, it’s often useful)
  • serde is used to serialize / deserialize JSON
  • criterion is an awesome benchmarking library for Rust

Optionally you can set “*” for the version, it will take the latest version but for this tutorial keep these versions or it may not work.

Now let’s edit the Rocket configuration file Rocket.toml:

[development]
address = "localhost"
port = 8001
workers = 8
log = "normal"
limits = { forms = 32768 }
[staging]
address = "0.0.0.0"
port = 80
workers = 8
log = "normal"
limits = { forms = 32768 }
[production]
address = "0.0.0.0"
port = 80
workers = 8
log = "critical"
limits = { forms = 32768 }

If you want to tweak these parameters check this page.

Play around with Rust, Rocket & Mongodb

In src/main.rs add

rustlang-rocket-mongodb/src/main.rs

Simple as hell :)

Now let’s build an app that store cats data in a database, our cats will have an id, name, color and age.

mkdir src/cats

We will first define their properties in src/cats/mod.rs

rustlang-rocket-mongodb/src/cats/mod.rs

Then we will write some CRUD functions for the model into src/cats/repository.rs

rustlang-rocket-mongodb/src/cats/repository.rs

Then we will write the API endpoints into src/cats/handler.rs

rustlang-rocket-mongodb/src/cats/handler.rs

Go back at src folder, we need to establish connection with mongo, which we will pass to each endpoints, create the file src/mongo_connection.rs

rustlang-rocket-mongodb/src/mongo_connection.rs

Now we need to run everything in a src/lib.rs, we expose the launching function to be available to tests

rustlang-rocket-mongodb/src/lib.rs

Let’s run the rocket function in src/main.rs replace everything by:

use rustlang_rocket_mongodb::rocket;fn main() {    rocket().launch();}

You can now run

cargo run
You should have a similar output

Extras

Now we will write some tests, if you want to tweak them see the Rocket guide.

rustlang-rocket-mongodb/tests/test.rs
# To avoid running parallel tests we use --test-threads=1 because we # modify database, otherwise tests would fail.cargo test -- --test-threads=1
You should have a similar output

The full code is available on Github

Let me know if there is some issues or questions :)

--

--