Your task is to implement a service that maintains a "real-time" ranking of users playing a specific game.
Requirements:
- Clients submit user scores when they achieve important milestones in the game
- Clients can submit absolute scores or relative scores, for example: {"user" :123, "total": 250}, or {"user": 456, "score": "+10"}, or {"user": 789, score: "-20"}
- Any client can request the ranking at any time, using one of the following requests:
- Absolute ranking, for example: Top100, Top200, Top500
- Relative ranking, for instance: At100/3, meaning 3 users around position 100th of the ranking, that is positioned 97th, 98th, 99th, 100th, 101st, 102nd, 103rd
We propose that it have the following endpoints:
- [POST] user/{user_id}/score
- [GET] ranking?type=top100
- [GET] ranking?type=At100/3
- We prefer you to develop the test in one of the main languages we use at SP (PHP or Golang) but if you don't feel comfortable enough with them, feel free to choose any other
- Do not couple yourself to a specific framework, as the test is pretty simple we prefer to see how big is your knowledge of what goes under the hood
- Do not use any database or external storage system, just keep the ranking in-memory (NB if you use a stateless language there's no need to keep this storage anywhere after the process dies)
- The code must work and sort as specified in this document
- How you approach the project (we left some stuff intentionally open, so you have to evaluate trade-offs and make some decisions)
- How you design and architecture the system
- How you test and ensure the overall quality of the solution
- Docker with docker-compose
- Readme to explain how we can check the code
- Testing with full code coverage or important code for you
- Go 1.18
- Docker
- docker-compose
make local
make test
Since we can have two different submissions for the user (absolute or relative), the body must contain only one option, as described below:
Must be sent with the integer total
. This will set the user's total score.
If the user_id
sent didn't exist in the database, a new user will be created.
Example:
[POST]
http://0.0.0.0:8894/user/1/score
[JSON Body]
{
"total": 100
}
Must be sent with the string score
. This will add or subtracts from user's score, depending on the first character sent. The API only accepts score
which starts with +
or -
.
The user can have a negative score.
If the user_id
sent didn't exist in the database, a new user will be created.
Example:
[POST]
http://0.0.0.0:8894/user/1/score
[JSON Body]
{
"score": "+20"
}
Response:
For both scenarios, the response will be the same, in case of success. A JSON containing the user_id
, and the current score
.
{
"user_id": 1,
"score": 100
}
In order to request the ranking, you need to set what kind of ranking do you want to see: absolute or relative. That said, the API will only accept the followin types as a parameter:
In this scenario, you must use the type top
, followed by the number of users that you want in the ranking. The number must be greater than 0.
Example:
Below we define type
as top3
, meaning that we want the 3 top players from our ranking.
[GET]
http://0.0.0.0:8894/ranking?type=top3
Response:
{
"ranking": [
{
"position": 1,
"user_id": 3,
"score": 452
},
{
"position": 2,
"user_id": 2,
"score": 101
},
{
"position": 3,
"user_id": 1,
"score": 5
}
]
}
In this scenario, you must use the type at
, followed by the position you want in the ranking, a /
, and a number of users around that position. Both numbers must be greater than 0.
Example:
Below we define type
as at10/2
, meaning 2 users around position 10th of the ranking, that is positioned 8th, 9th, 10th, 11th, 12th.
[GET]
http://0.0.0.0:8894/ranking?type=at10/2
Response:
{
"ranking": [
{
"position": 7,
"user_id": 12,
"score": 34
},
{
"position": 8,
"user_id": 7,
"score": 27
},
{
"position": 9,
"user_id": 9,
"score": 24
},
{
"position": 10,
"user_id": 8,
"score": 19
},
{
"position": 11,
"user_id": 4,
"score": 2
},
{
"position": 12,
"user_id": 5,
"score": -72
}
]
}
Edge case:
If you set your type as at1/3
, you'll see the the top 1 user, and the 3 users next to her/him.
ENV VAR | DESCRIPTION | DEFAULT |
---|---|---|
HOST | service host | 0.0.0.0 |
PORT | service port | 8884 |