10 releases

0.1.9 Mar 11, 2024
0.1.8 Oct 7, 2023
0.1.2 Feb 20, 2023
0.1.0 Jan 15, 2023

#1313 in Procedural macros

30 downloads per month
Used in conservator

MIT license

626 lines


provide a featured web framework

aim to

  • everything of actix-web
  • automatically swagger api generation
  • built-in message mechanism
  • environment based configuration system, support environment resolver ${ANY_ENV_VAR} and path variable ${app.database.name} powered by yaac
  • logging system
  • opt-in prometheus integration
  • sqlx based magic ORM
  • cron-based task system

get started

add dependency into Cargo.toml

gotcha = {version = "0.1"}
tokio = {version = "1", features = ["macros", 'rt-multi-thread']}
serde = {version="1", features=["derive"]}
use gotcha::{get, App, GotchaAppWrapperExt, GotchaCli, HttpServer, Responder};
use serde::Deserialize;

pub async fn hello_world() -> impl Responder {
    "hello world"

#[derive(Debug, Deserialize, Clone)]
struct Config {}

async fn main() {
    GotchaCli::<_, Config>::new()
        .server(|config| async move {
            HttpServer::new(|| {
            .bind(("", 8080))

Conservator ORM

Conservator ORM is based on sqlx, currently it only support postgres

#[derive(Debug, Deserialize, Serialize, Domain, FromRow)]
#[domain(table = "users")]
pub struct UserDomain {
    pub id: Uuid,
    pub username: String,
    pub email: String,
    pub password: String,
    pub role: UserRole,
    pub create_at: DateTime<Utc>,
    pub last_login_at: DateTime<Utc>,

the struct derived Domain would auto generate methods like:

  • find_by_id return optional entity
  • fetch_one_by_id return entity or raise
  • fetch_all return all entities
  • create passing the Createable to insert into table
#[derive(Debug, Deserialize, Serialize, Creatable)]
pub struct NewUser {
    pub username: String,
    pub email: String,
    pub password: String,

Createable means it can be executed by magic ORM, using UserDomain::create(NewUser{...}) to create a new user into user table.

#[sql] aslo provide some convinent way to write customized sql query

use conservator::sql;

impl UserService {
    pub async fn find_user<E>(email: &str, executor: E) -> Result<Option<UserEntity>, Error> {
        "select * from users where email = :email"

notice that, rather than sqlx's $1, we use param :email in sql, it can be used in native sql execution tools as well without any modification, like IDEA.


~110K SLoC