Overview

HTTP verbs

Ponyracer tries to adhere to REST conventions in its use of HTTP verbs.

Verb Usage

GET

Used to retrieve a resource

POST

Used to create a new resource

PUT

Used to update an existing resource

DELETE

Used to delete an existing resource

HTTP status codes

Ponyracer tries to adhere to standard HTTP conventions in its use of HTTP status codes.

Status code Usage

200 OK

The request completed successfully

201 Created

A new resource has been created successfully. Usually, the created resource is sent back in the response payload

204 No Content

An existing resource has been updated or deleted successfully

400 Bad Request

The request was malformed. The response body will include an error providing further information

401 Unauthorized

You need to be authenticated to access this resource. This indicates that the request doesn’t have, or has an invalid Authorization header

404 Not Found

The requested resource did not exist

417 Expectation failed

The action could not be completed due to a validation problem. For example, registering a user with a login that is already used. The response body will include an error providing further information

Resources

Users

Users can be listed. A user can be created (registration) or obtained. A user can also be authenticated.

Listing users

A GET request is used to list users. This only returns the latest registered users, though.

Example request

GET /api/users HTTP/1.1
Host: ponyracer.ninja-squad.com

Example response

HTTP/1.1 200 OK

[ {
  "id" : 2,
  "login" : "jb",
  "money" : 1000,
  "registrationInstant" : "2015-12-01T12:00:00Z"
}, {
  "id" : 1,
  "login" : "cexbrayat",
  "money" : 1000,
  "registrationInstant" : "2015-12-01T11:00:00Z"
} ]

Registering a user

A POST request is used to register a new user

Example request

POST /api/users HTTP/1.1
Host: ponyracer.ninja-squad.com

{
  "login" : "cexbrayat",
  "password" : "password",
  "birthYear" : 1980
}

Example response

HTTP/1.1 201 Created

{
  "id" : 1,
  "login" : "cexbrayat",
  "money" : 1000,
  "registrationInstant" : "2015-12-01T11:00:00Z",
  "token" : "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjF9._n2W-_vlURnEpYRFqX1P8H6cYMlBgFAIRqgNPsIVj98"
}
Path Type Description

id

Number

The ID of the created user.

money

Number

The amount of money that the user has to bet on ponies.

token

String

The JWT token to use for subsequent requests, in order to identify as the created user. This token must be used as a header: Authorization: Bearer <token>

Getting a user

A GET request is used to get a user by ID

Table 1. /api/users/{id}
Parameter Description

id

The user ID

Example request

GET /api/users/1 HTTP/1.1
Host: ponyracer.ninja-squad.com

Example response

HTTP/1.1 200 OK

{
  "id" : 1,
  "login" : "cexbrayat",
  "money" : 1000,
  "registrationInstant" : "2015-12-01T11:00:00Z"
}

Authenticating a user

A POST request is used to authenticate

Example request

POST /api/users/authentication HTTP/1.1
Host: ponyracer.ninja-squad.com

{
  "login" : "cexbrayat",
  "password" : "password"
}

Example response

HTTP/1.1 201 Created

{
  "id" : 1,
  "login" : "cexbrayat",
  "money" : 1000,
  "registrationInstant" : "2015-12-01T11:00:00Z",
  "token" : "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjF9._n2W-_vlURnEpYRFqX1P8H6cYMlBgFAIRqgNPsIVj98"
}
Path Type Description

id

Number

The ID of the created user.

money

Number

The amount of money that the user has to bet on ponies.

token

String

The JWT token to use for subsequent requests, in order to identify as the created user. This token must be used as a header: Authorization: Bearer <token>

Races

Races can be listed and obtained. A race always has 5 ponies, and all ponies of a race have a distinct color.

Listing races

A GET request is used to list races

Example request

GET /api/races HTTP/1.1
Host: ponyracer.ninja-squad.com

Example response

HTTP/1.1 200 OK

