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

Pagination support for /users #375

Merged
merged 23 commits into from
Nov 12, 2024
Merged

Pagination support for /users #375

merged 23 commits into from
Nov 12, 2024

Conversation

oguzkocer
Copy link
Contributor

@oguzkocer oguzkocer commented Nov 5, 2024

This PR adds strongly typed next_page_params & prev_page_params fields to the response types that supports pagination. The response types are generated by #[derive(WpDerivedRequest)], so here is a shortened example of how that looks:

#[derive(WpDerivedRequest)]
enum UsersRequest {
    #[contextual_paged(url = "/users", params = &UserListParams, output = Vec<crate::SparseUser>, filter_by = crate::SparseUserField)]
    List,
}

The above implementation will result in the following generated code:

pub struct UsersRequestListWithEditContextResponse {
    pub data: Vec<crate::UserWithEditContext>,
    pub header_map: std::sync::Arc<crate::request::WpNetworkHeaderMap>,
    pub next_page_params: Option<UserListParams>,
    pub prev_page_params: Option<UserListParams>,
}

Notice that there is now a new #[derive(WpDerivedRequest)] attribute: #[contextual_paged]. This attribute works exactly the same as #[contextual_get]. The only difference is #[contextual_paged] response types will have next_page_params & prev_page_params fields, but the #[contextual_get] doesn't.

Also notice that the type of next_page_params & prev_page_params are Option<UserListParams>. This is the params field that's passed in the #[contextual_paged] attribute.


WordPress endpoints that support pagination will have a header link with next & prev headers when it's appropriate. As far as I can tell, /users endpoint will include these headers if the per_page parameter is provided. So, at this time, the response for the default UserListParams will not include them. This issue will be handled in a separate PR.

The way this implementation works is by checking the next and prev header links for params types that support it. For a params type to support pagination, it needs to return true from its FromUrlQueryPairs::supports_pagination() implementation. All params type that implements this trait should return true for this function, except for the () type which is used as a marker to indicate pagination is not supported.

FromUrlQueryPairs trait is how we parse the header links into params type - using its from_url_query_pairs function implementation. There are a few helpers to do this, so its implementation for a params type is mostly straightforward. However, these helpers require the types used in a params type to implement std::str::FromStr or wp_api::OptionFromStr traits. For example, since UserListParams has pub who: Option<WpApiParamUsersWho> field, WpApiParamUsersWho has to implement the std::str::FromStr trait.


We now have AppendUrlQueryPairs & FromUrlQueryPairs traits to convert the params types to and from url query pairs. Since both of these implementations should use the same keys for the query pairs, a new enum UserListParamsField is added. This enum converts the field names for UserListParams into &str. It'd be easy to generate these field types from a proc macro, but for now they'll be hand rolled.


The PR includes unit tests to validate going from a UserListParams to query pairs and then parsing it back to UserListParams and compare the two. It also includes pagination Rust & Kotlin integration tests for /users endpoint.

There are also other unit & integration tests to validate the behavior changes to #[WpDerivedRequest].

@oguzkocer oguzkocer added this to the 0.2 milestone Nov 5, 2024
@oguzkocer oguzkocer marked this pull request as ready for review November 5, 2024 21:26
@oguzkocer oguzkocer enabled auto-merge (squash) November 5, 2024 21:26
@oguzkocer oguzkocer changed the title Pagination Pagination support for /users Nov 5, 2024
Copy link
Contributor

@jkmassel jkmassel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested this from Swift and it worked great – the test coverage here is good, so I'm confident in the codegen stuff

@oguzkocer oguzkocer merged commit 575c737 into trunk Nov 12, 2024
22 checks passed
@oguzkocer oguzkocer deleted the pagination-params branch November 12, 2024 21:04
@jkmassel jkmassel mentioned this pull request Nov 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants