This PR addresses two problems that exist between the frontend and the API:
Ambiguity for a player existing, but not having data for a ruleset
Not being able to request stats for a player's default ruleset
To address the first problem, some changes were made to the way stat generation works. Now, if a request to /stats/{key} specifies a ruleset but the player has no data, instead of returning a 404 Not Found, it will return a PlayerStatsDTO with only the playerInfo populated. The endpoint will now correctly return a 404 Not Found only if no player exists for the given key.
For the second problem, we are able to leverage the new settings storage to determine a player's preferred ruleset without having to specify it in the query. Now, if a request is made to /stats/{key} without specifying a ruleset, stats for the player's default ruleset will be returned. This allows us to mimic the functionality of the osu! website where navigating to a user page will display their preferred ruleset by default but still allowing the viewing user to switch to different rulesets if they wish.
As a bonus, this fixes most of the issues that existed API side with versatile search. Namely, issues with spaces (#238) and not being able to search for players by osu! id.
Breaking Changes
Endpoint Changes
Removed /stats/{id}
Functionality now combined with /stats/{key} using versatile search
Renamed /stats/{username} to /stats/{key}
Technically not breaking, but functionally allows key to be parsed as playerId, osuId, or username
Query parameters
Removed ?comparerId
Renamed ?mode to ?ruleset
Optional, If not provided the player's default is used (In the rare case where there is no default, standard is used as a fallback)
Example
Get stats for Stage for osu!std (his default ruleset is standard)
Request
// Result will be the same for "/stats/440" (player id) or "/stats/8191845" (osu! id)
fetch("otr.stagec.xyz/api/v1/stats/stage",
{
method: "GET",
headers: new Headers().append("Authorization", "Bearer {}")
});
Get stats for Stage for osu!catch (he has no data for catch)
Request
// Result will be the same for "/stats/440" (player id) or "/stats/8191845" (osu! id)
fetch("otr.stagec.xyz/api/v1/stats/stage?ruleset=2",
{
method: "GET",
headers: new Headers().append("Authorization", "Bearer {}")
});
Response (Still returns same schema, but all stat fields null)
This PR addresses two problems that exist between the frontend and the API:
To address the first problem, some changes were made to the way stat generation works. Now, if a request to
/stats/{key}
specifies a ruleset but the player has no data, instead of returning a404 Not Found
, it will return aPlayerStatsDTO
with only theplayerInfo
populated. The endpoint will now correctly return a404 Not Found
only if no player exists for the given key.For the second problem, we are able to leverage the new settings storage to determine a player's preferred ruleset without having to specify it in the query. Now, if a request is made to
/stats/{key}
without specifying a ruleset, stats for the player's default ruleset will be returned. This allows us to mimic the functionality of the osu! website where navigating to a user page will display their preferred ruleset by default but still allowing the viewing user to switch to different rulesets if they wish.As a bonus, this fixes most of the issues that existed API side with versatile search. Namely, issues with spaces (#238) and not being able to search for players by osu! id.
Breaking Changes
Endpoint Changes
/stats/{id}
/stats/{key}
using versatile search/stats/{username}
to/stats/{key}
key
to be parsed asplayerId
,osuId
, orusername
?comparerId
?mode
to?ruleset
Schema Changes
PlayerStatsDTO
(returns from/stats/{key}
)int
ruleset
playerInfo
andruleset
are now nullableCloses #238