1 unstable release

0.0.0 Jan 16, 2023

#120 in #server-framework

MIT license

5KB

aoi - Pre Development Draft

aoi - [葵] name of popular plant in Japan - is struct based web framework.
This is pre development draft.


Features

  • struct based architecture where a server is a struct
  • actively using macros

Examples ( under planning )

simple server

#[server]
MyServer {
    #[GET /]
    {
        self.OK("Hello!")
    }
}

#[main]
{
    let my_server = MyServer;
    bloom!(":3000", my_server)
}
$ curl http://localhost:3000
Hello!

handle db, path params, request body

struct User {
    id:   u64,
    name: String,
}

struct CreateUser {
    name:     String,
    password: String,
}

#[server]
UserServer {
    conn: ConnectionPool<Postgres>,
} {
    #[GET /api/users/{id:u64}]
    {
        let user = SQL![
            SELECT id, name FROM users
            WHERE id = $id
        ; as User]
            .fetch_one(&self.conn)
            .await?;

        self.OK(user)
    }

    #[POST /api/users, body: CreateUser]
    {
        let CreateUser { name, password } = body;

        let created_user = SQL![
            INSERT INTO users (name, password) VALUES ($name, $password)
            RETURNING id, name
        ; as User]
            .fetch_one(&self.conn)
            .await?;

        self.Created(created_user)
    }
}

#[main]
{
    let connection_pool = PgPoolOptions::new()
        .max_connections(5)
        .connect(
            "postgres://postgres:password@localhost/test"
        ).await?;

    let user_server = UserServer {
        conn: connection_pool,
    };

    bloom!(":8080", user_server)
}

nest servers

struct CreateUser {
    name:     String,
    password: String,
}

#[server]
RootServer {
    #[GET /]
    {
        self.OK("Hello!")
    }

    #[GET /health_check]
    {
        self.NoContent()
    }
}

#[server]
UserServer {
    conn: ConnectionPool<Postgres>,
} {
    #[GET /{id:u64}]
    {
        let user = SQL![
            SELECT id, name FROM users
            WHERE id = $id
        ; as User]
            .fetch_one(&self.conn)
            .await?;

        self.OK(user)
    }

    #[POST /, body: CreateUser]
    {
        let CreateUser { name, password } = body;

        let created_user = SQL![
            INSERT INTO users (name, password) VALUES ($name, $password)
            RETURNING id, name
        ; as User]
            .fetch_one(&self.conn)
            .await?;

        self.Created(created_user)
    }
}

#[main]
{
    let connection_pool = PgPoolOptions::new()
        .max_connections(5)
        .connect(
            "postgres://postgres:password@localhost/test"
        ).await?;

    let user_server = UserServer {
        conn: connection_pool,
    };

    let root_server = RootServer;

    bloom!(":8080",
        /api/users => user_server,
        / => root_server
    )
}

Dependencies

~1.5MB
~37K SLoC