[ {
  "id" : 1234,
  "name" : "Lyon",
  "ponies" : [ {
    "id" : 4,
    "name" : "Superb Runner",
    "color" : "BLUE"
  }, {
    "id" : 1,
    "name" : "Awesome Fridge",
    "color" : "GREEN"
  }, {
    "id" : 3,
    "name" : "Great Bottle",
    "color" : "ORANGE"
  }, {
    "id" : 7,
    "name" : "Little Flower",
    "color" : "YELLOW"
  }, {
    "id" : 10,
    "name" : "Nice Rock",
    "color" : "PURPLE"
  } ],
  "startInstant" : "2022-12-02T09:51:00Z",
  "status" : "PENDING"
}, {
  "id" : 1235,
  "name" : "London",
  "ponies" : [ {
    "id" : 3,
    "name" : "Great Bottle",
    "color" : "ORANGE"
  }, {
    "id" : 1,
    "name" : "Awesome Fridge",
    "color" : "GREEN"
  }, {
    "id" : 10,
    "name" : "Nice Rock",
    "color" : "PURPLE"
  }, {
    "id" : 15,
    "name" : "Gentle Whiskey",
    "color" : "BLUE"
  }, {
    "id" : 12,
    "name" : "Nasty Soda",
    "color" : "YELLOW"
  } ],
  "startInstant" : "2022-12-02T09:52:00Z",
  "status" : "PENDING"
} ]
Path Type Description

[].ponies

Array

The ponies running in the race.

[].startInstant

String

The instant when the race starts, in ISO format.

[].status

String

The status of the race. Can be one of PENDING, RUNNING, FINISHED.

Listing pending races

Most of the time, you don’t care about finished races, and only want the pending races, on which you can still bet. These races can be listed by specifying a query parameter.

Example request

GET /api/races?status=PENDING HTTP/1.1
Host: ponyracer.ninja-squad.com
Parameter Description

status

The status of the races you’re interested into. Can be one of PENDING, RUNNING, FINISHED.

Getting a race

A GET request is used to get a race, by ID. In addition to the information provided when listing races, this service also provides the pony on which you bet in that race (if you bet on one before, of course).

Table 2. /api/races/{id}
Parameter Description

id

The ID of the race you want to get

Example request

GET /api/races/1234 HTTP/1.1
Host: ponyracer.ninja-squad.com

Example response

HTTP/1.1 200 OK

{
  "id" : 1234,
  "name" : "Lyon",
  "ponies" : [ {
    "id" : 4,
    "name" : "Superb Runner",
    "color" : "BLUE"
  }, {
    "id" : 1,
    "name" : "Awesome Fridge",
    "color" : "GREEN"
  }, {
    "id" : 3,
    "name" : "Great Bottle",
    "color" : "ORANGE"
  }, {
    "id" : 7,
    "name" : "Little Flower",
    "color" : "YELLOW"
  }, {
    "id" : 10,
    "name" : "Nice Rock",
    "color" : "PURPLE"
  } ],
  "startInstant" : "2022-12-02T09:51:00Z",
  "status" : "PENDING",
  "betPonyId" : 1
}
Path Type Description

ponies

Array

The ponies running in the race.

startInstant

String

The instant when the race starts, in ISO format.

status

String

The status of the race. Can be one of PENDING, RUNNING, FINISHED.

betPonyId

Number

The ID of the pony on which you bet. Absent if you placed no bet on this race.

Bets

You can place a bet on a pony in a race. Several preconditions must be verified to be able to place a bet:

  • you must be authenticated (see the example Authorization header in the following example requests)

  • the race must not be started or finished (i.e. it must be pending)

  • you must have enough money left to place the bet

Placing a bet on a pony automatically cancels the previous bet you might already have on another pony of the same race.

A bet can be cancelled.

Placing a bet

A POST request is used to bet on a pony in a race.

Table 3. /api/races/{raceId}/bets
Parameter Description

raceId

The ID of the race in which you place a bet.

Example request

POST /api/races/1234/bets HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjF9._n2W-_vlURnEpYRFqX1P8H6cYMlBgFAIRqgNPsIVj98
Host: ponyracer.ninja-squad.com

{
  "ponyId" : 1
}
Path Type Description

ponyId

Number

The ID of the pony on which you place a bet.

Example response

HTTP/1.1 200 OK

