<h1 align="center">Poem OpenAPI</h1>
<p align="center">Fast and Type-Safe OpenAPI implementation for Poem.</p>
<div align="center">
<a href="https://crates.io/crates/poem-openapi">
<img src="https://img.shields.io/crates/v/poem-openapi.svg?style=flat-square"
alt="Crates.io version" />
</a>
<a href="https://crates.io/crates/poem-openapi">
<img src="https://img.shields.io/crates/d/poem-openapi.svg?style=flat-square"
alt="Download" />
</a>
<a href="https://docs.rs/poem-openapi">
<img src="https://img.shields.io/badge/docs-latest-blue.svg?style=flat-square"
alt="docs.rs docs" />
</a>
<a href="https://github.com/rust-secure-code/safety-dance/">
<img src="https://img.shields.io/badge/unsafe-forbidden-success.svg?style=flat-square"
alt="Unsafe Rust forbidden" />
</a>
<a href="https://blog.rust-lang.org/2023/11/16/Rust-1.81.0.html">
<img src="https://img.shields.io/badge/rustc-1.81.0+-ab6000.svg"
alt="rustc 1.81.0+" />
</a>
<a href="https://discord.gg/qWWNxwasb7">
<img src="https://img.shields.io/discord/932986985604333638.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2" />
</a>
</div>
***
`Poem-openapi` allows you to easily implement APIs that comply with the `OpenAPIv3` specification.
It uses procedural macros to generate a lots of boilerplate code, so that you only need to focus on the more
important business implementations.
* [Docs](https://docs.rs/poem-openapi)
* [Cargo package](https://crates.io/crates/poem-openapi)
## Features
* **Type safety** If your codes can be compiled, then it is fully compliant with the `OpenAPI v3` specification.
* **Rustfmt friendly** Do not create any DSL that does not conform to Rust's syntax specifications.
* **IDE friendly** Any code generated by the procedural macro will not be used directly.
* **Minimal overhead** All generated code is necessary, and there is almost no overhead.
## Crate features
To avoid compiling unused dependencies, Poem gates certain features, some of which are disabled by default:
| chrono | Integrate with the [`chrono` crate](https://crates.io/crates/chrono). |
| time | Integrate with the [`time` crate](https://crates.io/crates/time). |
| humantime | Integrate with the [`humantime` crate](https://crates.io/crates/humantime) |
| openapi-explorer | Add OpenAPI Explorer support |
| swagger-ui | Add swagger UI support |
| rapidoc | Add RapiDoc UI support |
| redoc | Add Redoc UI support |
| email | Support for email address string |
| hostname | Support for hostname string |
| uuid | Integrate with the [`uuid` crate](https://crates.io/crates/uuid) |
| url | Integrate with the [`url` crate](https://crates.io/crates/url) |
| geo | Integrate with the [`geo-types` crate](https://crates.io/crates/geo-types) |
| bson | Integrate with the [`bson` crate](https://crates.io/crates/bson) |
| rust_decimal | Integrate with the [`rust_decimal` crate](https://crates.io/crates/rust_decimal) |
| prost-wkt-types | Integrate with the [`prost-wkt-types` crate](https://crates.io/crates/prost-wkt-types) |
| static-files | Support for static file response |
| websocket | Support for websocket |
| sonic-rs | Uses [`sonic-rs`](https://github.com/cloudwego/sonic-rs) instead of `serde_json`. Pls, checkout `sonic-rs` requirements to properly enable `sonic-rs` capabilities |
## Safety
This crate uses `#![forbid(unsafe_code)]` to ensure everything is implemented in 100% Safe Rust.
## Example
```rust
use poem::{listener::TcpListener, Route};
use poem_openapi::{param::Query, payload::PlainText, OpenApi, OpenApiService};
struct Api;
#[OpenApi]
impl Api {
#[oai(path = "/hello", method = "get")]
async fn index(&self, name: Query<Option<String>>) -> PlainText<String> {
match name.0 {
Some(name) => PlainText(format!("hello, {}!", name)),
None => PlainText("hello!".to_string()),
}
}
}
#[tokio::main]
async fn main() -> Result<(), std::io::Error> {
let api_service =
OpenApiService::new(Api, "Hello World", "1.0").server("http://localhost:3000/api");
let ui = api_service.swagger_ui();
let app = Route::new().nest("/api", api_service).nest("/", ui);
poem::Server::new(TcpListener::bind("0.0.0.0:3000"))
.run(app)
.await
}
```
This feature needs to be opted-in. It can be done by adding the feature in `Cargo.toml` file
```toml filename=Cargo.toml
[dependencies]
poem = "3"
poem-openapi = { version = "5", features = ["swagger-ui"]}
tokio = { version = "1", features = ["full"] }
```
## Run example
Open `http://localhost:3000/` in your browser, you will see the `Swagger UI` that contains these API definitions.
```shell
> cargo run --example hello_world
> curl http://localhost:3000/api/hello
hello!
> curl http://localhost:3000/api/hello?name=sunli
hello, sunli!
```
## MSRV
The minimum supported Rust version for this crate is `1.81.0`.
## Contributing
:balloon: Thanks for your help improving the project! We are so happy to have you!
## License
Licensed under either of
* Apache License, Version 2.0,([LICENSE-APACHE](./LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](./LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Poem by you, shall be licensed as Apache, without any additional terms or conditions.