This project is a basic template for actix-web
,
using sqlx
as database driver.
The template has already done these for you:
- Global configuration using
dotenvy
; - Supporting multiple data sources at the same time, including mock data;
- Initializing a basic server;
- Connecting to a database;
- Defining response structure;
- Showing some example services/apps;
- Supporting
Logger
;
The template uses JSON as response:
{
"success": true,
"data": {
"foo": "bar"
}
}
{
"success": false,
"err": "some error"
}
The template makes use of dotenvy
to manage environment variables:
# Unix systems
mv .env.example .env
And edit .env
file:
# Log level
RUST_LOG=debug
# To enable `Mock` data source:
# MOCK=1
MOCK=0
# Service
HOST="127.0.0.1"
PORT=8080
# Database
DB_HOST="localhost"
DB_USER="postgres"
DB_DATABASE="some_db"
DB_PASSWORD="PASSWORD"
use serde::Serialize;
use crate::response::{AppResponse, AppResult};
#[derive(Serialize)]
struct PingResponse {
msg: &'static str,
}
#[get("/ping")]
pub async fn ping() -> AppResult<PingResponse> {
AppResponse::Success(PingResponse { msg: "pong" }).response()
}
- 1st. Choose your data source:
// main.rs
impl AppState {
pub async fn new(config: &AppConfig) -> std::io::Result<AppState> {
let db = AppDB::postgres(&config).await?;
Ok(AppState { db })
}
}
- 2nd. Acquire your data:
// define the method yourself.
impl AppDB {
// give the result a type if you wish to use the data in your response
pub async fn test_db(&self) -> DBResult<()> {
match self {
Self::Postgres(pool) => { // pool is already `&Pool<Postgres>`
let row: (i64,) = sqlx::query_as("SELECT $1")
.bind(150_i64)
.fetch_one(pool)
.await?;
assert_eq!(row.0, 150);
Ok(())
}
// if you don't want to implement for other data sources:
_ => Err(DBError::Unimplemented),
}
}
}
- 3rd. Use the data in your response:
use serde::Serialize;
use crate::{
response::{AppResponse, AppResult},
AppState,
};
#[get("/db")]
pub async fn test_db(data: web::Data<AppState>) -> AppResult<&'static str> {
// or `let some_data = data.db.some_method(args).await?;`
data.db.test_db().await?;
AppResponse::Success("Test for db is success").response()
}