You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I come from my inactivity to outline some improvements and refactoring for Gulag's API. Thanks to FastAPI, it is possible to implement some improvements that were much harder to do with cmyui_pkg. In my opinion, I think the current API (hereby referred to as v1) is should be deprecated and replaced with a v2. That being said, here are my takes for a future API.
:mode = <osu | mania | catch | taiko>
GET /api/v2/online : return total registered & online player counts. (? I have to think about this one)
GET /api/v2/player/:id : return info or stats for a given player.
GET /api/v2/player/:id/status : return a player's current status, if online. (should be a WebSocket)
GET /api/v2/player/:id/scores/<best | recent | most_played> : return a list of best, recent, or most played scores for a given player.
GET /api/v2/map/:id : return information about a given beatmap
GET /api/v2/map/:id/:mode : return information about a given beatmap for a mode.
GET /api/v2/map/:id/:mode/scores : return the best scores for a given beatmap & mode.
GET /api/v2/mapset/:id : return information about a given beatmapset
GET /api/v2/mapset/:id/:mode : return information about a given beatmapset for a mode.
GET /api/v2/mapset/:id/:mode/scores : return the best scores for a given beatmap & mode.
GET /api/v2/score/:id : return information about a given score.
GET /api/v2/score/:id/dl: return the file for a given replay (with or without headers).
GET /api/v2/match/:id : return information for a given multiplayer match.
GET /api/v2/leaderboard/<score | pp>/:mode : return the top players for a given mode & sort condition
GET /api/v2/leaderboard/country/:country_code/<score | pp>/:mode
mode might be optional, just defaults to osu!std
GET /api/v2/map/:id/calc/pp : calculates pp
GET /api/v2/map/:id/calc/score : calculates largest possible score
GET /api/v2/me : user information about oneself
PUT /api/v2/me/avatar : upload an avatar
GET /api/v2/search/players : searches players
GET /api/v2/search/maps : searches maps
GET /api/v2/search/mapsets : searches mapsets
GET /api/v2/search/scores : searches scores scores
GET /api/v2/player/from/:name : returns a player response / id from a name
Get rid of "monopaths" and use a RESTful path system. Instead of a single endpoint returning a certain JSON response, every model should have child paths that return related responses. /get_user_info would become /user, /get_player_scores would become /player/scores, etc. The get_ prefix is redundant, as any request other than an HTTP GET should be a 405 error. _info endpoints can be moved to the root model path (i.e. /user, /beatmap, /score). When requesting models that have an Id (aka all of them), it would be better to pass their Id in the path (i.e /user/124493). In my mind path variables are required whereas query parameters are optional. Models should have two types of response structures: Compact and Full. The full structure is returned whenever the model is by itself, while compact is returned when it is in a list. Search endpoints should return a list of compact responses. If one needs more information one must request the full response.
Pros
Easy to set up
Everyone knows how to use a REST API
Cons
Returns unused data (sometimes the client only wants a few fields from the returned data)
Limited by number of endpoints
Harder to Documnet
GraphQL
If you're unfamiliar, please take a look at the offical guide. It's a good read.
example query
query {
user(id: 124493) {
id
name
created_at
scores(type: RECENT) {
map {
title
}
pp
}
}
}
Imagine taking all the previous endpoints and condensing them into one: /graphql. Yep. Instead of having a path represent an entity, root queries that represent certain types of REST endpoints (in a way). For example, say we want to query a single user. We could have a query along the lines of user(id: 124493). Say we wanted multiple users. We can just do something like users(ids: [124493, 3]). This allows for much more flexibility. Also, no versioning!.
@cmyui I'd be happy to code up GraphQL. We can talk semantics on Discord.
Pros
Much more flexibility
More efficient data retrieval
Better bulk requests (you can send files as Base64)
Option of using subscription for WebSocket use (getting new scores via ws 💯 )
Better development environment (GraphiQL)
Cons
More difficult to setup (despite FastAPI having built-in support)
Not many people know graphql
Final Notes
It's late, I'm tired, I'll keep this short. We should pick either REST or GraphQL. I think having both would be complicated: stick to one and do it well. I'm on side GraphQL. Ok bye.
The text was updated successfully, but these errors were encountered:
sup gamers,
I come from my inactivity to outline some improvements and refactoring for Gulag's API. Thanks to FastAPI, it is possible to implement some improvements that were much harder to do with cmyui_pkg. In my opinion, I think the current API (hereby referred to as
v1
) is should be deprecated and replaced with av2
. That being said, here are my takes for a future API.In General
/api
rate limit via X-Ratelimit (good stack overflow about it)/api
only is 301 redirect to Rick Roll (le epic troll)REST
Here are all
v1
endpoints at the time of writing:https://github.com/cmyui/gulag/blob/e40ed8921eb62a7561ecb6d5042e7062bb6b9a61/mount/app/api/domains/api.py#L45-L63
Proposed Changes
Reasoning
see osu!api v2
Get rid of "monopaths" and use a RESTful path system. Instead of a single endpoint returning a certain JSON response, every model should have child paths that return related responses.
/get_user_info
would become/user
,/get_player_scores
would become/player/scores
, etc. Theget_
prefix is redundant, as any request other than anHTTP GET
should be a 405 error._info
endpoints can be moved to the root model path (i.e./user
,/beatmap
,/score
). When requesting models that have an Id (aka all of them), it would be better to pass their Id in the path (i.e/user/124493
). In my mind path variables are required whereas query parameters are optional. Models should have two types of response structures:Compact
andFull
. The full structure is returned whenever the model is by itself, while compact is returned when it is in a list. Search endpoints should return a list of compact responses. If one needs more information one must request the full response.Pros
Cons
GraphQL
If you're unfamiliar, please take a look at the offical guide. It's a good read.
example query
example response
Reasoning
Imagine taking all the previous endpoints and condensing them into one:
/graphql
. Yep. Instead of having a path represent an entity, root queries that represent certain types of REST endpoints (in a way). For example, say we want to query a single user. We could have a query along the lines ofuser(id: 124493)
. Say we wanted multiple users. We can just do something likeusers(ids: [124493, 3])
. This allows for much more flexibility. Also, no versioning!.@cmyui I'd be happy to code up GraphQL. We can talk semantics on Discord.
Pros
subscription
for WebSocket use (getting new scores via ws 💯 )Cons
Final Notes
It's late, I'm tired, I'll keep this short. We should pick either REST or GraphQL. I think having both would be complicated: stick to one and do it well. I'm on side GraphQL. Ok bye.
The text was updated successfully, but these errors were encountered: