adjust line wrapping for better diffs

This commit is contained in:
Jesse D. McDonald 2020-05-02 15:27:42 -05:00
parent 902445c29f
commit a2d0bcc18f
1 changed files with 122 additions and 99 deletions

221
README.md
View File

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