{"id":21228152,"url":"https://github.com/probablyclem/utoipauto","last_synced_at":"2025-05-15T15:02:37.110Z","repository":{"id":209485771,"uuid":"724139888","full_name":"ProbablyClem/utoipauto","owner":"ProbablyClem","description":"Rust Macros to automate the addition of Paths/Schemas to Utoipa crate, simulating Reflection during the compilation phase","archived":false,"fork":false,"pushed_at":"2025-02-10T09:17:00.000Z","size":220,"stargazers_count":154,"open_issues_count":6,"forks_count":10,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-07T22:03:08.669Z","etag":null,"topics":["code-first","openapi","openapi-generator","schema","swagger","swagger-ui","utoipa"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"rxdiscovery/utoipa_auto_discovery","license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ProbablyClem.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-11-27T13:32:10.000Z","updated_at":"2025-04-05T23:57:09.000Z","dependencies_parsed_at":"2024-05-17T16:35:58.220Z","dependency_job_id":"50551841-2d6b-4d70-8af9-3900860a6a48","html_url":"https://github.com/ProbablyClem/utoipauto","commit_stats":null,"previous_names":["probablyclem/utoipa_auto_discovery","probablyclem/utoipauto"],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ProbablyClem%2Futoipauto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ProbablyClem%2Futoipauto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ProbablyClem%2Futoipauto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ProbablyClem%2Futoipauto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ProbablyClem","download_url":"https://codeload.github.com/ProbablyClem/utoipauto/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247737770,"owners_count":20987718,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["code-first","openapi","openapi-generator","schema","swagger","swagger-ui","utoipa"],"created_at":"2024-11-20T23:14:43.295Z","updated_at":"2025-04-07T22:03:15.650Z","avatar_url":"https://github.com/ProbablyClem.png","language":"Rust","readme":"\u003cdiv style=\"text-align: center\"\u003e\n\u003ch1\u003eUtoipauto\u003c/h1\u003e\n  \u003cp\u003e\n    \u003cstrong\u003eRust Macros to automate the addition of Paths/Schemas to Utoipa crate, simulating Reflection during the compilation phase\u003c/strong\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\n# Crate presentation\n\nUtoipa is a great crate for generating documentation (openapi/swagger) via source code.\n\nBut since Rust is a static programming language, we don't have the possibility of automatically discovering paths and\ndto in runtime and adding them to the documentation,\n\nFor APIs with just a few endpoints, it's not that much trouble to add controller functions one by one, and DTOs one by\none.\n\nBut, if you have hundreds or even thousands of endpoints, the code becomes very verbose and difficult to maintain.\n\nEx :\n\n```rust\n\n#[derive(OpenApi)]\n#[openapi(\n    paths(\n        // \u003c================================ All functions  1 to N\n        test_controller::service::func_get_1,\n        test_controller::service::func_get_2,\n        test_controller::service::func_get_3,\n        test_controller::service::func_get_4,\n       ....\n       ....\n       ....\n        test_controller::service::func_get_N,\n\n    ),\n    components(\n        // \u003c====================== All DTO one by one\n        schemas(TestDTO_1,  TestDTO_2, ........ , TestDTO_N)\n    ),\n    tags(\n        (name = \"todo\", description = \"Todo management endpoints.\")\n    ),\n    modifiers(\u0026SecurityAddon)\n)]\npub struct ApiDoc;\n\n```\n\nThe goal of this crate is to propose a macro that automates the detection of methods carrying Utoipa\nmacros (`#[utoipa::path(...]`), and adds them automatically. (it also detects sub-modules.)\n\nIt also detects struct that derive or implement `ToSchema` for the `components(schemas)` section, and the `ToResponse`\nfor the `components(responses)` section.\n\n# Features\n\n- [x] Automatic recursive path detection\n- [x] Automatic import from module\n- [x] Automatic import from src folder\n- [x] Automatic model detection\n- [x] Automatic response detection\n- [x] Works with workspaces\n- [x] Exclude a method from automatic scanning\n- [x] Custom path detection\n\n# How to use it\n\nSimply add the crate `utoipauto` to the project\n\n```\ncargo add utoipauto\n```\n\nImport macro\n\n```rust\nuse utoipauto::utoipauto;\n```\n\nThen add the `#[utoipauto]` macro just before the #[derive(OpenApi)] and `#[openapi]` macros.\n\n## Important !!\n\nPut `#[utoipauto]` before `#[derive(OpenApi)] `and `#[openapi]` macros.\n\n```rust\n#[utoipauto(paths = \"MODULE_SRC_FILE_PATH, MODULE_SRC_FILE_PATH, ...\")]\n```\n\nThe paths receives a String which must respect this structure :\n\n`\"MODULE_SRC_FILE_PATH, MODULE_SRC_FILE_PATH, ...\"`\n\nYou can add several paths by separating them with a coma `\",\"`.\n\n## Usage with workspaces\n\nIf you are using a workspace, you must specify the name of the crate in the path.\n\u003cbr\u003e\nThis applies even if you are using `#[utoipauto]` in the same crate.\n\n```rust\n#[utoipauto(paths = \"./utoipauto/src\")]\n```\n\nYou can specify that the specified paths are from another crate by using the from key work.\n\n```rust\n#[utoipauto(paths = \"./utoipauto/src from utoipauto\")]\n```\n\n### Import from src folder\n\nIf no path is specified, the macro will automatically scan the `src` folder and add all the methods carrying\nthe `#[utoipa::path(...)]` macro, and all structs deriving `ToSchema` and `ToResponse`.\nHere's an example of how to add all the methods contained in the src code.\n\n```rust\n...\n\nuse utoipauto::utoipauto;\n\n...\n#[utoipauto]\n#[derive(OpenApi)]\n#[openapi(\n    tags(\n        (name = \"todo\", description = \"Todo management endpoints.\")\n    ),\n    modifiers(\u0026SecurityAddon)\n)]\n\npub struct ApiDoc;\n\n...\n\n```\n\n### Import from module\n\nHere's an example of how to add all the methods and structs contained in the rest module.\n\n```rust\n\nuse utoipauto::utoipauto;\n\n#[utoipauto(\n    paths = \"./src/rest\"\n)]\n#[derive(OpenApi)]\n#[openapi(\n    tags(\n        (name = \"todo\", description = \"Todo management endpoints.\")\n    ),\n    modifiers(\u0026SecurityAddon)\n)]\n\npub struct ApiDoc;\n\n```\n\nHere's an example of how to add all methods and structs contained in the rest module if it is in a sub-folder:\n\n```rust\n\nuse utoipauto::utoipauto;\n\n#[utoipauto(\n    paths = \"(./src/lib/rest from crate::rest)\"\n)]\n#[derive(OpenApi)]\n#[openapi(\n    tags(\n        (name = \"todo\", description = \"Todo management endpoints.\")\n    ),\n    modifiers(\u0026SecurityAddon)\n)]\n\npub struct ApiDoc;\n\n```\n\n### Import from filename\n\nHere's an example of how to add all the methods contained in the test_controller and test2_controller modules.\nyou can also combine automatic and manual addition, as here we've added a method manually to the documentation \"\nother_controller::get_users\", and a schema \"TestDTO\".\n\n```rust\n\nuse utoipauto::utoipauto;\n\n#[utoipauto(\n    paths = \"./src/rest/test_controller.rs,./src/rest/test2_controller.rs \"\n)]\n#[derive(OpenApi)]\n#[openapi(\n    paths(\n\n        crate::rest::other_controller::get_users,\n    ),\n    components(\n        schemas(TestDTO)\n    ),\n    tags(\n        (name = \"todo\", description = \"Todo management endpoints.\")\n    ),\n    modifiers(\u0026SecurityAddon)\n)]\n\npub struct ApiDoc;\n\n\n\n```\n\n## Exclude a method from automatic scanning\n\nyou can exclude a function from the Doc Path list by adding the following macro `#[utoipa_ignore]` .\n\nex:\n\n```rust\n    /// Get all pets from database\n///\n#[utoipa_ignore]  //\u003c============== this Macro\n#[utoipa::path(\n    responses(\n            (status = 200, description = \"List all Pets\", body = [ListPetsDTO])\n    )\n)]\n#[get(\"/pets\")]\nasync fn get_all_pets(req: HttpRequest, store: web::Data\u003cAppState\u003e) -\u003e impl Responder {\n    // your CODE\n}\n\n```\n\n## Exclude a struct from automatic scanning\n\nyou can also exclude a struct from the models and reponses list by adding the following macro `#[utoipa_ignore]` .\n\nex:\n\n```rust\n    #[utoipa_ignore]  //\u003c============== this Macro\n#[derive(ToSchema)]\nstruct ModelToIgnore {\n    // your CODE\n}\n\n```\n\n### Custom path detection\n\nBy default, this macro will look for function with the `#[utoipa::path(...)]` attribute, but you can also specify a\ncustom attribute to look for.\n\n```rust\n#[handler]\npub fn custom_router() {\n    // ...\n}\n\n#[utoipauto(function_attribute_name = \"handler\")] //Custom attribute\n#[derive(OpenApi)]\n#[openapi(tags()))]\npub struct ApiDoc;\n\n```\n\nYou can also specify custom attributes for the model and response detection.\n\n```rust\n#[derive(Schema, Response)]\npub struct CustomModel {\n    // ...\n}\n\n#[utoipauto(schema_attribute_name = \"Schema\", response_attribute_name = \"Response\")] //Custom derive\n#[derive(OpenApi)]\n#[openapi(tags())]\npub struct ApiDoc;\n\n```\n\n## Note\n\nSub-modules within a module containing methods tagged with utoipa::path are also automatically detected.\n\n## Contributing\n\nContributions are welcomed, feel free to submit a PR or an issue.\n\n## Inspiration\n\nInspired by [utoipa_auto_discovery](https://github.com/rxdiscovery/utoipa_auto_discovery)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprobablyclem%2Futoipauto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprobablyclem%2Futoipauto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprobablyclem%2Futoipauto/lists"}