{
  "id" : 1234,
  "name" : "Lyon",
  "ponies" : [ {
    "id" : 4,
    "name" : "Superb Runner",
    "color" : "BLUE"
  }, {
    "id" : 1,
    "name" : "Awesome Fridge",
    "color" : "GREEN"
  }, {
    "id" : 3,
    "name" : "Great Bottle",
    "color" : "ORANGE"
  }, {
    "id" : 7,
    "name" : "Little Flower",
    "color" : "YELLOW"
  }, {
    "id" : 10,
    "name" : "Nice Rock",
    "color" : "PURPLE"
  } ],
  "startInstant" : "2022-12-02T09:51:00Z",
  "status" : "PENDING",
  "betPonyId" : 1
}

Cancelling a bet

A DELETE request is used to cancel your bet in a race.

Table 4. /api/races/{raceId}/bets
Parameter Description

raceId

The ID of the race in which you cancel your bet.

Example request

DELETE /api/races/1234/bets HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjF9._n2W-_vlURnEpYRFqX1P8H6cYMlBgFAIRqgNPsIVj98
Host: ponyracer.ninja-squad.com

Example response

HTTP/1.1 204 No Content

Boosts

You can boost a pony in a race. The race must be started, but not finished (i.e. it must be running) to be able to boost one of its ponies.

Boosting a pony will make it go faster for a short while, and that will be reflected in the boosted flag of the pony received by the WebSocket notifications.

Boosting a pony

A POST request is used to boost a pony in a race.

Table 5. /api/races/{raceId}/boosts
Parameter Description

raceId

The ID of the race in which you boost a pony.

Example request

POST /api/races/1234/boosts HTTP/1.1
Host: ponyracer.ninja-squad.com

{
  "ponyId" : 1
}
Path Type Description

ponyId

Number

The ID of the pony that you want to boost.

Example response

HTTP/1.1 204 No Content

Money history

You can get the history of the evolution of your money.

Listing your money history

A GET request is used to get your money history. The returned elements are sorted chronologically.

Example request

GET /api/money/history HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjF9._n2W-_vlURnEpYRFqX1P8H6cYMlBgFAIRqgNPsIVj98
Host: ponyracer.ninja-squad.com

Example response

HTTP/1.1 200 OK

[ {
  "instant" : "2017-08-03T10:40:00Z",
  "money" : 10000
}, {
  "instant" : "2017-08-04T09:15:00Z",
  "money" : 9800
}, {
  "instant" : "2017-08-04T11:15:00Z",
  "money" : 10600
} ]

WebSocket communication

The server pushes notifications, using Stomp over WebSocket, on various channels.

The first step to receive these notifications is to open a WebSocket connection on wss://ponyracer.ninja-squad.com/ws.

Then you can subscribe to the following Stomp channels:

  • /race/{raceId} to be notified of the changing positions of the ponies while the race is running.

  • /player/{userId} to be notified when the amount of money of a user changes (i.e. after placing a bet, or winning a bet)

Getting positions of ponies

Every time the positions of ponies change (every second in a running race), a notification is broadcast containing the ponies with their position and the status of the race. The position goes from 0 to 100. The first pony (or ponies) to get to 100 wins the race. The race finishes as soon as one position reaches 100. At this time, a message is sent with the race status RUNNING and a last message is emitted right after with the same positions and the status FINISHED. Ponies are always listed in the same order.

Example notification payload

{
  "ponies" : [ {
    "id" : 4,
    "name" : "Superb Runner",
    "color" : "BLUE",
    "position" : 29,
    "boosted" : false
  }, {
    "id" : 1,
    "name" : "Awesome Fridge",
    "color" : "GREEN",
    "position" : 20,
    "boosted" : false
  }, {
    "id" : 3,
    "name" : "Great Bottle",
    "color" : "ORANGE",
    "position" : 26,
    "boosted" : false
  }, {
    "id" : 7,
    "name" : "Little Flower",
    "color" : "YELLOW",
    "position" : 25,
    "boosted" : false
  }, {
    "id" : 10,
    "name" : "Nice Rock",
    "color" : "PURPLE",
    "position" : 27,
    "boosted" : false
  } ],
  "status" : "RUNNING"
}

Getting score updates

Every time the score of the user changes (after a bet or when the bet is won), a notification is broadcast with the user info.

Example notification payload

{
  "id" : 1,
  "login" : "cexbrayat",
  "money" : 1000,
  "registrationInstant" : "2015-12-01T11:00:00Z"
}