utoipa: Generics do not work with lifetime specifiers
Hey @juhaku
Thank you for your work on this library. It is astonishing and a great developer experience. However, I have a use-case where the behavior is a bit shakey.
I have a rocket web api for testing out some scenarios. One scenario would be to return paginated generic responses.
I have the following struct that returns a generic list of data, with a total sice and two optional links to the “next” or “prev” page.
/// Paginated response for a list of results.
/// Contains optional links to the next and previous page,
/// and the total count of items that are available.
#[derive(Debug, Serialize, ToSchema)]
pub struct Paginated<'r, TResult> {
pub total: usize,
pub data: Vec<TResult>,
pub next: Option<&'r str>,
pub prev: Option<&'r str>,
}
I know referenced the crate via git reference on the master branch to get the new features like “content” in the responses for multiple response types. Then I tried to use the aliases, however, they do not work since I don’t have all the structs in one file.
When trying with type aliases like so:
type Test = Paginated<'static, Test<'static>>;
#[derive(OpenApi)]
// components(schemas(test::models::Test, test::models::Metadata)),
#[openapi(
paths(test::get_all, test::get_by_id),
components(schemas(Test))
)]
pub(super) struct ApiDoc;
I run into the following error:
Could not resolve reference: Could not resolve pointer: /components/schemas/TResult does not exist in document
With aliases, the references to the models are not present, in which case the compiler will not run through.
Do you have any advice or solution for this matter?
When using aliases like described (#[aliases(PaginatedPages = Paginated<Page>)]) it requires a “,” in between. Or when I specify the lifetimes, it complains that the combination is not correct for parsing.
Regards
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 21 (10 by maintainers)
need to try that asap 😄
I wrote another implementation now working with
syn::Typeand according to the tests it should work now with extensive use of lifetimes and even with nested generics. You can peek it here #546I belive this happes because one might add the generic schema to the
#[openapi(components(schemas(...)))]but one should actuallly place the aliases instead and not the type that has generics. Also if generic argument is another sized type e.g. struct likestruct Result {...}then that should also be decorated with#[derive(ToSchema)]and registered in#[openapi(components(schemas(...)))]Aah, yeah… That is a thing indeed. For that As now the alias blindly uses
Identbut then it should be parsed asTypePath. But the biggest obstacle will be updating theTypeTreewhich holds the actual type tree representation. https://github.com/juhaku/utoipa/blob/5b51eb41b7dedf07a684c7ca2516654c18f13a74/utoipa-gen/src/component/schema.rs#L1593If you want you can try to make a change so that you can replace this ident above to a
TypePath. But we only need ident to theTypeTree. Updating theTypeTreeis bit of a whack 😄 because it’s all references with lifetimes.Hey there, yes, I’m working on adressing the comments on my PR (#414) today. Sorry it took so long, I got busy with new years’ and prioritized something else at work…
Thank you! 😃 I know the feeling, life happens, no pressure. I try to have a look at lifetimes, since Rust requires them even in the macros. Otherwise, this library (with swagger ui) is pretty neat and removes a lot of extra work when using openAPI spec.
I hope the PR #414 lands soon, as we have a data-scheme that requires other enum representations 😉
Have a nice day, and thanks again for this crate!