adjust line wrapping for better diffs
This commit is contained in:
parent
902445c29f
commit
a2d0bcc18f
221
README.md
221
README.md
|
|
@ -1,10 +1,10 @@
|
|||
# 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.
|
||||
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
|
||||
|
||||
|
|
@ -12,68 +12,74 @@ listening port is configurable and HTTPS is supported with a certificate file.
|
|||
node ./server.js [PORT]
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
npm start [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.
|
||||
If any of these variables are defined
|
||||
then 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`
|
||||
### `HTTPS_KEY` and `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.
|
||||
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:
|
||||
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.
|
||||
* `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.)
|
||||
* `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.
|
||||
* `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.
|
||||
* `timestamp`: Integer. The UTC time in milliseconds of the most recent move.
|
||||
Typically the same as the `timestamp` metadata for 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.
|
||||
* `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.
|
||||
* `modified`: Integer. The modification time 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.
|
||||
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.
|
||||
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:
|
||||
|
||||
|
|
@ -84,33 +90,41 @@ The following data is stored in the database but not included in any REST API:
|
|||
|
||||
### `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.
|
||||
Returns the list of active games.
|
||||
A game is considered "active" if the `timestamp` field indicates that
|
||||
either 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 objectsi
|
||||
in descending order by their `timestamp` fields,
|
||||
and `modified` which is the maximum value of the `modified` fields
|
||||
of all of the games in the `games` array,
|
||||
or zero if the array is empty.
|
||||
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.
|
||||
* `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.
|
||||
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`.
|
||||
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`
|
||||
|
||||
|
|
@ -119,8 +133,8 @@ 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.
|
||||
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`
|
||||
|
||||
|
|
@ -133,22 +147,23 @@ 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.
|
||||
* `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.
|
||||
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`.
|
||||
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`
|
||||
|
||||
|
|
@ -161,25 +176,33 @@ 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.
|
||||
The JSON-encoded 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, if such a record exists;
|
||||
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.
|
||||
If there is no existing version of the record then
|
||||
value of the `modified` field in the request is not used;
|
||||
however, the field is still required.
|
||||
It is recommended that a `modified` value of zero be used
|
||||
when initializing a new game
|
||||
since this value is guaranteed not to match any existing game record.
|
||||
|
||||
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.
|
||||
A 400 status will be returned if the request body does not follow the expected schema.
|
||||
If the `modified` field 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.
|
||||
|
||||
### `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`.
|
||||
This is an alias for the `POST /pacosako/api/game/:gameId` API.
|
||||
Either API can be used to update any field, including `board`.
|
||||
|
|
|
|||
Loading…
Reference in New Issue