Skip to content

Commit

Permalink
Merge pull request #375 from ohkami-rs/v0.23
Browse files Browse the repository at this point in the history
v0.23
  • Loading branch information
kanarus authored Feb 14, 2025
2 parents 6e243ac + 9a0219c commit 925df35
Show file tree
Hide file tree
Showing 54 changed files with 2,530 additions and 545 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ jobs:

strategy:
matrix:
toolchain: [stable, nightly]
toolchain: ['stable', 'nightly']
task: ['check', 'test:core', 'test:other', 'bench:dryrun']

steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -61,4 +62,4 @@ jobs:
- name: Run tasks
run: |
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin
task CI
task ${{ matrix.task }}
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ exclude = [
]

[workspace.package]
version = "0.22.0"
version = "0.23.0"
edition = "2021"
authors = ["kanarus <kanarus786@gmail.com>"]
homepage = "https://crates.io/crates/ohkami"
Expand Down
128 changes: 80 additions & 48 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@

- *macro-less and type-safe* APIs for intuitive and declarative code
- *various runtimes* are supported:`tokio`, `async-std`, `smol`, `nio`, `glommio` and `worker` (Cloudflare Workers), `lambda` (AWS Lambda)
- *extremely fast*[Web Frameworks Benchmark](https://web-frameworks-benchmark.netlify.app/result)
- no-network testing, well-structured middlewares, Server-Sent Events, WebSocket, OpenAPI document generation, ...
- extremely fast, no-network testing, well-structured middlewares, Server-Sent Events, WebSocket, highly integrated OpenAPI document generation, ...

<div align="right">
<a href="https://github.com/ohkami-rs/ohkami/blob/main/LICENSE"><img alt="License" src="https://img.shields.io/crates/l/ohkami.svg" /></a>
Expand All @@ -24,7 +23,7 @@

```toml
[dependencies]
ohkami = { version = "0.22", features = ["rt_tokio"] }
ohkami = { version = "0.23", features = ["rt_tokio"] }
tokio = { version = "1", features = ["full"] }
```

Expand Down Expand Up @@ -195,7 +194,7 @@ async fn main() {

`"openapi"` provides highly integrated OpenAPI support.

This enables *as consistent as possible* OpenAPI document generation, where most of the consistency between document and behavior is automatically assured by Ohkami's internal work.
This enables **macro-less**, *as consistent as possible* OpenAPI document generation, where most of the consistency between document and behavior is automatically assured by Ohkami's internal work.

Only you have to

Expand Down Expand Up @@ -284,48 +283,6 @@ async fn main() {

## Snippets

### Middlewares

Ohkami's request handling system is called "**fang**s", and middlewares are implemented on this.

*builtin fang* : `CORS`, `JWT`, `BasicAuth`, `Timeout`, `Context`

```rust,no_run
use ohkami::prelude::*;
#[derive(Clone)]
struct GreetingFang(usize);
/* utility trait; automatically impl `Fang` trait */
impl FangAction for GreetingFang {
async fn fore<'a>(&'a self, req: &'a mut Request) -> Result<(), Response> {
let Self(id) = self;
println!("[{id}] Welcome request!: {req:?}");
Ok(())
}
async fn back<'a>(&'a self, res: &'a mut Response) {
let Self(id) = self;
println!("[{id}] Go, response!: {res:?}");
}
}
#[tokio::main]
async fn main() {
Ohkami::new((
// register fangs to a Ohkami
GreetingFang(1),
"/hello"
.GET(|| async {"Hello, fangs!"})
.POST((
// register *local fangs* to a handler
GreetingFang(2),
|| async {"I'm `POST /hello`!"}
))
)).howl("localhost:3000").await
}
```

### Typed payload

*builtin payload* : `JSON`, `Text`, `HTML`, `URLEncoded`, `Multipart`
Expand Down Expand Up @@ -366,10 +323,10 @@ use ohkami::prelude::*;
#[tokio::main]
async fn main() {
Ohkami::new((
"/hello/:name"
.GET(hello),
"/hello/:name/:n"
.GET(hello_n),
"/hello/:name"
.GET(hello),
"/search"
.GET(search),
)).howl("localhost:5000").await
Expand Down Expand Up @@ -404,6 +361,81 @@ async fn search(
}
```

### Middlewares

Ohkami's request handling system is called "**fang**s", and middlewares are implemented on this.

*builtin fang* :

- `Context` *( typed interaction with reuqest context )*
- `CORS`, `JWT`, `BasicAuth`
- `Timeout` *( native runtime )*
- `Enamel` *( experimantal; security headers )*

```rust,no_run
use ohkami::prelude::*;
#[derive(Clone)]
struct GreetingFang(usize);
/* utility trait; automatically impl `Fang` trait */
impl FangAction for GreetingFang {
async fn fore<'a>(&'a self, req: &'a mut Request) -> Result<(), Response> {
let Self(id) = self;
println!("[{id}] Welcome request!: {req:?}");
Ok(())
}
async fn back<'a>(&'a self, res: &'a mut Response) {
let Self(id) = self;
println!("[{id}] Go, response!: {res:?}");
}
}
#[tokio::main]
async fn main() {
Ohkami::new((
// register fangs to a Ohkami
GreetingFang(1),
"/hello"
.GET(|| async {"Hello, fangs!"})
.POST((
// register *local fangs* to a handler
GreetingFang(2),
|| async {"I'm `POST /hello`!"}
))
)).howl("localhost:3000").await
}
```

### Database connection management with `Context`

```rust,no_run
use ohkami::prelude::*;
use ohkami::typed::status;
use sqlx::postgres::{PgPoolOptions, PgPool};
#[tokio::main]
async fn main() {
let pool = PgPoolOptions::new()
.connect("postgres://ohkami:password@localhost:5432/db").await
.expect("failed to connect");
Ohkami::new((
Context::new(pool),
"/users".POST(create_user),
)).howl("localhost:5050").await
}
async fn create_user(
Context(pool): Context<'_, PgPool>,
) -> status::Created {
//...
status::Created(())
}
```

### Static directory serving

```rust,no_run
Expand Down
14 changes: 10 additions & 4 deletions Taskfile.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,20 @@ tasks:

test:
deps:
- task: test:deps
- task: test:doc
- task: test:examples
- task: test:samples
- task: test:core
- task: test:other
test:core:
deps:
- task: test:no_rt
- for: [tokio, async-std, smol, nio, glommio, lambda, worker]
task: test:rt
vars: { rt: '{{.ITEM}}' }
test:other:
deps:
- task: test:deps
- task: test:doc
- task: test:examples
- task: test:samples

check:
deps:
Expand Down
12 changes: 8 additions & 4 deletions ohkami/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ features = ["rt_tokio", "nightly", "sse", "ws"]

[dependencies]
# workspace members
ohkami_lib = { version = "=0.22.0", path = "../ohkami_lib" }
ohkami_macros = { version = "=0.22.0", path = "../ohkami_macros" }
ohkami_openapi = { optional = true, version = "=0.22.0", path = "../ohkami_openapi" }
ohkami_lib = { version = "=0.23.0", path = "../ohkami_lib" }
ohkami_macros = { version = "=0.23.0", path = "../ohkami_macros" }
ohkami_openapi = { optional = true, version = "=0.23.0", path = "../ohkami_openapi" }

# workspace dependencies
byte_reader = { workspace = true }
Expand Down Expand Up @@ -107,4 +107,8 @@ DEBUG = ["tokio?/rt-multi-thread", "tokio?/macros"]
# #"rt_glommio",
# #"rt_worker",
# "DEBUG",
#]
#]


[dev-dependencies]
sqlx = { version = "0.8", features = ["runtime-tokio", "postgres"] }
3 changes: 3 additions & 0 deletions ohkami/src/fang/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ pub use jwt::{JWT, JWTToken};
mod context;
pub use context::Context;

pub mod enamel;
pub use enamel::Enamel;

#[cfg(feature="__rt_native__")]
mod timeout;
#[cfg(feature="__rt_native__")]
Expand Down
Loading

0 comments on commit 925df35

Please sign in to comment.