Treasure Hunt: API Guide
A Code Cyprus project
This is version 1.0.0 of the Treasure Hunt API Guide. It is available online at http://www.codecyprus.org/th/guide.
There is also a Treasure Hunt testing API Guide, available at http://www.codecyprus.org/th/testing.
This service provides the server-side functionality for the Treasure Hunt challenge. This challenge is undertaken by students pursuing the BSc (Hons) Computing degree at UCLan Cyprus, as part of module CO1111 (The Computing Challenge). This backend is designed for and deployed on Google's App-Engine platform.
The concept of the challenge is inspired from the equivalent Four-week challenge, originally created at UCLan in Preston. Given the API description of the service, the students are asked to develop mobile apps either using AppInventor or pure HTML+JavaScript. The main goal is to provide students with an overview of key practical aspects of computing.
This project is open-source, and its code is available for cloning from GitHub under the LGPL-3.0 license. For feedback or questions please contact npaspallis at uclan point ac dot uk.
An API (Application Programming Interface) is a set of functions, typically available over the Web, which allow third-party developers to integrate with an existing app/functionality. In this particular case, the API allows anyone interested to build a Treasure Hunt app, such as the formal Android App of Code Cyprus, to do so.
Like most Web APIs, this one realizes the client/server paradigm where the client makes requests and the server answers them. For instance, a request is to provide a list of the available Treasure Hunts.
To enable maximum security possible, the whole API requires secure connections and thus any requests
applied to http://codecyprus.org/th/api/... are automatically redirected to their
secure equivalent https://codecyprus.org/th/api/.... This is in line with best practices
recommended by
the likes of Google etc. who even rank websites higher when they are secured with HTTPS.
Requests are generally formed as URLs, such as http://codecyprus.org/th/api/list. In this
API, all requests are based on the same server URL http://codecyprus.org and use a path
that has a prefix of /th/api/<call> where <call> identifies
one of the available calls described below.
Requests can also include parameters. Those are defined as <name>=<value>
pairs, such as answer=42. In this example the name of the parameter is
answer and its value is 42. If multiple parameters need to be specified in
the same call, you can join them using the ampersand symbol &. For example you
could specify two parameters player and app as
player=Homer&app=simpsons-app. Note that parameters are defined right after the
call and their beginning is identified with a question mark ?. For example, a full call
URL is http://codecyprus.org/th/api/start?player=Homer&app=simpsons-android.
Last note that Boolean parameters are sometimes defined as just a name rather than a full
<name>=<value> pair. For instance include-finished is a valid
parameter and the call https://codecyprus.org/th/api/list?include-finished=true is
equivalent to https://codecyprus.org/th/api/list?include-finished.
Following a request, the server replies with a proper reply message. Replies are encoded in JSON (JavaScript Object Notation) which is probably the most widely-used encoding format used in Web APIs. if you need a fresh-up on JSON you can follow any of the many online tutorials, such as this one from W3Schools.
Each API call has its own specific reply, encoding relevant information as needed. Data included in
specific call replies are discussed in detail in the calls section.
Nevertheless, one thing common in all replies is the status property which gets the
value OK when the call was successful or ERROR if a problem occurred, such
as a required parameter that is missing.
An error can occur for many reasons. A proper client app must anticipate errors and either overcome them (e.g. retry if there was a connection error) or inform the user accordingly (e.g. when trying to use a player name that is already in use).
Errors can occur if you make a mistake in forming the URL (e.g. a 404 resource not found error if you mistype the server URL) or if there is an error outside your control (e.g. a 500 internal server error).
Nevertheless, errors might occur even when the server responds with a success code (i.e.
200 OK). In this case, the error will be identified in the reply message, with a status
property marked as ERROR and an array of one or more error messages named
errorMessages.
The Treasure Hunt is built around the concepts of treasure hunt, session,
and question.
The treasure hunt is the main concept describing a treasure hunt game that includes
questions, and players. Normally, every treasure hunt has a starting and an ending
time. The list of available treasure hunts can be accessed using the /th/api/list
call.
The session is an instance of an active player. Each session is associated with one
treasure hunt and includes information like the player name, the current question, etc. A session
is created when the player uses the /th/api/start call.
A question includes the information required to describe the question to the user
and includes the question text itself, the expected type of the answer (e.g. Boolean, Integer,
Multiple Choice Question, etc.) and whether it is mandatory or can be skipped. A player can get
the current question using the /th/api/question call.
The essence of the API is the various function calls available to the clients. This section describes the available calls, their semantics, and the expected returned data.
A typical flow of using the API is shown in this flow chart:
The starting point of any treasure hunt challenge is to list the available treasure hunts so the
player can pick the one they want to compete in. This is enabled using the
/th/api/list call.
The API call is as follows:
The call has these parameters:
include-finished is an optional parameter specifying that the
reply must include all treasure hunts, including finished ones. This is usually not needed.
A sample request is https://codecyprus.org/th/api/list?include-finished
The output includes the status and the array of available
treasureHunts.
To join a treasure hunt, the player must use the start call and specify their
name, app id and requested treasure hunt id.
The API call is as follows:
The call has these parameters:
player is a mandatory parameter specifying the requested
player name or nickname. This is required to be unique, so if the specified
player is already in use, an appropriate error message is returned.app is also a mandatory parameter specifying the name of
the app used to play the treasure hunt. This is a required parameter, so if it
is not specified, an appropriate error message is returned.treasure-hunt-id is a mandatory parameter specifying the id
of the treasure hunt to be launched. The id is normally picked from the result
of the list call. This is a required parameter and it must
be a valid id, i.e. one that corresponds to an existing and available treasure
hunt. If not, an appropriate error message is returned.
The output includes the status the total numOfQuestions and the
session id which is required for subsequent calls, such as to get the current
question.
Once you join a treasure hunt you can start looking up questions. To view a question, you
can use the /th/api/question call. This gives you information about the actual
question (i.e. its text) as well as the expected answer type.
The API call is as follows:
The call has one parameter:
session is a mandatory parameter specifying the id of the
session which corresponds to this player.
The output includes the status and some properties of the question.
For instance the completed property specifies if the user has already completed
this treasure hunt (i.e. has answered all questions already). The questionText
contains the text-based question, whcih can also be specified in simple HTML. The
questionType specifies the expected type of the answer. The possible answer
types are:
BOOLEAN can be either Boolean value true/falseINTEGER can be any valid integer like -1, 0, 1, 2, etc.NUMERIC can be any valid numeric value like -1.2, 0.2, 1.234, etc.MCQ can be any of four possible multiple-choice answers, i.e. A, B, C, DTEXT can be any general text, normally a single word
The canBeSkipped is a Boolean that specifies whether this particular question
can be skipped or must be answered. The requires-location indicates whether
this is a location sensitive question where the player must be at a specific location for
their answer to be checked. The numOfQuestions specifies the total number of
questions in the treasure hunt, and the currentQuestionIndex defines the
zero-based index of the current question (the first one is 0, and the last one is
numOfQuestions-1). Finally, the correctScore,
wrongScore and skipScore specify the score adjustment for when
the answer is correct, wrong, or the question was skipped, respectively.
To answer the current question you can use the /th/api/answer call. This allows
you to specify the answer for the given session.
The API call is as follows:
The call has two parameters:
session is a mandatory parameter specifying the id of the
session which corresponds to this player.answer is a mandatory parameter for specifying the tries
answer. The answer is provided in text form but must match the question type as
indicated in the reply of the question call.
The output includes the status and some properties such as whether the provided
answer was correct, whether the session is no completed (meaning
there are no more unanswered questions), an optional text-based message and
the scoreAdjustment as an integer that indicates how the score has changed
(i.e. points gained or subtracted from the player's score).
Some of the questions require that the player is at a specific location to be able to answer.
The /th/api/location call allows you to specify the location in terms of
latitude and longitude for the given session.
The /th/api/location call is used periodically to update the server of the
player's current location, and also before answering a location-sensitive
question as indicated by the requires-location
property of the /question call. Normally, you can not call
/th/api/location too often. Instead allow at least 30 seconds between calls.
The API call is as follows:
The call has three parameters:
The output includes the status and a text-based message explaining
whether the call was recorded or not.
Some of the questions can be skipped, usually with a penalty to the score. The
/th/api/skip call allows you to skip a question
if the player chooses to do so.
The API call is as follows:
The call has one parameter:
session is a mandatory parameter specifying the id of the
selected session.
The output includes the status, a Boolean indication of whether the treasure
hunt is completed after skipping, a text-based message and the
scoreAdjustment which is normally a negative integer, e.g. -5.
The /th/api/score call is used to access the current score of this
session.
The API call is as follows:
The call has one parameter:
session is a mandatory parameter specifying the id of the
selected session.
The output includes the status, a Boolean indication of whether the treasure
hunt is completed, i.e. there are no more unanswered questions, and whether
the treasure hunt is finished, i.e. it has ended time-wise. The
player property gives the selected player name, the score property
gives the score as an integer, e.g. 23. Last, the hasPrize property shows
whether there is a prize associated with the current treasure hunt (this is needed for
some special applications).
Naturally multiple players can be competing in a treasure hunt. To access the current
leaderboard us the /th/api/leaderboard call and specify either the current
player session or the selected treasure-hunt-id. Optionally,
also use the sorted flag to indicate that you want the list of scores to be
sorted from higher to smaller score. You can also specify the optional limit
parameter to limit the number of entries that appear in the leaderboard.
The API call is as follows:
The call has four possible parameters. You can only use one of session and
treasure-hunt-id. If you specify both, the latter is ignored. The other
parameters are as follows:
session is an mandatory parameter specifying the id of the
session which corresponds to this player. Not to be used at the same time with
treasure-hunt-id described next.treasure-hunt-id is a mandatory parameter for specifying the
selected treasure hunt. Not to be used at the same time with
session described previously.sorted is an optional parameter for specifying that the
score list is to be sorted from higher to lower scores.limit is also an optional parameter for limiting the number
of entries that appear in the leaderboard. This parameter is ignored if
you do not also specify the sorted flag. Also it is ignored if not
a valid integer value not less than the minimum limit of
5. When specified, it returns the
limit top entries in the sorted leaderboard.
The output includes the status, the numOfPlayers, a Boolean
value indicating whether the list is sorted, the applied limit
and the leaderboard. When not specified or when invalid, the limit
is automatically set to the max integer value, i.e. 2147483647. Finally, the
nae of the corresponding Treasure Hunt is provided for convenience
as the named value treasureHuntName.
The leaderboard consists of a JSON array containing numOfPlayers entries, where
each entry has a player name, a score and a
completionTime. The latter is a timestamp of when the player answered the last
question, expressed in
Unix epoch in milliseconds. If the player has not finished yet, it is set to zero.
Players with higher score are ranked higher irrespective of
completionTime. When players have the same score then the player
with the earliest completionTime is ranked higher (as the player answered the
last question first). Players with a completionTime of zero (i.e. unfinished)
are ranked lower to other players with the same score.