Skip to content

CMM-1177/CMM-1178 create the top post and referrers endpoints#1119

Merged
adalpari merged 24 commits intotrunkfrom
task/CMM-1177-create-the-top-post-endpoint
Feb 4, 2026
Merged

CMM-1177/CMM-1178 create the top post and referrers endpoints#1119
adalpari merged 24 commits intotrunkfrom
task/CMM-1177-create-the-top-post-endpoint

Conversation

@adalpari
Copy link
Contributor

@adalpari adalpari commented Jan 26, 2026

Summary

  • Adds new WordPress.com REST API endpoints for fetching site statistics:
    • Top Posts (/rest/v1.1/sites/<site_id>/stats/top-posts) - Returns most viewed posts/pages
    • Referrers (/rest/v1.1/sites/<site_id>/stats/referrers) - Returns traffic referrer sources

Implementation Details

New Files

Top Posts Endpoint:

  • wp_api/src/wp_com/stats_top_posts.rs - Types, parameters, response structures, and helper functions
  • wp_api/src/wp_com/endpoint/stats_top_posts_endpoint.rs - Endpoint definition
  • wp_api/tests/wpcom/stats_top_posts/top-posts-01.json - Test data fixture

Referrers Endpoint:

  • wp_api/src/wp_com/stats_referrers.rs - Types, parameters, response structures, and helper functions
  • wp_api/src/wp_com/endpoint/stats_referrers_endpoint.rs - Endpoint definition
  • wp_api/tests/wpcom/stats_referrers/referrers-01.json - Test data fixture

Modified Files

  • wp_api/src/wp_com/mod.rs - Module registration
  • wp_api/src/wp_com/endpoint.rs - Endpoint module registration
  • wp_api/src/wp_com/client.rs - Request builder and executor integration

API Parameters

Top Posts:

Parameter Type Description
period StatsTopPostsPeriod Time period grouping (day, week, month, year)
start_date String Start date in YYYY-MM-DD format
date String Query date in YYYY-MM-DD format
max u32 Maximum number of top posts to return

Referrers:

Parameter Type Description
period StatsReferrersPeriod Time period grouping (day, week, month, year)
date String Query date in YYYY-MM-DD format
start_date String Start date in YYYY-MM-DD format
max u32 Maximum number of referrers to return

Helper Functions

Top Posts:

  • get_stats_top_posts_all_post_views() - Returns all post views from all days
  • get_stats_top_posts_for_date() - Returns post views for a specific date
  • get_stats_top_posts_total_views() - Returns total views across all days

Referrers:

  • get_stats_referrers_all_groups() - Returns all referrer groups from all days
  • get_stats_referrers_for_date() - Returns referrer data for a specific date
  • get_stats_referrers_total_views() - Returns total views across all days

Notable Implementation Details

The referrers endpoint has a polymorphic results field that can be either:

  • A simple views object: {"views": 12}
  • A detailed referrer array (e.g., for Search Engines): [{"name": "Google Search", ...}]

This is handled using #[serde(untagged)] enum (StatsReferrersResults).

@adalpari adalpari marked this pull request as ready for review January 26, 2026 11:56
@adalpari adalpari changed the title CMM-1177 create the top post endpoint CMM-1177/CMM-1178 create the top post and referrers endpoints Jan 26, 2026
@adalpari adalpari requested a review from jkmassel January 26, 2026 14:02
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.

Good start – this properly parsed both https://public-api.wordpress.com/rest/v1.1/sites/en.blog.wordpress.com/stats/referrers and https://public-api.wordpress.com/rest/v1.1/sites/en.blog.wordpress.com/stats/top-posts (with summarize=1).

Left some inline suggestions.


