mirror of
https://github.com/Steffo99/distributed-arcade.git
synced 2024-11-21 23:54:25 +00:00
344 lines
11 KiB
YAML
344 lines
11 KiB
YAML
openapi: 3.0.3
|
|
|
|
info:
|
|
title: "Distributed Arcade"
|
|
version: 1.0.0
|
|
description: |-
|
|
A super-fast high score gatherer using Rust and Redis.
|
|
|
|
It allows the creation of _boards_, [sorted sets](https://redis.io/docs/data-types/sorted-sets/) that can be used to track the scores of players in videogames.
|
|
|
|
It is written to be extremely fast and scalable: it should be able to receive bursts of many requests.
|
|
|
|
Errors can be distinguished from successful requests via HTTP status codes >=400.
|
|
contact:
|
|
name: "Stefano Pigozzi"
|
|
url: "https://www.steffo.eu"
|
|
email: "me@steffo.eu"
|
|
license:
|
|
name: "GNU Affero General Public License v3.0 or later"
|
|
url: "https://github.com/Steffo99/distributed-arcade/blob/main/LICENSE.txt"
|
|
|
|
servers:
|
|
- url: "https://arcade.steffo.eu"
|
|
description: "Experimental production server"
|
|
- url: "http://127.0.0.1:30000"
|
|
description: "Local development server"
|
|
|
|
tags:
|
|
- name: "Home"
|
|
description: "Launch checklist"
|
|
- name: "Board"
|
|
description: "About boards"
|
|
- name: "Score"
|
|
description: "Submit scores"
|
|
|
|
paths:
|
|
/:
|
|
get:
|
|
operationId: "getHome"
|
|
summary: "Verify that the web server is working as expected"
|
|
description: |-
|
|
This method simply echoes back a response, and can be used to verify that the API web server is working.
|
|
tags: ["Home"]
|
|
responses:
|
|
204:
|
|
description: "Working as expected"
|
|
post:
|
|
operationId: "postHome"
|
|
summary: "Verify that everything is working as expected"
|
|
description: |-
|
|
This method is like `GET /`, but it also `PING`s the Redis server to ensure it is working and configured properly.
|
|
tags: ["Home"]
|
|
responses:
|
|
204:
|
|
description: "Working as expected"
|
|
500:
|
|
description: "Did not receive `PONG` from redis"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: string
|
|
example: "Redis gave an unexpected response"
|
|
502:
|
|
$ref: "#/components/responses/RedisCmdFailed"
|
|
504:
|
|
$ref: "#/components/responses/RedisConnFailed"
|
|
|
|
/board/:
|
|
get:
|
|
operationId: "getBoard"
|
|
summary: "Get the scores of a board"
|
|
description: |-
|
|
This method requests a page of scores from a board using the [`ZSCAN`](https://redis.io/commands/zscan/) Redis command.
|
|
|
|
An offset must be specified to start returning scores from a certain index.
|
|
The number of responses to return must be specified as well.
|
|
tags: ["Board"]
|
|
parameters:
|
|
- $ref: "#/components/parameters/board"
|
|
- $ref: "#/components/parameters/offset"
|
|
- $ref: "#/components/parameters/size"
|
|
responses:
|
|
200:
|
|
description: "Scores retrieved successfully"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
type: object
|
|
description: "A score submitted by an user."
|
|
properties:
|
|
name:
|
|
type: string
|
|
description: "The name of the user who submitted the score."
|
|
example: "Steffo"
|
|
score:
|
|
type: number
|
|
description: "The submitted score."
|
|
example: 1234.56
|
|
502:
|
|
$ref: "#/components/responses/RedisCmdFailed"
|
|
504:
|
|
$ref: "#/components/responses/RedisConnFailed"
|
|
post:
|
|
operationId: "postBoard"
|
|
summary: "Create a new board"
|
|
description: |-
|
|
This method creates a new board.
|
|
|
|
It returns its _score submission token_ (`XBoardToken` in this spec), which is required to submit new scores to the board.
|
|
|
|
Boards can use two different orders:
|
|
|
|
- using the `Ascending` order, lower scores are better ranked than higher scores, like in racing games or golf;
|
|
- using the `Descending` order, higher scores are better ranked than lower scores, like in arcade games or athletics.
|
|
|
|
**WARNING: Once created, a board cannot be edited or deleted, and its token will not be accessible any longer!**
|
|
|
|
Requires an authorization key, set as the `CREATE_TOKEN` environment variable of the server.
|
|
tags: ["Board"]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
name:
|
|
type: string
|
|
description: "The name of the board to create. It will be converted to kebab-case."
|
|
example: "gravityfusion"
|
|
order:
|
|
type: string
|
|
example: "Descending"
|
|
description: "The ordering of the board, either ascending or descending."
|
|
enum:
|
|
- "Ascending"
|
|
- "Descending"
|
|
security:
|
|
- XCreateToken: []
|
|
responses:
|
|
201:
|
|
description: "Board created successfully"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: string
|
|
example: "W4SbhbJ3tnGaIM1S"
|
|
links:
|
|
getScore:
|
|
operationId: "getScore"
|
|
parameters:
|
|
board: "$response.body/name"
|
|
putScore:
|
|
operationId: "putScore"
|
|
parameters:
|
|
board: "$response.body/name"
|
|
401:
|
|
description: "Missing, invalid or malformed Authorization header"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: string
|
|
example: "Missing Authorization header"
|
|
403:
|
|
description: "Invalid create token"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: string
|
|
example: "Invalid create token"
|
|
409:
|
|
description: "Board already exists"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: string
|
|
example: "Board already exists"
|
|
500:
|
|
description: "Could not generate secure board token"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: string
|
|
example: "Could not generate secure board token"
|
|
502:
|
|
$ref: "#/components/responses/RedisCmdFailed"
|
|
504:
|
|
$ref: "#/components/responses/RedisConnFailed"
|
|
|
|
/score/:
|
|
get:
|
|
operationId: "getScore"
|
|
summary: "Get a score from a board"
|
|
description: |-
|
|
Retrieve the score and the position that the given user has on the leaderboard.
|
|
tags: ["Score"]
|
|
parameters:
|
|
- $ref: "#/components/parameters/board"
|
|
- $ref: "#/components/parameters/player"
|
|
responses:
|
|
200:
|
|
description: "Score retrieved successfully"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
score:
|
|
type: number
|
|
description: "The score of the specified player."
|
|
example: 1234.56
|
|
rank:
|
|
type: integer
|
|
description: "The zero-indexed rank of the specified player. (You may probably want to add `1` before displaying it to an user.)"
|
|
example: 0
|
|
502:
|
|
$ref: "#/components/responses/RedisCmdFailed"
|
|
504:
|
|
$ref: "#/components/responses/RedisConnFailed"
|
|
|
|
put:
|
|
operationId: "putScore"
|
|
summary: "Submit a score to a board"
|
|
tags: ["Score"]
|
|
parameters:
|
|
- $ref: "#/components/parameters/board"
|
|
- $ref: "#/components/parameters/player"
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: number
|
|
description: "The score to submit to the board."
|
|
example: 1234.56
|
|
security:
|
|
- XBoardToken: []
|
|
responses:
|
|
200:
|
|
description: "Score discarded as it was worse than the previous one"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
score:
|
|
type: number
|
|
description: "The score of the specified player."
|
|
example: 1234.56
|
|
rank:
|
|
type: integer
|
|
description: "The zero-indexed rank of the specified player. (You may probably want to add `1` before displaying it to an user.)"
|
|
example: 0
|
|
201:
|
|
description: "Score submitted and updated"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
score:
|
|
type: number
|
|
description: "The score of the specified player."
|
|
example: 2468.13
|
|
rank:
|
|
type: integer
|
|
description: "The zero-indexed rank of the specified player. (You may probably want to add `1` before displaying it to an user.)"
|
|
example: 0
|
|
401:
|
|
description: "Missing, invalid or malformed Authorization header"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: string
|
|
example: "Missing Authorization header"
|
|
403:
|
|
description: "Invalid board token"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: string
|
|
example: "Invalid board token"
|
|
502:
|
|
$ref: "#/components/responses/RedisCmdFailed"
|
|
504:
|
|
$ref: "#/components/responses/RedisConnFailed"
|
|
|
|
|
|
components:
|
|
securitySchemes:
|
|
XCreateToken:
|
|
type: http
|
|
scheme: "bearer"
|
|
bearerFormat: "setInEnvVars"
|
|
XBoardToken:
|
|
type: http
|
|
scheme: "bearer"
|
|
bearerFormat: "gVsuzIxgVfRx4RNl"
|
|
|
|
parameters:
|
|
board:
|
|
name: "board"
|
|
description: "The name of the board to operate on."
|
|
in: query
|
|
schema:
|
|
type: string
|
|
player:
|
|
name: "player"
|
|
description: "The name of the player to operate on."
|
|
in: query
|
|
schema:
|
|
type: string
|
|
offset:
|
|
name: "offset"
|
|
description: "The offset to start returning results from."
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
size:
|
|
name: "size"
|
|
description: "How many results to return."
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
minimum: 0
|
|
maximum: 500
|
|
|
|
responses:
|
|
RedisCmdFailed:
|
|
description: "Could not execute Redis command"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: string
|
|
example: "Could not execute Redis command"
|
|
RedisConnFailed:
|
|
description: "Could not connect to Redis"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: string
|
|
example: "Could not connect to Redis"
|