Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Break down #[derive(OpenApi)] #[openapi(...)] into smaller chunks #1204

Open
jacques-kigo opened this issue Nov 14, 2024 · 2 comments
Open

Comments

@jacques-kigo
Copy link

jacques-kigo commented Nov 14, 2024

I'm working on a large project using utoipa with hundreds of paths and component schemas.

My docs.rs file where I keep the utoipa macros is thousands of lines long.

Adding / organizing new and existing paths and types to #[derive(OpenApi)] #[openapi(...)] is becoming a very large pain point in my codebase.

I'd like to split them up into separate files. At minimum something like:

docs/
├── external.rs
├── internal.rs
├── mod.rs
├── modifiers.rs
├── paths.rs
├── schemas.rs
└── tags.rs

I've tried macros and functions to break down the file into the proposed structure above but nothing seems to work, it keeps breaking the utoipa macro and won't compile unless it's all inline in one file.

Is there something I'm missing here? A better workflow perhaps? This is becoming very frustrating.

@juhaku
Copy link
Owner

juhaku commented Nov 14, 2024

If you are using utoipa-5.0.0 you can use nest(...) attribute (https://docs.rs/utoipa/latest/utoipa/derive.OpenApi.html#nest-attribute-syntax) to nest other OpenAPIs to a single one. Or nest / merge manually OpenApi to a single one with nest() or merge() methods on OpenApi. https://docs.rs/utoipa/latest/utoipa/openapi/struct.OpenApi.html

You can create multiple OpenApi instances and finally merge them into one. E.g. you can create one within paths.rs one in schemas.rs etc. in order to split the functionality.

If you are using axum or actix-web you can also use the utoipa-axum or utoipa-actix-web to register the handlers simultaneously to the OpenApi without registering the paths in paths(...) attribute. Of course this has a drawback that then axum or actix-web dependency needs to be there as well when the OpenAPI schema is created as it ties utoipa and axum / actix-web together which makes it little harder to have a separate command to dump the generated OpenAPI spec to file e.g. in build step as explained here #214 (comment).

Utoipa 5.0.0 will automatically collect schemas from the usages points recursive. This requires that all types that derive ToSchema need to make sure all fields and variant types also implement the ToSchema trait. The schemas are automatically collected from request_body or response body or from schemas(...) attribute, But there is no need to define those schemas anymore in #[openapi(schemas(...))] attribute as long as they are defined somewhere for request body or response body. For axum and actix-web the request body is also resolved from the handler function argument as well.

Currently the IntoParams which have type that implements ToSchema is not automatically collected and such type needs to be manually added to the OpenApi via schemas(..) attribute.

Example of utoipa axum bindings: https://github.com/juhaku/utoipa/tree/master/examples/actix-web-scopes-binding
Example of utoipa actix-web bindings: https://github.com/juhaku/utoipa/tree/master/examples/actix-web-scopes-binding
Example of using nesting: https://github.com/juhaku/utoipa/tree/master/examples/axum-utoipa-nesting-vendored

Also the latest todo examples for axum and actix-web has been updated to use the bindings instead of registering handlers via paths(...) attribute. It is true that when there are plenty of types and handlers to register, it does get burden some the register them all via schemas(...) or paths(...) as they also need to be accessible by the macro as well. By way of using nesting or merging OpenApi instances into single one there is no need expose all paths and types publicly to single OpenApi but instead only the sub OpenApis can be exposed publicly.

@jacques-kigo
Copy link
Author

jacques-kigo commented Nov 15, 2024

@juhaku thank you very much for your response and suggestions. I will try using nest(...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants