<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/2021/07/29/Rust-1.54.0.html">
<img src="https://img.shields.io/badge/rustc-1.54+-ab6000.svg"
alt="rustc 1.54+" />
</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.
* [Book](https://poem-web.github.io/poem/)
* [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, all of which are disabled by default:
|chrono | Integrate with the [`chrono` crate](https://crates.io/crates/chrono). |
## Example
```rust
use poem::{listener::TcpListener, route};
use poem_openapi::{payload::PlainText, OpenApi, OpenApiService};
struct Api;
#[OpenApi]
impl Api {
#[oai(path = "/hello", method = "get")]
async fn index(
&self,
#[oai(name = "name", in = "query")] name: Option<String>,
) -> PlainText<String> {
match name {
Some(name) => PlainText(format!("hello, {}!", name)),
None => PlainText("hello!".to_string()),
}
}
}
#[tokio::main]
async fn main() -> Result<(), std::io::Error> {
let listener = TcpListener::bind("127.0.0.1:3000");
let api_service = OpenApiService::new(Api)
.title("Hello World")
.server("http://localhost:3000/api");
let ui = api_service.swagger_ui("http://localhost:3000");
poem::Server::new(listener)
.await?
.run(route().nest("/api", api_service).nest("/", ui))
.await
}
```
## Run example
Open `http://localhost:3000/ui` in your browser, you will see the `Swagger UI` that contains these API definitions.
```shell
> cargo run --example hello_world
> curl http://localhost:3000
hello!
> curl http://localhost:3000\?name\=sunli
hello, sunli!
```