186 lines
8.1 KiB
Markdown
186 lines
8.1 KiB
Markdown
# README
|
|
|
|
This is the REST API server for the online Paco Ŝako chess variation front-end
|
|
provided by the [paco-sako](https://jessemcdonald.info/gogs/nybble/paco_sako)
|
|
package. The server stores game data in a SQLite3 database and exposes
|
|
interfaces for immediate queries, long-polling, and POST updates. The
|
|
listening port is configurable and HTTPS is supported with a certificate file.
|
|
|
|
## Invocation
|
|
|
|
```
|
|
node ./server.js [PORT]
|
|
```
|
|
|
|
## Environment Variables
|
|
|
|
### `OPENSHIFT_NODEJS_PORT`, `VCAP_APP_PORT`, or `PORT`
|
|
|
|
If any of these variables are defined, the first one encountered determines
|
|
the listening port, overriding any port specified on the command line. The
|
|
default port is 8765 if no environment variable is defined and no port is
|
|
given on the command line.
|
|
|
|
### `HTTPS_KEY`, `HTTPS_CERT`
|
|
|
|
If the `HTTPS_KEY` environment variable is defined then the server operates in
|
|
HTTPS mode using the key found in the file named by `HTTPS_KEY` and the
|
|
certificate found in the file named by `HTTPS_CERT`. If `HTTPS_KEY` is set
|
|
then `HTTPS_CERT` is also required.
|
|
|
|
## JSON Schema
|
|
|
|
Most APIs either accept or return a JSON "game data" object with some or all
|
|
of the following fields:
|
|
|
|
* `gameId`: String. Sixteen hexadecimal characters. The randomly-generated
|
|
code which uniquely identifies a game.
|
|
|
|
* `lightName`: String. The name of the player controlling the light pieces.
|
|
|
|
* `darkName`: String. The name of the player controlling the dark pieces.
|
|
|
|
* `moves`: Integer. The number of partial *or* completed *turns* in the current
|
|
game. Also the number of times the light player has started a move. (The use
|
|
of the name `moves` rather than `turns` is a historical artifact.)
|
|
|
|
* `status`: String. A short string which describes the current state of the
|
|
game, for example the current player if the game is ongoing or the winner
|
|
otherwise. This string appers in the game selection list.
|
|
|
|
* `timestamp`: Integer. The UTC time in milliseconds (`+new Date()`) of the
|
|
most recent move. Typically the same as the `timestamp` metadata associated
|
|
with the last move in `board.past`, or the time when the metadata was most
|
|
recently updated if there are no moves. The timestamp can decrease, for
|
|
example in response to a player undoing a move.
|
|
|
|
* `board`: Object. An arbitrary JSON object provided by the front-end to
|
|
describe the current state of the game. The object is not validated by the
|
|
server at present but it typically includes two fields, `past` and `future`,
|
|
which are arrays of objects respectively representing the moves completed
|
|
thus far and (in reverse order) any moves which were undone, to support the
|
|
redo operation. This object is stored in the database as a JSON-encoded
|
|
string.
|
|
|
|
* `modified`: Integer. The modification timestamp of the record, as determined
|
|
by the server. This is normally a UTC time in milliseconds but the server
|
|
adjusts the value to ensure that updates have modification times which are
|
|
strictly greater than any modification times previously stored in the
|
|
database.
|
|
|
|
The "metadata" fields are all the fields listed above except `board`. The
|
|
`board` field is potentially large and consequently is omitted from the
|
|
responses for certain APIs.
|
|
|
|
Fields which are either NULL or equal to an empty string are not included in
|
|
game objects returned from the REST APIs.
|
|
|
|
The following data is stored in the database but not included in any REST API:
|
|
|
|
* `added`: The value of the `modified` field at the point where the game
|
|
record was first inserted into the database.
|
|
|
|
## REST APIs
|
|
|
|
### `GET /pacosako/api/games`
|
|
|
|
Returns the list of active games. A game is considered "active" if the
|
|
`timestamp` field indicates that the game was started or the last move was
|
|
played within the past two weeks, according to the server's clock. The
|
|
successful JSON response consists of two fields, `games` which is an array of
|
|
game objects in descending order by their `timestamp` fields, and `modified`
|
|
which is the maximum of the `modified` field for any of the games in the
|
|
`games` array. The objects in the `games` array include all of the game object
|
|
fields described above *except* the `board` field.
|
|
|
|
### `GET /pacosako/api/games/poll/:afterTime`
|
|
|
|
Parameters:
|
|
|
|
* `afterTime`: Integer. Any record with a `modified` field less than or equal
|
|
to this value is excluded from the results.
|
|
|
|
Equivalent to the `GET /pacosako/api/games` API with two exceptions. First, it
|
|
excludes games with older `modified` times from the results. Second, if there
|
|
are no results which match this criteria then the server waits up to one
|
|
minute for the situation to change before responding with a 204 status code.
|
|
It is expected that the client will respond to a 204 status by repeating the
|
|
request. If a game is updated during the waiting period then the server will
|
|
respond immediately with the new information.
|
|
|
|
The `afterTime` parameter will normally match the `modified` field from the
|
|
most recent successful response to either `GET /pacosako/api/games` or `GET
|
|
/pacosako/api/games/poll/:afterTime`.
|
|
|
|
### `GET /pacosako/api/game/:gameId`
|
|
|
|
Parameters:
|
|
|
|
* `gameId`: String. Identifies the game object to be returned.
|
|
|
|
On success this API returns the complete game object for the given `gameId`,
|
|
which must be a 16-character hexadecimal string. If there is no record
|
|
matching the given gameId then a 404 status code is returned.
|
|
|
|
### `GET /pacosako/api/meta/:gameId`
|
|
|
|
This API is identical to `GET /pacosako/api/game/:gameId` except that the
|
|
`board` field is omitted from the response.
|
|
|
|
### `GET /pacosako/api/game/:gameId/poll/:afterTime`
|
|
|
|
Parameters:
|
|
|
|
* `gameId`: String. Identifies the game object to be returned.
|
|
|
|
* `afterTime`: Integer. The response must be a game object with a `modified`
|
|
field strictly greater than this value.
|
|
|
|
Equivalent to the `GET /pacosako/api/game/:gameId` API except that if there is
|
|
no record with a matching `gameId` or the record has a `modified` field less
|
|
than or equal to the `afterTime` parameter then the server waits up to one
|
|
minute for the situation to change before responding with a 204 status code.
|
|
It is expected that the client will respond to a 204 status by repeating the
|
|
request. If the game is created or updated during the waiting period then the
|
|
server will respond immediately with the new information. Unlike the
|
|
non-polling version, this API does not return a 404 status code when the
|
|
`gameId` does not exist.
|
|
|
|
The `afterTime` parameter will normally match the `modified` field from the
|
|
most recent successful response to either `GET /pacosako/api/game/:gameId` or
|
|
`GET /pacosako/api/game/:gameId/poll/:afterTime`.
|
|
|
|
### `GET /pacosako/api/meta/:gameId/poll/:afterTime`
|
|
|
|
This API is identical to `GET /pacosako/api/game/:gameId/poll/:afterTime`
|
|
except that the `board` field is omitted from the response.
|
|
|
|
### `POST /pacosako/api/game/:gameId`
|
|
|
|
Parameters:
|
|
|
|
* `gameId`: String. Identifies the game object to be updated.
|
|
|
|
The request body for this API should consist of a subset of a game object
|
|
which includes the `modified` field and at least one other field to be
|
|
updated. The `modified` field in the request must match the *current* version
|
|
of the record in the database for the update to be successful; this serves as
|
|
a form of locking to prevent race conditions between multiple clients updating
|
|
the same game record. The `modified` field of the new version of the record on
|
|
success will be determined by the server.
|
|
|
|
A 400 status code will be returned if the request body does not follow the
|
|
expected schema. If the `modified` field in the request does not match the
|
|
`modified` field in the database *and* the value of any other field in the
|
|
request does not match the current version of the data in the database then a
|
|
409 response is returned with a `message` string field describing the error
|
|
and the `modified` field from the current version of the record in the
|
|
database. Otherwise the POST request succeeds with a status code of 200 and
|
|
the response body consists of a `success` field with the value `true` and the
|
|
`modified` field of the new version of the record in the database.
|
|
|
|
### `POST /pacosako/api/meta/:gameId`
|
|
|
|
This is an alias for the `POST /pacosako/api/game/:gameId` API. Either API can
|
|
be used to update any field, including `board`.
|