This repository contains an application template built using Axum and PostgreSQL. It serves as a starting point for creating a new Axum server.
Inspired by Zero To Production In Rust and realworld-axum-sqlx.
The full list of crates used can be found in the Cargo.toml file. However, here are some key ones:
- Axum - A user-friendly, modular web framework built with Tokio, Tower, and Hyper.
- Sqlx - An asynchronous, pure Rust SQL crate that supports compile-time checked queries without a DSL. It supports PostgreSQL, MySQL, SQLite, and MSSQL.
- Tracing - A framework for instrumenting Rust programs to collect structured, event-based diagnostic information.
- Chrono - A comprehensive Date and Time library for Rust.
- Serde - A framework for efficiently and generically serializing and deserializing Rust data structures.
- Uuid - A library for generating and parsing UUIDs.
To begin with this project:
SQLx offers a command-line tool for creating and managing databases as well as migrations. It is available on the Cargo crates registry as sqlx-cli and can be installed as follows:
$ cargo install sqlx-cli --features postgresThe most straightforward way to run Postgres is by using a container with a pre-built image. The command below will start latest version of Postgres using Docker:
$ docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=password postgres$ git clone https://github.com/koskeller/axum-postgres-template
$ cd axum-postgres-templateThe backend application is preferably configured via environment variables. To simplify the process during development, we can use .env files to avoid defining the variables each time. As a starting point, you can simply copy the sample .env file in this repo and modify the .env file as per the comments therein.
$ cp .env.sample .envWith sqlx-cli installed and your .env file set up, you only need to run the following command to prepare the Postgres database for use:
$ sqlx db setupTo avoid the need of having a development database around to compile the project even when no modifications (to the database-accessing parts of the code) are done, this projects enables "offline mode" to cache the results of the SQL query analysis using the sqlx command-line tool. See sqlx-cli/README.md for more details.
$ cargo sqlx prepareWith everything else set up, all you need to do now is:
$ cargo runTo start the server and autoreload on code changes:
$ cargo install cargo-watch
$ cargo watch -q -x runTo format .json logs using jq:
$ cargo watch -q -x run | jq .#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ExampleReq {
pub input: String,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ExampleResp {
pub output: String,
}
pub async fn example(
State(state): State<AppState>,
req: Result<Json<ExampleReq>, JsonRejection>,
) -> Result<Json<ExampleResp>, ApiError> {
// Returns ApiError::InvalidJsonBody if the Axum built-in extractor
// returns an error.
let Json(req) = req?;
// Proceed with additional validation.
if req.input.is_empty() {
return Err(ApiError::InvalidRequest(
"'input' should not be empty".to_string(),
));
}
// Anyhow errors are by default converted into ApiError::InternalError and assigned a 500 HTTP status code.
let data: anyhow::Result<()> = Err(anyhow!("Some internal error"));
let data = data?;
let resp = ExampleResp {
output: "hello".to_string(),
};
Ok(Json(resp))
}Contributions are always welcome! Feel free to check the current issues in this repository for tasks that need attention. If you find something missing or that could be improved, please open a new issue.