Skip to content

Commit

Permalink
Add get_nested_endpoints_and_docs macro and update example
Browse files Browse the repository at this point in the history
  • Loading branch information
maximeborges committed Dec 17, 2023
1 parent ceaa204 commit b0f5d8d
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 24 deletions.
29 changes: 5 additions & 24 deletions examples/nested/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,11 @@ mod post;
mod message;

use rocket::Route;
use rocket_okapi::{okapi::openapi3::OpenApi, settings::OpenApiSettings};
use rocket_okapi::{okapi::openapi3::OpenApi, settings::OpenApiSettings, get_nested_endpoints_and_docs};

pub fn get_routes_and_docs(settings: &OpenApiSettings) -> (Vec<rocket::Route>, OpenApi) {
let mut routes = vec![];
let mut openapi_list: Vec<(_, rocket_okapi::okapi::openapi3::OpenApi)> = Vec::new();

[
("/posts", post::get_routes_and_docs(settings)),
("/message", message::get_routes_and_docs(settings)),
]
.into_iter()
.for_each(|(path, (new_routes, openapi))| {
let new_routes = new_routes
.into_iter()
.map(|r: Route| r.map_base(|base| format!("{}{}", path, base)).unwrap())
.collect::<Vec<_>>();
routes.extend(new_routes);
openapi_list.push((path, openapi));
});

let openapi_docs = match rocket_okapi::okapi::merge::marge_spec_list(&openapi_list) {
Ok(docs) => docs,
Err(err) => panic!("Could not merge OpenAPI spec: {}", err),
};

(routes, openapi_docs)
get_nested_endpoints_and_docs! {
"/posts" => post::get_routes_and_docs(settings),
"/message" => message::get_routes_and_docs(settings),
}
}
68 changes: 68 additions & 0 deletions rocket-okapi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,74 @@ macro_rules! mount_endpoints_and_merged_docs {
}};
}



/// Get and merge nested endpoints and OpenAPI documentation.
///
/// This macro enables to split endpoints definition in smaller pieces to make code look
/// cleaner and improves readability for bigger codebases.
///
/// The macro expects the following arguments:
/// - List of (0 or more):
/// - path: `&str`, `String` or [`Uri`](rocket::http::uri::Uri).
/// Anything accepted by `mount()` (`base_path` should not be included).
/// - `=>`: divider
/// - route_and_docs: `(Vec<rocket::Route>, OpenApi)`
///
/// Example:
/// ```rust,ignore
/// let settings = OpenApiSettings::default();
/// let custom_route_spec = (vec![], custom_spec());
/// mount_endpoints_and_merged_docs! {
/// building_rocket, "/v1".to_owned(), settings,
/// "/" => custom_route_spec,
/// "/api" => api::get_routes_and_docs(),
/// };
///
/// mod api {
/// pub fn get_routes_and_docs(settings: &OpenApiSettings) -> (Vec<rocket::Route>, OpenApi) {
/// get_nested_endpoints_and_docs! {
/// "/posts" => post::get_routes_and_docs(settings),
/// "/message" => message::get_routes_and_docs(settings),
/// }
/// }
/// mod posts {
/// pub fn get_routes_and_docs(settings: &OpenApiSettings) -> (Vec<rocket::Route>, OpenApi) {
/// openapi_get_routes_spec![settings: create_post, get_post]
/// }
/// }
/// mod messages {
/// pub fn get_routes_and_docs(settings: &OpenApiSettings) -> (Vec<rocket::Route>, OpenApi) {
/// openapi_get_routes_spec![settings: create_message, get_message]
/// }
/// }
/// }
/// ```
///
#[macro_export]
macro_rules! get_nested_endpoints_and_docs {
($($path_prefix:expr => $route_and_docs:expr),* $(,)*) => {{
let mut routes = Vec::new();
let mut openapi_specs = rocket_okapi::okapi::openapi3::OpenApi::new();

$({
let (new_routes, new_specs) = $route_and_docs;
// Prepend the path prefix to all routes
let new_routes = new_routes
.into_iter()
.map(|r: Route| r.map_base(|base| format!("{}{}", $path_prefix, base)).unwrap())
.collect::<Vec<_>>();
routes.extend(new_routes);
// Merge OpenAPI specs
if let Err(err) = rocket_okapi::okapi::merge::merge_specs(&mut openapi_specs, &$path_prefix, &new_specs) {
panic!("Failed to merge specs: {}", err)
}
})*

(routes, openapi_specs)
}};
}

/// A replacement macro for `rocket::routes`. This also takes a optional settings object.
///
/// The key differences are that this macro will add an additional element to the
Expand Down

0 comments on commit b0f5d8d

Please sign in to comment.