/// Parameters for the stats referrers endpoint.
#[derive(Debug, Default, PartialEq, Eq, uniffi::Record)]
pub struct StatsReferrersParams {
Copy link
Contributor

Choose a reason for hiding this comment

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

This needs to take a locale param – that's used to translate the response's strings (for example "Search Engines").

It should probably be an enum that matches WP.com locales - @crazytonyli wdyt about using WPComLanguage from #1011?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch! Added here

Copy link
Contributor

Choose a reason for hiding this comment

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

wdyt about using WPComLanguage?

That makes sense to me. I presume the local argument in this request is treated as the same as WPComLanguage.slug in the backend.

@adalpari adalpari requested a review from jkmassel January 28, 2026 13:31
Comment on lines 350 to 353
#[rstest]
#[case("tests/wpcom/stats_referrers/referrers-01.json")]
#[case("tests/wpcom/stats_referrers/referrers-03-follow-data-false.json")]
#[case("tests/wpcom/stats_referrers/referrers-04-real-response.json")]
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a good parameterized test, but should include all of the test cases you've defined. Even if they're used for a more specific test, running every valid json test case you have through the generic deserialization test is more likely to catch issues.

Said another way – you have the data anyway, might as well use it :)

Copy link
Contributor Author

@adalpari adalpari Jan 29, 2026

Choose a reason for hiding this comment

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

You are right. The problem is that because of the endpoint specifications, some JSON files are different.
For instance, referrers-02-days.json has no period field. So, it cannot be included in this general test.
However, there's a specific test for it.

Note: I've added referrers-05-with-nulls.json, though, and an extra check.

Done here: 2c589f4

Copy link
Contributor

Choose a reason for hiding this comment

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

For instance, referrers-02-days.json has no period field

This seems odd – https://public-api.wordpress.com/rest/v1.1/sites/en.blog.wordpress.com/stats/referrers?summarize=1&period=day has a period field, but https://public-api.wordpress.com/rest/v1.1/sites/en.blog.wordpress.com/stats/referrers?period=day does not. Should we be using the former?

@jkmassel jkmassel force-pushed the task/CMM-1177-create-the-top-post-endpoint branch from 2c589f4 to 8f31d58 Compare January 29, 2026 21:49
@jkmassel jkmassel force-pushed the task/CMM-1177-create-the-top-post-endpoint branch from 8f31d58 to d0ec9a0 Compare January 29, 2026 22:54
@jkmassel
Copy link
Contributor

To help land this quicker, I've:

  1. Rebased this PR atop trunk now that Add language endpoint and database #1011 and Rework WP.com e2e tests to remove custom test harness and run in CI #1126 have landed.
  2. Opened Cmm 1177 suggestions #1133 with an implementation of the WP.com e2e tests covering these new endpoints.

Still to do – if we really need both summarize=1 and summarize=0, we should support both. The fact that we can't run the parser tests over all of our JSON files means something's not quite right – we should be able to (if they have different expectations – like one should always have Some summary, for instance, that can be baked into the test definition and doesn't need to be part of the test function body.

@adalpari
Copy link
Contributor Author

To help land this quicker, I've:

  1. Rebased this PR atop trunk now that Add language endpoint and database #1011 and Rework WP.com e2e tests to remove custom test harness and run in CI #1126 have landed.
  2. Opened Cmm 1177 suggestions #1133 with an implementation of the WP.com e2e tests covering these new endpoints.

Thank you!!

Still to do – if we really need both summarize=1 and summarize=0, we should support both. The fact that we can't run the parser tests over all of our JSON files means something's not quite right – we should be able to (if they have different expectations – like one should always have Some summary, for instance, that can be baked into the test definition and doesn't need to be part of the test function body.

We are already supporting both outputs. In tests, we can parse both as well (but in different tests).
However, given that each test checks different output fields, they cannot be mixed. One test checks period and summary.groups, while the other one checks summary.is_none() and days.is_some().

I've tried to follow your suggestion about "baking it into the test definition". So, let me know if you think this is a good approach: fde295e

jkmassel and others added 3 commits February 3, 2026 10:00
* Add WP.com e2e tests

fx

* Use `WPComLanguage` for locale

* Explicitly specify `summarize` for for all requests
…om:Automattic/wordpress-rs into task/CMM-1177-create-the-top-post-endpoint
@adalpari
Copy link
Contributor Author

adalpari commented Feb 3, 2026

Tests renaming 6a1917f

@adalpari adalpari merged commit 76cc78d into trunk Feb 4, 2026
23 checks passed
@adalpari adalpari deleted the task/CMM-1177-create-the-top-post-endpoint branch February 4, 2026 14:38
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

Successfully merging this pull request may close these issues.

3 participants