Skip to content

Commit

Permalink
Update README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
juhaku committed Jan 18, 2022
1 parent a13f66a commit 4b7dfb3
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 40 deletions.
168 changes: 156 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,178 @@
# utoipa - Autogenerate OpenAPI documentation

Want to document your utopic api? Want it to feel as fuzzy as cold ipa? You are then probably in need of utoipa.
Want to document your utopic api? Want it to feel as fuzzy as cold ipa? Then you are probably in need of utoipa.

Utoipa crate provides autogenerated OpenAPI documentation for Rust REST apis. It aims to ease out and simplify the
REST api documentation by using the code first aproach. It contains Rust implementation of OpenAPI spec and it allows
users to write their API code without feeling anxious of the documentation by doing the heavy lifting behind the scenes
with help of macros.
Utoipa crate provides autogenerated OpenAPI documentation for Rust REST APIs. It treats code first appoach as a
first class citizen and simplifies API documentation by providing simple macros for generating the
documentation from your code.

It also contains Rust types of OpenAPI spec allowing you to write the OpenAPI speck only using Rust as well if
autogeneration is not your flavor or does not fit your purpose.

In future there are plans to support more sophisticated code generation from generated OpenAPI spec and as well
to support contract first approach.

## Current project status

**This project is currently in active development and not ready for PRODUCTION use!**

It is yet to be released to crates later on when the api and the functionalities mature enough for wider scale adoption.
The reference implementation is almost there which enables people to play around with the library. It is yet to be released to crates later on when the api and the functionalities are mature enough for wider scale adoption.

See https://github.com/juhaku/utoipa/projects for more details about the progress of the project implementation.

## 30 sec Lesson

Create type for API. Crusial part is the `Component` derive which will create OpenAPI component for the struct or enum.
```rust
#[derive(Deserialize, Serialize, Component)]
struct Pet {
id: u64,
name: String,
age: Option<i32>,
}
```

Create your Get pet API.
```rust
mod pet_api {
/// Get pet by id
///
/// Get pet from database by pet database id
#[utoipa::path(
get,
path = "/pets/{id}"
responses = [
(status = 200, description = "Pet found succesfully", body = Pet),
(status = 404, description = "Pet was not found")
],
params = [
("id" = u64, path, description = "Pet database id to get Per for"),
]
)]
async fn get_pet_by_id(pet_id: u64) -> Pet {
Pet {
id: pet_id,
age: None,
name: "lightning".to_string(),
}
}
}
```

Tie the API and Component together with the `OpenApi` derive which will create OpenAPI api doc for you.
```rust
#[derive(OpenApi, Default)]
#[openapi(handlers = [pet_api::get_pet_by_id], components = [Pet])]
struct ApiDoc;

println!("{}", ApiDoc::openapi().to_pretty_json().unwrap());
```

This would produce api doc something similar to:
```json
{
"openapi": "3.0.3",
"info": {
"title": "application name from Cargo.toml",
"description": "description from Cargo.toml",
"contact": {
"name": "author name from Cargo.toml",
"email":"author email from Cargo.toml"
},
"licence": {
"name": "license from Cargo.toml"
},
"version": "version from Cargo.toml"
},
"paths": {
"/pets/{id}": {
"get": {
"tags": [
"pet_api"
],
"summary": "Get pet by id",
"description": "Get pet by id\n\nGet pet from database by pet database id\n",
"operationId": "get_pet_by_id",
"parameters": [
{
"name": "id",
"in": "path",
"description": "Pet database id to get Per for",
"required": true,
"deprecated": false,
"schema": {
"type": "integer",
"format": "int64"
}
}
],
"responses": {
"200": {
"description": "Pet found succesfully",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Pet"
}
}
}
},
"404": {
"description": "Pet was not found"
}
},
"deprecated": false
}
}
},
"components": {
"schemas": {
"Pet": {
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
},
"age": {
"type": "integer",
"format": "int32"
}
}
}
}
}
}
```

## Goals

Eeasy of use, and easy of development along with excessive cloning keeping perfomance in mind while developing
the library. It should follow the general rust quidelines and latest conventions of the Rust.

Goal|Status
-|-
Necessary subset implementation of OpenAPI spec in Rust| :heavy_minus_sign: Some definitions missing
Macros for autogenerating documentation | :x: In development and experiment
Macros for autogenerating documentation | :heavy_check_mark: Done, but some things missing
Embed Swagger UI for OpenAPI documentation | :heavy_check_mark: Done
Embed ReDocly for OpenAPI documentation | :x: Not done
Integration with Actix web framework | :x: In development
Integration with Actix web framework | :heavy_minus_sign: In development
Integration with Rocker framework | :x: Not done
Write exessive documentation & Book & Examples | :x: Not done
At least 90 % tested code | :x: Still ongoing along with the other development
At least 90 % tested code | :heavy_check_mark: Still ongoing along with the other development

Integration with other frameworks are not planned as of this stage but when the intial set of features are complete
the integrations with other frameworks can be prioritized.
Integration with other frameworks are not planned as of this stage but when the intial set of features are complete the integrations with other frameworks can be prioritized.

# License

Licensed under either of [Apache 2.0](LICENSE-APACHE) or [MIT](LICENSE-MIT) license at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, shall be dual licensed, without any additional terms or conditions.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate
by you, shall be dual licensed, without any additional terms or conditions.
56 changes: 28 additions & 28 deletions tests/utoipa_gen_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,43 @@ use serde_json::json;
use utoipa::{Component, OpenApi};

#[derive(Deserialize, Serialize, Component)]
struct Foo {
ids: Vec<i32>,
struct Pet {
id: u64,
name: String,
age: Option<i32>,
}

// mod api {
// use super::*;
mod pet_api {
use super::*;

/// Delete foo entity
///
/// Delete foo entity by what
#[utoipa::path(
request_body = (content = Foo, required, description = "foobar", content_type = "text/xml"),
responses = [
(status = 200, description = "success response", body = [Foo], headers = [("xrfs-token" = u64)])
// (400, "my bad error", u64),
// (404, "vault not found"),
// (500, "internal server error")
],
params = [
("ids" = [i32], query, description = "Search foos by ids"),
]
)]
#[get("/foo/{_:.*}")]
// #[deprecated = "this is deprecated"]
// web::Path(id): web::Path<i32>
async fn foo_delete(web::Query(foo): web::Query<Foo>) -> impl Responder {
let ids = foo.ids;
HttpResponse::Ok().json(json!({ "searched": ids }))
/// Get pet by id
///
/// Get pet from database by pet database id
#[utoipa::path(
get,
path = "/pets/{id}"
responses = [
(status = 200, description = "Pet found succesfully", body = Pet),
(status = 404, description = "Pet was not found")
],
params = [
("id" = u64, path, description = "Pet database id to get Per for"),
]
)]
async fn get_pet_by_id(pet_id: u64) -> Pet {
Pet {
id: pet_id,
age: None,
name: "lightning".to_string(),
}
}
}
// }

#[test]
#[ignore = "this is just a test bed to run macros"]
fn derive_openapi() {
// use crate::api::__path_foo_delete;
#[derive(OpenApi, Default)]
#[openapi(handlers = [foo_delete], components = [Foo])]
#[openapi(handlers = [pet_api::get_pet_by_id], components = [Pet])]
struct ApiDoc;

println!("{}", ApiDoc::openapi().to_pretty_json().unwrap());
Expand Down

0 comments on commit 4b7dfb3

Please sign in to comment.