Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion utoipa-gen/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ impl HttpMethod {
.map_err(|error| {
let mut diagnostics = Diagnostics::with_span(ident.span(), error.to_string());
if name == "connect" {
diagnostics = diagnostics.note("HTTP method `CONNET` is not supported by OpenAPI spec <https://spec.openapis.org/oas/latest.html#path-item-object>");
diagnostics = diagnostics.note("HTTP method `CONNECT` is not supported by OpenAPI spec <https://spec.openapis.org/oas/latest.html#path-item-object>");
}

diagnostics
Expand Down
54 changes: 47 additions & 7 deletions utoipa/src/openapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,14 +294,13 @@ impl OpenApi {
O: Into<OpenApi>,
F: Fn(&str, &str) -> String,
>(
mut self,
self,
path: P,
other: O,
composer: F,
) -> Self {
let path: String = path.into();
let mut other_api: OpenApi = other.into();

let nested_paths = other_api
.paths
.paths
Expand All @@ -311,11 +310,7 @@ impl OpenApi {
(path, item)
})
.collect::<PathsMap<_, _>>();

self.paths.paths.extend(nested_paths);

// paths are already merged, thus we can ignore them
other_api.paths.paths = PathsMap::new();
other_api.paths.paths = nested_paths;
self.merge_from(other_api)
}
}
Expand Down Expand Up @@ -906,6 +901,51 @@ mod tests {
assert_json_snapshot!(paths);
}

/// Assert that nesting "merged" properly with existing routes
#[test]
fn test_nest_open_apis_same_path_diff_methods() {
let user_api_1 = OpenApiBuilder::new()
.paths(
PathsBuilder::new().path(
"/api/v1/status",
PathItem::new(
HttpMethod::Get,
OperationBuilder::new()
.description(Some("Get status"))
.build(),
),
),
)
.build();

let user_api_2 = OpenApiBuilder::new()
.paths(
PathsBuilder::new()
.path(
"/status",
PathItem::new(
HttpMethod::Post,
OperationBuilder::new()
.description(Some("Post status"))
.build(),
),
)
.path(
"/foo",
PathItem::new(HttpMethod::Post, OperationBuilder::new().build()),
),
)
.build();

let nest_merged = user_api_1.nest("/api/v1", user_api_2);
let value = serde_json::to_value(nest_merged).expect("should serialize as json");
let paths = value
.pointer("/paths")
.expect("paths should exits in openapi");

assert_json_snapshot!(paths);
}

#[test]
fn openapi_custom_extension() {
let mut api = OpenApiBuilder::new().build();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
source: utoipa/src/openapi.rs
expression: paths
---
{
"/api/v1/foo": {
"post": {
"responses": {}
}
},
"/api/v1/status": {
"get": {
"description": "Get status",
"responses": {}
},
"post": {
"description": "Post status",
"responses": {}
}
}
}