GREsau / okapi

OpenAPI (AKA Swagger) document generation for Rust projects
MIT License
578 stars 103 forks source link

Nested routes? #137

Closed maximeborges closed 6 months ago

maximeborges commented 7 months ago

Hello, I've been trying to nest routes in a somewhat clean way, but I couldn't manage to do that with the proposed macros. The idea is to include the routes from a module, adding a sub-path in the URI, and this module get more nested routes adding even more sub-path. All of that without having to specify all the routes at the top level (or second level by using mount_endpoints_and_merged_docs).

It's a bit late here, so here is some code which might makes my explanation a bit more clear (hopefully), based on the custom_schema example: https://github.com/maximeborges/okapi/blob/ac9e23b6383591d8e9d69d742112679d163fa899/examples/nested/src/api/mod.rs

Basically in the main:

mount_endpoints_and_merged_docs! {
        building_rocket, "/v1".to_owned(), openapi_settings,
        "/external" => custom_route_spec,
        "/api" => api::get_routes_and_docs(&openapi_settings),
    };

and in the api module, which has post and message as sub-module:


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)
}

Is there a better way of doing that, or should I propose a PR to have some function/macro for that?

ralpha commented 7 months ago

Hey, in short, no, we do not have a very good solution for this at the moment. A solution for this would be welcome.

Not sure how we should best go about implementing this. Ether we extend mount_endpoints_and_merged_docs and/or openapi_get_routes. But they might not be the right place to do this. So yes, maybe creating a new macro that does the combining is the best solution.

I see you already took inspiration from both macro's. Feel free to create a MR. If the MR is created soon I might be able to add before the next release.

ralpha commented 6 months ago

Closed because #138 was merged

ralpha commented 6 months ago

@maximeborges Thanks for the MR. :heart: (and sorry for the delay)