Skip to content

Commit

Permalink
Update docs for Swagger UI (#90)
Browse files Browse the repository at this point in the history
* Update docs for Swagger UI about rocket
* Update docs for utoipa path attribute macro about **actix_extras** and **rocket_extras**
  • Loading branch information
juhaku authored Apr 18, 2022
1 parent 96e0228 commit 53d743e
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 57 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,5 @@ jobs:
elif [[ "${{ matrix.testset }}" == "utoipa-gen" ]] && [[ ${{ steps.changes.outputs.gen_changed }} == true ]]; then
cargo test -p utoipa-gen --features actix_extras
elif [[ "${{ matrix.testset }}" == "utoipa-swagger-ui" ]] && [[ ${{ steps.changes.outputs.swagger_changed }} == true ]]; then
cargo test -p utoipa-swagger-ui --features actix-web
cargo test -p utoipa-swagger-ui --features actix-web,rocket
fi
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ Existing [examples](./examples) for following frameworks:
* **actix-web**
* **warp**
* **tide**

**actix-web** has support support for actix specific parsing via **actix_extras** feature.
* **rocket**

Even if there is no example for your favourite framework `utoipa` can be used with any
web framework which supports decorating functions with macros similarly to **warp** and **tide** examples.
Expand All @@ -49,10 +48,11 @@ and the `ipa` is _api_ reversed. Aaand... `ipa` is also awesome type of beer :be
enabled by default.
* **yaml** Enables **serde_yaml** serialization of OpenApi objects.
* **actix_extras** Enhances [actix-web](https://github.com/actix/actix-web/) intgration with being able to
parse `path` and `path parameters` from actix web path attribute macros. See the
[path attribute macro](https://docs.rs/utoipa/0.1.2/utoipa/attr.path.html) for more details.
parse `path` and `path parameters` from actix web path attribute macros. See
[docs](https://docs.rs/utoipa/0.1.2/utoipa/attr.path.html#actix_extras-support-for-actix-web) or [examples](./examples) for more details.
* **rocket_extras** Enhances [rocket](https://github.com/SergioBenitez/Rocket) framework integration with being
able to parse `path`, `path and query parameters` from rocket path attribute macros.
able to parse `path`, `path and query parameters` from rocket path attribute macros. See [docs](https://docs.rs/utoipa/0.1.2/utoipa/attr.path.html#rocket_extras-support-for-rocket)
or [examples](./examples) for more details.
* **debug** Add extra traits such as debug traits to openapi definitions and elsewhere.
* **chrono_types** Add support for [chrono](https://crates.io/crates/chrono) `DateTime`, `Date` and `Duration` types. By default these types
are parsed to `string` types without additional format. If you want to have formats added to the types
Expand Down
12 changes: 7 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@
//! * **actix-web**
//! * **warp**
//! * **tide**
//!
//! **actix-web** has support support for actix specific parsing via **actix_extras** feature.
//! * **rocket**
//!
//! Even if there is no example for your favourite framework `utoipa` can be used with any
//! web framework which supports decorating functions with macros similarly to **warp** and **tide** examples.
Expand All @@ -46,10 +45,11 @@
//! This is enabled by default.
//! * **yaml** Enables **serde_yaml** serialization of OpenApi objects.
//! * **actix_extras** Enhances [actix-web](https://github.com/actix/actix-web/) intgration with being able to
//! parse `path` and `path parameters` from actix web path attribute macros. See [`utoipa::path(...)`][path]
//! for more details.
//! parse `path` and `path parameters` from actix web path attribute macros. See [actix extras support][actix_path] or
//! [examples](https://github.com/juhaku/utoipa/tree/master/examples) for more details.
//! * **rocket_extras** Enhances [rocket](https://github.com/SergioBenitez/Rocket) framework integration with being
//! able to parse `path`, `path and query parameters` from rocket path attribute macros.
//! able to parse `path`, `path and query parameters` from rocket path attribute macros. See [rocket extras support][rocket_path]
//! or [examples](https://github.com/juhaku/utoipa/tree/master/examples) for more details
//! * **debug** Add extra traits such as debug traits to openapi definitions and elsewhere.
//! * **chrono_types** Add support for [chrono](https://crates.io/crates/chrono) `DateTime`, `Date` and `Duration` types. By default these types
//! are parsed to `string` types without
Expand Down Expand Up @@ -188,6 +188,8 @@
//! * More about OpenAPI security in [security documentation][security].
//!
//! [path]: attr.path.html
//! [rocket_path]: attr.path.html#rocket_extras-support-for-rocket
//! [actix_path]: attr.path.html#actix_extras-support-for-actix-web
//!
//! [security]: openapi/security/index.html
//! [component_derive]: derive.Component.html
Expand Down
97 changes: 59 additions & 38 deletions utoipa-gen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,65 @@ pub fn derive_component(input: TokenStream) -> TokenStream {
/// Leaving empty _`()`_ creates an empty [`SecurityRequirement`][security] this is useful when
/// security requirement is optional for operation.
///
/// # actix_extras support for actix-web
///
/// **actix_extas** feature gives **utoipa** ability to use **actix-web** path operation macros such as `#[get(...)]` to
/// resolve path for `#[utoipa::path]`. Also it is able to parse the the `path` parameters with types from function arguments
/// of operation which are defined within type `web::Path<...>`. Allowing you leave out types of parameters in `params(...)`
/// section of even leave out the section if description is not needed for parameters. Utoipa is only able to resolve
/// [primitive types][primitive] and [`String`] type. Using other types is undefined behaviour.
///
/// See the **actix_extras** in action in examples [todo-actix](https://github.com/juhaku/utoipa/tree/master/examples/todo-actix).
///
/// With **actix_extras** feature enabled the you can leave out definitions for **path**, **operation** and **parmater types** [^actix_extras].
/// ```rust
/// use actix_web::{get, web, HttpResponse, Responder};
/// use serde_json::json;
///
/// /// Get Pet by id
/// #[utoipa::path(
/// responses(
/// (status = 200, description = "Pet found from database")
/// ),
/// params(
/// ("id", description = "Pet id"),
/// )
/// )]
/// #[get("/pet/{id}")]
/// async fn get_pet_by_id(id: web::Path<i32>) -> impl Responder {
/// HttpResponse::Ok().json(json!({ "pet": format!("{:?}", &id.into_inner()) }))
/// }
/// ```
///
/// With **actix_extras** you may also not to list any _**parmas**_ if you do not want to specify any description for them. Params are resolved from
/// path and the argument types of handler. [^actix_extras]
/// ```rust
/// use actix_web::{get, web, HttpResponse, Responder};
/// use serde_json::json;
///
/// /// Get Pet by id
/// #[utoipa::path(
/// responses(
/// (status = 200, description = "Pet found from database")
/// )
/// )]
/// #[get("/pet/{id}")]
/// async fn get_pet_by_id(id: web::Path<i32>) -> impl Responder {
/// HttpResponse::Ok().json(json!({ "pet": format!("{:?}", &id.into_inner()) }))
/// }
/// ```
///
/// # rocket_extras support for rocket
///
/// **rocket_extras** feature give **utoipa** ability to use **rocket** path operation macros such as `#[get(...)]` to
/// resolve path for `#[utoipa::path]`. Also it is able to parse the `path` and `query` parameters from path operation macro
/// combined with function arguments of the operation. Allowing you leave out types from parameters in `params(...)` section
/// or even leave out the section if description is not needed for parameters. Utoipa is only able to parse parameter types
/// for [primitive types][primitive], [`String`], [`Vec`], [`Option`] or [`std::path::PathBuf`] type. Other function arguments are
/// simply ignored.
///
/// See the **rocket_extras** in action in examples [rocket-todo](https://github.com/juhaku/utoipa/tree/master/examples/rocket-todo).
///
/// # Examples
///
/// Example with all possible arguments.
Expand Down Expand Up @@ -456,44 +515,6 @@ pub fn derive_component(input: TokenStream) -> TokenStream {
/// }
/// ```
///
/// With **actix_extras** feature enabled the you can leave out definitions for **path**, **operation** and **parmater types** [^actix_extras].
/// ```rust
/// use actix_web::{get, web, HttpResponse, Responder};
/// use serde_json::json;
///
/// /// Get Pet by id
/// #[utoipa::path(
/// responses(
/// (status = 200, description = "Pet found from database")
/// ),
/// params(
/// ("id", description = "Pet id"),
/// )
/// )]
/// #[get("/pet/{id}")]
/// async fn get_pet_by_id(id: web::Path<i32>) -> impl Responder {
/// HttpResponse::Ok().json(json!({ "pet": format!("{:?}", &id.into_inner()) }))
/// }
/// ```
///
/// With **actix_extras** you may also not to list any _**parmas**_ if you do not want to specify any description for them. Params are resolved from
/// path and the argument types of handler.
/// ```rust
/// use actix_web::{get, web, HttpResponse, Responder};
/// use serde_json::json;
///
/// /// Get Pet by id
/// #[utoipa::path(
/// responses(
/// (status = 200, description = "Pet found from database")
/// )
/// )]
/// #[get("/pet/{id}")]
/// async fn get_pet_by_id(id: web::Path<i32>) -> impl Responder {
/// HttpResponse::Ok().json(json!({ "pet": format!("{:?}", &id.into_inner()) }))
/// }
/// ```
///
/// Use of Rust's own `#[deprecated]` attribute will refect to the generated OpenAPI spec and mark this operation as deprecated.
/// ```rust
/// # use actix_web::{get, web, HttpResponse, Responder};
Expand Down
2 changes: 1 addition & 1 deletion utoipa-swagger-ui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ rocket = { version = "0.5.0-rc.1", features = ["json"], optional = true }
utoipa = { version = "0.1", path = "..", default-features = false, features = [] }

[package.metadata.docs.rs]
features = ["actix-web"]
features = ["actix-web", "rocket"]

[build-dependencies]
zip = "0.6"
16 changes: 16 additions & 0 deletions utoipa-swagger-ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ works as a bridge for serving the OpenAPI documetation created with
**Currently implemented boiler plate for:**

* **actix-web** `version >= 4`
* **rocket** `version >=0.5.0-rc.1`

Serving Swagger UI is framework independant thus this crate also supports serving the Swagger UI with
other frameworks as well. With other frameworks there is bit more manual implementation to be done. See
Expand All @@ -21,6 +22,8 @@ more details at [serve](https://docs.rs/utoipa-swagger-ui/0.2.0/utoipa_swagger_u

* **actix-web** Enables actix-web integration with pre-configured SwaggerUI service factory allowing
users to use the Swagger UI without a hazzle.
* **rocket** Enables rocket integration with with pre-configured routes for serving the Swagger UI
and api doc without a hazzle.

# Install

Expand Down Expand Up @@ -54,6 +57,19 @@ HttpServer::new(move || {
```
**actix-web** feature need to be enabled.

Serve Swagger UI with api doc via rocket.
```rust
#[rocket::launch]
fn rocket() -> Rocket<Build> {
rocket::build()
.mount(
"/",
SwaggerUi::new("/swagger-ui/<_..>").url("/api-doc/openapi.json", ApiDoc::openapi()),
)
}
```
**rocket** feature need to be enabled.

# License

Licensed under either of [Apache 2.0](LICENSE-APACHE) or [MIT](LICENSE-MIT) license at your option.
Expand Down
41 changes: 34 additions & 7 deletions utoipa-swagger-ui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//! **Currently implemented boiler plate for:**
//!
//! * **actix-web**
//! * **rocket** `version >=0.5.0-rc.1`
//!
//! Serving Swagger UI is framework independant thus this crate also supports serving the Swagger UI with
//! other frameworks as well. With other frameworks there is bit more manual implementation to be done. See
Expand All @@ -18,6 +19,8 @@
//!
//! * **actix-web** Enables actix-web integration with pre-configured SwaggerUI service factory allowing
//! users to use the Swagger UI without a hazzle.
//! * **rocket** Enables rocket integration with with pre-configured routes for serving the Swagger UI
//! and api doc without a hazzle.
//!
//! # Install
//!
Expand Down Expand Up @@ -56,24 +59,48 @@
//! .bind((Ipv4Addr::UNSPECIFIED, 8989)).unwrap()
//! .run();
//! ```
//!
//! Serve Swagger UI with api doc via rocket [^rocket]
//! ```no_run
//! # use rocket::{Build, Rocket};
//! # use utoipa_swagger_ui::SwaggerUi;
//! # use utoipa::OpenApi;
//! #[rocket::launch]
//! fn rocket() -> Rocket<Build> {
//! #
//! # #[derive(OpenApi)]
//! # #[openapi()]
//! # struct ApiDoc;
//! #
//! rocket::build()
//! .mount(
//! "/",
//! SwaggerUi::new("/swagger-ui/<_..>").url("/api-doc/openapi.json", ApiDoc::openapi()),
//! )
//! }
//! ```
//!
//! [^actix]: **actix-web** feature need to be enabled.
//!
//! [^rocket]: **rocket** feature need to be enabled.
use std::{borrow::Cow, error::Error, io::Cursor, sync::Arc};

#[cfg(feature = "actix-web")]
use actix_web::{
dev::HttpServiceFactory, guard::Get, web, web::Data, HttpResponse, Resource, Responder,
dev::HttpServiceFactory, guard::Get, web, web::Data, HttpResponse, Resource,
Responder as ActixResponder,
};

#[cfg(feature = "rocket")]
use rocket::{
http::{Header, Status},
response::{
status::{self, NotFound},
Responder,
Responder as RocketResponder,
},
route::{Handler, Outcome},
serde::json::Json,
Data, Request, Response, Route,
Data as RocketData, Request, Response, Route,
};

use rust_embed::RustEmbed;
Expand Down Expand Up @@ -211,7 +238,7 @@ impl HttpServiceFactory for SwaggerUi {

#[cfg(feature = "actix-web")]
fn register_api_doc_url_resource(url: &str, api: OpenApi, config: &mut actix_web::dev::AppService) {
pub async fn get_api_doc(api_doc: web::Data<OpenApi>) -> impl Responder {
pub async fn get_api_doc(api_doc: web::Data<OpenApi>) -> impl ActixResponder {
HttpResponse::Ok().json(api_doc.as_ref())
}

Expand Down Expand Up @@ -255,7 +282,7 @@ struct ServeApiDoc(utoipa::openapi::OpenApi);
#[cfg(feature = "rocket")]
#[rocket::async_trait]
impl Handler for ServeApiDoc {
async fn handle<'r>(&self, request: &'r Request<'_>, _: Data<'r>) -> Outcome<'r> {
async fn handle<'r>(&self, request: &'r Request<'_>, _: RocketData<'r>) -> Outcome<'r> {
Outcome::from(request, Json(self.0.clone()))
}
}
Expand All @@ -267,7 +294,7 @@ struct ServeSwagger(Cow<'static, str>, Arc<Config<'static>>);
#[cfg(feature = "rocket")]
#[rocket::async_trait]
impl Handler for ServeSwagger {
async fn handle<'r>(&self, request: &'r Request<'_>, _: Data<'r>) -> Outcome<'r> {
async fn handle<'r>(&self, request: &'r Request<'_>, _: RocketData<'r>) -> Outcome<'r> {
let mut path = self.0.as_ref();
if let Some(index) = self.0.find('<') {
path = &path[..index];
Expand All @@ -286,7 +313,7 @@ impl Handler for ServeSwagger {
}

#[cfg(feature = "rocket")]
impl<'r, 'o: 'r> Responder<'r, 'o> for SwaggerFile<'o> {
impl<'r, 'o: 'r> RocketResponder<'r, 'o> for SwaggerFile<'o> {
fn respond_to(self, _: &'r Request<'_>) -> rocket::response::Result<'o> {
rocket::response::Result::Ok(
Response::build()
Expand Down

0 comments on commit 53d743e

Please sign in to comment.