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

Parse failure using #[serde(flatten)] with Query Params #721

Closed
epompeii opened this issue Jul 7, 2023 · 2 comments
Closed

Parse failure using #[serde(flatten)] with Query Params #721

epompeii opened this issue Jul 7, 2023 · 2 comments

Comments

@epompeii
Copy link
Contributor

epompeii commented Jul 7, 2023

When trying to use #[serde(flatten)] with query params, integers fail to parse with the following error when they are part of the nested, flattened struct:

Jul 07 23:10:58.044 INFO request completed, error_message_external: unable to parse query string: invalid type: string "8", expected u8, error_message_internal: unable to parse query string: invalid type: string "8", expected u8, response_code: 400, uri: /v0/projects/the-computer/branches?per_page=8&page=1, method: OPTIONS, req_id: 9fe8794e-d777-433a-8cb5-071c3ca69091, remote_addr: 127.0.0.1:64916, local_addr: 0.0.0.0:61016

Using flatten things look like this:

#[derive(Deserialize, JsonSchema)]
pub struct ProjBranchesQuery {
    pub name: Option<String>,
    #[serde(flatten)]
    pub pagination: JsonPagination<ProjBranchesSort>,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(JsonSchema))]
pub struct JsonPagination<T> {
    pub sort: Option<T>,
    pub direction: Option<JsonDirection>,
    pub per_page: Option<u8>,
    pub page: Option<u32>,
}

However in-lining things manually works just fine, no parse errors:

#[derive(Deserialize, JsonSchema)]
pub struct ProjBranchesQuery {
    pub name: Option<String>,
    pub sort: Option<ProjBranchesSort>,
    pub direction: Option<JsonDirection>,
    pub per_page: Option<u8>,
    pub page: Option<u32>,
}

Also inverting things works:

pub type ProjBranchesQuery = JsonPagination<ProjBranchesSort, ProjBranchesQueryParams>;

#[derive(Debug, Clone, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(JsonSchema))]
pub struct JsonPagination<S, Q> {
    pub sort: Option<S>,
    pub direction: Option<JsonDirection>,
    pub per_page: Option<u8>,
    pub page: Option<u32>,
    #[serde(flatten)]
    pub query: Q,
}

#[derive(Deserialize, JsonSchema)]
pub struct ProjBranchesQueryParams {
    pub name: Option<String>,
}

It is only when the integer field is in the nested, flattened struct that the error occurs.

@davepacheco
Copy link
Collaborator

Sorry for the slow response on this. Things have been pretty busy over here.

I believe this is the issue that's mentioned in the docs under https://docs.rs/dropshot/0.9.0/dropshot/index.html#advanced-usage-notes:

It’s possible to accept additional query parameters besides the pagination parameters by having your API endpoint handler function take two different arguments using Query, like this:
...
You might expect that instead of doing this, you could define your own structure that includes a PaginationParams using #[serde(flatten)], and this ought to work, but it currently doesn’t due to serde_urlencoded#33, which is really serde#1183.

I think this is the same issue as nox/serde_urlencoded#33, which is serde-rs/serde#1183. I'm not sure what we can do better here.

@epompeii
Copy link
Contributor Author

No worries, @davepacheco. Congrats to you and the Oxide team for shipping your first rack!

I thought that, that limitation was just for the built-in PaginationParams, which I'm not using here.
Given how deep this limitation seems to run though, I'll just go the additional query parameters route.
Thanks for the pointer!

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