Logo

dev-resources.site

for different kinds of informations.

Building a Clean Architecture with Rust's Rocket and sqlx

Published at
9/25/2023
Categories
rust
rocket
sqlx
cleanarchitecture
Author
edo1z
Author
5 person written this
edo1z
open
Building a Clean Architecture with Rust's Rocket and sqlx

I tried my best to create a clean architecture with Rust Rocket and sqlx.
I tried my best to create a state that is easy to test and mock, while also separating modules in a nice way.

We've done something similar before at Axum

I used to try to do the same thing with Axum. The repository with the highest number of stars in my history is below.

GitHub logo edo1z / rust-axum-sqlx-sample

Rust Axum+SQLx Sample




The version of Axum in this repository is already quite old, so I think the whole thing needs to be modified if you try to do it now. Also, use_case is not a Trait, so it may be difficult to create mocks.

However, the code is rather simple (in my opinion), so I think it is good in terms of simplicity.

However, the DB Pool is passed to the repository, so each time a function in the repository is executed, it gets a connection from the Pool. I wonder if this is the difference between this version of Rocket and the current version.

I wonder if getting and destroying a connection every time a function is executed is relatively inefficient compared to continuing to use the same connection for a single request. (I have not measured this, but I asked ChatGPT and they said yes. I think it is basically impossible (and complicated) to do things such as crossing multiple repositories or waiting for a response from an external service before committing.

Repository of the Rocket version we made this time

The repository of this Rocket version is below. Please star it if you like!

GitHub logo edo1z / rust-rocket-sqlx-sample

A clean architecture style Sample using Rust's Rocket, sqlx and PostgreSQL.

rust-rocket-sqlx-sample

GitHub GitHub code size in bytes GitHub last commit (by committer) X (formerly Twitter) Follow

A clean architecture style Sample using Rust's Rocket(v0.5), sqlx(v0.6) and PostgreSQL.

How to Use

git clone https://github.com/net3i/rust-rocket-sqlx-sample
cd rust-rocket-sqlx-sample
docker-compose up -d
cp .env.example .env
sh migrate.sh
cargo test -- --test-threads=1
cargo run
Enter fullscreen mode Exit fullscreen mode

Overview of how it works

Use Rocket's rocket_db_pools to retrieve DB Pool connections from Controller arguments. This is passed as an argument to use_case, which passes the connection as an argument to each function in the repository. Only one connection is used per request, and it is returned to the Pool as soon as the request is processed.

Mocking

Since use_case and repository are Trait, mock can be easily created by mockall when testing.

DB Transaction

DB transactions are basically assumed to be used only within each function of repository, but transactions can be generated from DB Pool connections on the use_case side if necessary. However, since the functions in repository do not accept…

Features

  • Both use_case and repository are Trait, so it is easier to create mocks.
  • The repository functions are now passed only references to connections obtained from the DB Pool, which I think is a bit more efficient than the Axum version above. I think it is a little more efficient than the Axum version above.
    • A connection is obtained from the Pool for each request, and that connection is used throughout the same request. The connection is returned (discarded) when the request is finished.
  • Since the connection is passed to each function of repository, it is possible to create a transaction on the use_case side and have it commit after multiple repository functions are executed, if you want to do so.
  • It is easy to do controller, use_case, and repository (integration test).

Points that annoyed me

  • Transaction handling
    • Transaction and PoolConnection, it was difficult to use mockall.automock while using a repository function that can receive both (I eventually stopped using a function that can receive both).
    • As a result of the above, I can no longer use Transaction's Rollback to clear the table state when testing repository. (I now truncate before testing).
  • Compared to the Axum version, the code around DB connection is a little less simple.
    • But it is inefficient to pass a Pool to a function, and it is difficult to use transactions, so I thought it was good.

What I want to do in the future

  • I would like to introduce SeaORM.
  • I want to make it easy to use transactions in testing.
  • Currently, Rocket's sqlx is 0.6, but SeaORM is 0.7. Maybe we will stop using Rocket's db related libraries.

Summary

  • I thought Axum and Rocket were nice.
  • I thought it was transaction complicated.
  • Please star repository if you like!
cleanarchitecture Article's
30 articles in total
Favicon
Unit Testing Clean Architecture Use Cases
Favicon
The best way of implementing Domain-driven design, Clean Architecture, and CQRS
Favicon
Microservices Clean Architecture: Key Design Points and Migration Strategies
Favicon
Code Speaks for Itself: Métodos Bem Escritos Dispensam Comentários
Favicon
Clean Architecture: The Missing Chapter
Favicon
Framework agnostic Avatar component
Favicon
Usecase: TumbleLog
Favicon
Understanding Clean Architecture Principles
Favicon
1 - Clean Architecture: A Simpler Approach to Software Design
Favicon
Clean Architecture Demystified: A Practical Guide for Software Developers
Favicon
Screaming Architecture
Favicon
Registro 002 - Organizando el Código: Clean Architecture en Acción para tu Proyecto Flutter
Favicon
Your Laravel application with Repository doesn't make any sense
Favicon
Small Clean Application
Favicon
Building Your First Use Case With Clean Architecture
Favicon
Introduction to the principles of clean architecture in a NodeJs API (Express)
Favicon
Demystifying Clean Architecture: Fundamentals and Benefits
Favicon
Clean Architecture no NestJS 🏛️🚀
Favicon
Finding the Right Balance: Clean Architecture and Entity Framework in Practice
Favicon
Decoupling Dependencies in Clean Architecture: A Practical Guide
Favicon
Kotlin Clean Architecture and CQRS 🚀👋👨‍💻
Favicon
Don't go all-in Clean Architecture: An alternative for NestJS applications
Favicon
Fundamentals of Clean Architecture
Favicon
#4 Estudos: Explorando a Evolução das Arquiteturas de Software
Favicon
#3 Estudos: Arquitetura Limpa
Favicon
#1 Estudos: Arquitetura Limpa
Favicon
Além dos Templates: Uma Crítica Construtiva à Arquitetura Limpa e a Adaptação Pragmática no Design de Software
Favicon
Screaming Architecture
Favicon
Building a Clean Architecture with Rust's Rocket and sqlx
Favicon
Unveiling the essence of Clean Architectures 🫣

Featured ones: