11 releases

0.1.12 Oct 31, 2023
0.1.11 Oct 19, 2023
0.1.10 Sep 2, 2023
0.1.9 Aug 10, 2023
0.1.0 Aug 4, 2019

#164 in HTTP server

36 downloads per month

MIT license

335KB
633 lines

gotcha

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;

#[get("/")]
pub async fn hello_world() -> impl Responder {
    "hello world"
}

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

#[tokio::main]
async fn main() {
    GotchaCli::<_, Config>::new()
        .server(|config| async move {
            HttpServer::new(|| {
                App::new()
                    .into_gotcha()
                    .service(hello_world)
                    .data(config)
                    .done()
            })
            .bind(("127.0.0.1", 8080))
                .unwrap()
                .run()
                .await;
        })
        .run()
        .await
}

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 {
    #[domain(primary_key)]
    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 {
    
    #[sql(find)]
    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.

Dependencies

~23–38MB
~655K SLoC