juhaku / utoipa

Simple, Fast, Code first and Compile time generated OpenAPI documentation for Rust
Apache License 2.0
2.2k stars 170 forks source link

auto detection of paths/schemas for documentation #624

Open rxdiscovery opened 1 year ago

rxdiscovery commented 1 year ago

Hello, I would like to know if there is a way to automatically generate all the paths / schemas, without having to do it one by one in the code.

For example if we have 1000 functions in our API, we have to write 1000 Paths with the used schemas in the macro #[openapi] ?

#[derive(OpenApi)]
#[openapi(
    paths(

        test_controller::service::func_get_1, // <================================ 1 to N ?
        test_controller::service::func_get_2,
        test_controller::service::func_get_3,
        test_controller::service::func_get_4,
       ....
       ....
       ....
        test_controller::service::func_get_N,

    ),
    components(
        schemas(TestDTO_1,  TestDTO_2, ........ , TestDTO_N) // <====================== All DTO one by one ?
    ),
    tags(
        (name = "todo", description = "Todo management endpoints.")
    ),
    modifiers(&SecurityAddon)
)]
pub struct ApiDoc;

isn't there a way to detect the functions with the Macro #[utoipa::path] and add them automatically to the documentation?

isn't there a way to make it transparent like Springdoc ? because I really don't want to go back to the JAVA world, I know that things are simpler when a language implements the reflection, but I keep hoping that it's still possible to do it on Rust with the Macros :1st_place_medal:

Thank you in advance.

juhaku commented 1 year ago

isn't there a way to detect the functions with the Macro #[utoipa::path] and add them automatically to the documentation?

Yeah, that is that. This is not simple to do. As you said Rust does not have runtime reflection like Java has and that is exactly what Springdoc leverages when building the docs. There already is classes loaded to the classpath and the library can simply just loop through them and find the relevant ones.

But because of nature of macros they do not know about their environment nor they know about available structs and functions and types. Macros are only aware of the type tokens of a struct or function it is being used with. To make them to recognize paths and schemas they need to be declared explicitly by some means.

I also had planned to implement the support for this. I think it would be cool if it was "automagic" like in Java world. But so far I have no complete picture of how it would be possible. At least I am able to make it work in theory within a single crate but it is not enough to say that it would be usable. Cross crate references still need to be somehow indicated somewhere to the macros.

I think this is an important feature however perhaps this need to be looked from another perspective. This is to leverage macro rules with sub modules. For exmaple same time the path is registered it would register it to a sub router that will then be merged to the actual http framework. This is also something that has been requested (#394, #537) but still I haven't had bandwidth to invest into that as of yet.

Bigger APIs have split the API defintion in smaller pieces e.g. in user module they are creating new OpenApi that contains only paths and types for user releated operations. Then in root level all these sub modules would be merged into single one.

Paracetamol56 commented 1 year ago

👋 Hello, I'm also interested in this topic.

Bigger APIs have split the API defintion in smaller pieces e.g. in user module they are creating new OpenApi that contains only paths and types for user releated operations. Then in root level all these sub modules would be merged into single one.

Is there any way to do this in the current state of your crate? I have nearly 400 lines of path and schema declarations for a professional project, and I would appreciate it if the declaration could be divided into several parts in submodules. Thanks !

rxdiscovery commented 1 year ago

@juhaku I'm currently working on a solution. If it works, I'll share the code here and then integrate it into Utoipa (if you're interested).

the idea is simple, I'm creating a super macro, which will take as a parameter the folder where the REST controllers are located, then parse it and list all the functions containing the tag #[utoipa::path] , then generate the Utoipa macro (#[openapi]) with the paths for each function.

it will be a good start to automate this task.

rxdiscovery commented 1 year ago

Hello,

(this is my small contribution to this wonderful community)

Here's a first version of a crate (utoipa_auto_discovery) that automates Paths and Schemas detection on Utoipa. I'm currently using it on an internal project,

Url of the crate : https://crates.io/crates/utoipa_auto_discovery

it's not perfect yet, but it works well :+1: , you can try it and give me your feedback.

Thanks..

ProbablyClem commented 9 months ago

Hello guys, I finished the work that @rxdiscovery started and created a new crate because I needed to import it in another projet.

You can find it here: utoipauto

I now support auto import of everything, including paths, schemas and models.

Basically, just need to add one macro annotation and the rest would be done automatically.

I think it's neat !

...

use utoipauto::utoipauto;

...
#[utoipauto]
#[derive(OpenApi)]
#[openapi()]

pub struct ApiDoc;

...

Would you be interessted in merging this project into yours ? Or maybe just promoting it in the readme or something ? @juhaku

juhaku commented 4 months ago

Would you be interessted in merging this project into yours ? Or maybe just promoting it in the readme or something ? @juhaku

Sure, for time being I will add a mention to the REAMDE about the crate. Maybe in longer run it can be merged into utoipa as well, or just to keep it separate :thinking: