You've successfully subscribed to Qoddi Blog
Great! Next, complete checkout for full access to Qoddi Blog
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.
Success! Your billing info is updated.
Billing info update failed.

Connect to Postgres from Rust with Actix and Diesel

Qoddi
Qoddi

Qoddi apps can communicate with each other inside the same stack using Qoddi's internal network capabilities: an ultra-fast internal network between apps installed inside the same cluster. In this tutorial, we will learn how to connect a Rust app to a Postgres database using Actix with Diesel

This post describes the creation of a Qoddi app along with a Postgres SQL, you can use an external database (like an AWS RDS database or a database located on another Qoddi cluster) using its web address.

This tutorial uses ENV variables to set and uses the database, you can connect to an external database by setting the DATABASE_URL ENV variable :

DATABASE_URL=postgres://[user]:[password]@[internal_name or URL]/database

Actix is a great RUST framework used to increase the capabilities of apps built on Rust.

Creating a REST API using RUST is simple. In this tutorial, we will use Diesel, an ORM, and Query builder, that simplifies the uses of databases inside a Rust project.

Prepare your app locally

You need to have Rust installed locally. Check this tutorial to install rustup to do that easily.
It will also install cargo, a package manager to manage rust projects. Simply run:

cargo new rust-actix-diesel-connect

This will create a new project called rust-actix-diesel-connect. Let’s update our Cargo.toml, add some dependencies:

[package]
name = "rust-actix-diesel-connect"
version = "0.1.0"
edition = "2018"
 
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
[dependencies]
actix-web = "3"
diesel = { version = "1.4.8", features = ["postgres", "r2d2",] }
dotenv = "0.15.0"
r2d2 = "0.8.9"

We are using Diesel ORM with postgres with the r2d2 feature enabled.

R2d2 has a ConnectionManager that can create a connection to a postgres database along with a database pool.

Now let's update src/main.rs with this code:

use actix_web::{ web, App, HttpServer, HttpResponse, Responder};
use dotenv::dotenv;
use std::env;
 
mod postgres;
 
async fn home() -> impl Responder {
   HttpResponse::Ok().body("PostgreSQL connected")
}
 
#[actix_web::main]
async fn main() -> std::io::Result<()> {
   dotenv().ok();
   env::set_var("RUST_LOG", "actix_web=debug");
   let host = env::var("HOST").expect("Host not set");
   let port = env::var("PORT").expect("Port not set");
 
   let pool = postgres::get_pool();
   HttpServer::new(move || {
       App::new()
       .data(pool.clone())
           .route("/", web::get().to(home))
          
   })
   .bind(format!("{}:{}", host, port))?
   .run()
   .await
}

Here we are using Actix, dotenv, and standard env library. We are also importing a module called Postgres and we will write our Postgres configuration there.

In the main function, we created a pool from the Postgres config and inserted that in our actix server data method.

Now, let’s create a postgres.rs file and write our postgres connection:

use diesel::pg::PgConnection;
use diesel::r2d2::ConnectionManager;
use dotenv::dotenv;
use r2d2::Pool;
use std::env;
 
// The Postgres-specific connection pool managing all database connections.
pub type PostgresPool = Pool<ConnectionManager<PgConnection>>;
 
pub fn get_pool() -> PostgresPool {
   // it from the environment within this function
   dotenv().ok();
   let url = env::var("DATABASE_URL").expect("no DB URL");
   let migr = ConnectionManager::<PgConnection>::new(url);
   r2d2::Pool::builder()
       .build(migr)
       .expect("could not build connection pool")
}

From r2d2 we import ConnectionManager and Pool and create a PostgresPool with it. Our get_pool function simply uses our environment variable DATABASE_URL and creates a new connection to our database.

Install diesel_cli locally with this command:

cargo install diesel_cli --no-default-features --features postgres

Add a Procfile to your project

Procfile is used to let the Qoddi orchestrator how to start and manage your app.  Check this tutorial for a more detailed Rust deployment.

For this app we simply need to add a Procfile to our root app folder with this command:

web: /workspaces/bin/rust-actix-diesel-connect

Once it's done, push your code to GitHub or any Git software.

Qoddi App with Postgres

Create a new Qoddi app and select Postgres as a datastore:

Connect your repository to Qoddi using the automatic or manual method. Check this tutorial for more information.

Once your app is built, the connection to the app is made automatically by the builder:


You can edit the DATABASE_URL env variable to connect to another database (external or internal to the same stack).

Code related to this tutorial can be found here.