Skip to content

Services API

Ernest Badu edited this page Mar 20, 2021 · 3 revisions

The service API package defines and handles the interaction between the app and external RESTful APIs over HTTP(S). It also performs its own error handling and output parsing. It is a completely removable component and can exist on its own and inserted anywhere.

For use as a RESTful API (instead of native Java code, detailed below), more information can be found in the section [below](#RESTful-Service API-Interaction).

Interface

The makeRequest method takes the service name and required data as parameters and performs the API request, the output is a sentence for the speech synthesiser to speak aloud to the user (with the relevant data included).

  • This output is put onto an API response queue, maintained by the main controller of the app.
void makeRequest(String serviceName, HashMap <String, String> payload)

The recognised service names are:

Getting Responses

The API response queue should have the type:

BlockingQueue<ApiResponse> appQueue;

Periodically polling this queue returns an ApiResponse object returning the service's response after a call is made.

The string response, used in speech synthesis, can be retrieved using the getResponse() method of the object.

The name of the service that was called can be retrieved using the getName() method of the object.

A service may return (required) data that is not suitable for speech synthesis e.g. an image to display. This type of data is referred to as 'metadata', stored in a HashMap<String, Object named metadata. It is retrieved by calling the metadata() method of an ApiResponse object.

  • Note that there is no standard for the representation of data inside the hashmap - this is entirely dependent on the service, and its corresponding parseOutput method.
  • Expected metadata (for successful API calls) for relevant services is detailed below, for that specific service only.

The getName() method should be used to check what service was returned to determine how to read its metadata, if required.

An example implementation showing how to retrieve responses can be found in test package.

The following section defines the required parameters needed by each service. See the "Adding Services" wiki article for more information on how to integrate new services.

API Formats

The following set of tables define the required data needed by each service. The internal structure of a RESTful service API request is a HashMap<String, String> object where the Attribute columns below represent the exact field names in the hash map for a service.

Current Weather API

A service allowing the user to retrieve information about the current weather in their (or explicitly specified) city.

Attribute Type Default Description
CITY_NAME String "London" The name of the city the user's device is located in.
COUNTRY_CODE String "uk" The two-character ISO country code of the city. The full list of possible country codes can be found here.
LANGUAGE String "en" The two-character (or three) ISO code of the language to return the weather in. The full list of possible language codes can be found here.

Weather Forecast API

A service returning the predicted weather for the user's exact location.

Attribute Type Default Description
LAT Double 51.534121 The latitude of the user's current (or most recent) location.
LON Double -0.006 The longitude of the user's current (or most recent location.
LANGUAGE String "en" The two-character (or three) ISO code of the language to return the weather in. The full list of possible language codes can be found here.
DAYS Integer 1 The number of days to forecast for. The minimum is 7 and the maximum is 7.

Air Quality API

A service returning the air quality index for a given city.

Attribute Type Default Description
CITY_NAME String "London" The name of the city the user's device is located in.

Stocks API

A service allowing the user to retrieve stock information on an equity of their choice.

Attribute Type Default Description
FUNCTION String "TIME_SERIES_INTRADAY" The time series of your choice.
SYMBOL String "IBM" The name of the equity.
INTERVAL Integer 1 Time interval between two consecutive data points in the time series. The following values are supported: 1, 5, 15, 30, 60.

Joke API

A service retrieving a random or specific joke.

Attribute Type Default Description
TERM String "" The search term to search for a joke.

Dictionary API

A service retrieving the definition, examples and synonyms for a given word.

Attribute Type Default Description
WORD String "hello" The word to retrieve the definition of.
LANGUAGE String "en" The two-character (or three) ISO code of the language to return the definition in. The full list of possible language codes can be found here.
INCLUDE_SYNONYMS Boolean "false" Indicates whether to retrieve the synonyms of the word as well.
SYNONYMS_ONLY Boolean "false" Allows for thesaurus usage, retrieving only the synonyms of the word and not its definition and example sentence usage. If this is set to true, INCLUDE_SYNONYMS is also set to true by default.

Nearest Transport API

This service returns either the nearest train stations or bus stops for a given location range.

Attribute Type Default Description
MIN-LAT Double 51.530121 The minimum latitude, representing one corner of the bounding box - must be less than MAX-LAT.
MAX-LAT Double 51.538121 The maximum latitude, representing one corner of the bounding box - must be more than MIN-LAT.
MIN-LON Double -0.009 The minimum longitude, representing one corner of the bounding box - must be less than MAX-LON.
MAX-LON Double -0.001 The maximum longitude, representing one corner of the bounding box - must be more than MIN-LON.
TRANSPORT String "train_station" Indicates whether to search for a train station (train_station) or a bus stop (bus_stop).

Note that this service does not return any spoken ouput, just the coordinates of the nearest transport points defined below.

Metadata

The metadata returned by this service contains just one top-level field - locations which is an array of latitude, longitude pairs for each returned transport point. Each element in the locations array is a Double[] array, with the following elements:

Attribute Type Description
latitude Double The latitude of the transport point.
longitude Double The longitude of the transport point.

Note that the ordering here is important - the first element in the array is the latitude, the second the longitude.

Transport By Search API

This service returns information on a bus stop or train station by its name.

Attribute Type Default Description
QUERY String "euston" The name of the train station or bus stop to search for.
TRANSPORT String "train_station" Indicates whether to search for a train station (train_station) or a bus stop (bus_stop).

Metadata

The metadata returned by this service is:

Attribute Type Description
latitude Double The latitude of the transport point.
longitude Double The longitude of the transport point.

Random Recipe API

This service returns a random recipe.

This service requires no parameters - supplying them has no effect.

Metadata

The metadata returned by this service is:

Attribute Type Description
recipe-id String The ID of the recipe, useful for further API calls, e.g., fetching the full instructions using the recipe instructions API.
image String A URL to the cover image of the recipe.

Recipe By Search API

This service returns a set of recipes by searching via natural language.

Attribute Type Default Description
QUERY String "" The search term.

Metadata

The metadata returned by this service is:

Attribute Type Description
recipe-id String The ID of the recipe, useful for further API calls, e.g., fetching the full instructions using the recipe instructions API.
image String A URL to the cover image of the recipe.

Recipe By Ingredient API

This service returns a set of recipes with certain ingredients, specified by the user.

Attribute Type Default Description
INGREDIENTS String "" A comma separated string of ingredients to search for.

Metadata

The metadata returned by this service is:

Attribute Type Description
recipe-id String The ID of the recipe, useful for further API calls, e.g., fetching the full instructions using the recipe instructions API.
image String A URL to the cover image of the recipe.

Recipe Instructions API

This service returns the instructions for the recipes returned by the services above.

Attribute Type Default Description
ID String "" The ID of the recipe.
DETAILED Boolean true Whether to split instructions into steps (true) or return a plain description (false).

Note that this service is intended to be used internally - each recipe service above returns the ID of the recipe in the metadata of the response object; the recipe instructions service should then be used to retrieve the instructions of that recipe.

This service also returns no spoken output. The metadata, defined below, can be used to programmatically decide what steps to read (instead of reading it all at once).

Metadata

The metadata returned by this service is:

Attribute Type Description
steps ArrayList<String> An array of instructions for the recipe - each element is one instruction step.

News API

This service returns a news article based on the user's search.

Attribute Type Default Description
QUERY String "" The search term, in natural language.
LANGUAGE String "en" The language to return the result in. Uses the two-character IS0-639-1 code scheme. The full list of possible language codes can be found here.

Metadata

The metadata returned by this service is:

Attribute Type Description
url String A URL to the full news article.
image String A URL to the cover image of the article.

Charity Search API

This service returns information on a specified number of charities, based on the user's search in natural language.

Attribute Type Default Description
QUERY String "" The search term, in natural language.
VALUES String 1 The (maximum) number of charities to return information on.

Metadata

The metadata returned by this service contains just one top-level field: charities which is an array of maps (each one representing a charity) where each map contains the following information:

Attribute Type Description
name String The name of the charity.
URL String A URL to the charity's registered page.
donationURL String A URL to donate to the charity.
latitude Double The latitude of the charity.
longitude Double The longitude of the charity.

Charity By City API

This service returns information on a specified number of charities in a given city.

Attribute Type Default Description
CITY String "london" The search term, in natural language.
VALUES Integer 1 The (maximum) number of charities to return information on.

Metadata

The metadata returned by this service contains just one top-level field: charities which is an array of maps (each one representing a charity) where each map contains the following information:

Attribute Type Description
name String The name of the charity.
URL String A URL to the charity's registered page.
donationURL String A URL to donate to the charity.
latitude Double The latitude of the charity.
longitude Double The longitude of the charity.

Book By Search API

This service returns information on a book based on the user's search.

Attribute Type Default Description
QUERY String "" The search term, in natural language. Entirely optional.
TOPIC String "" A certain topic to look for. Entirely optional.
LANGUAGES String "en" A comma separated string containing the list of languages to search for. Uses the two-character IS0-639-1 code scheme. The full list of possible language codes can be found here.

Note that both the QUERY and TOPIC attributes are optional, but at least one must be supplied.

Metadata

The metadata returned by this service is:

Attribute Type Description
id Integer The ID of the book, useful for making further API calls.
image/jpeg String A URL to the image of the book cover.
text/html String A URL to an online version of the book, formatted with HTML.
text/plaintext String A URL to an online verison of the book, in plain text with no formatting.
application/x-mobipocket-ebook String A URL to an ebook download of the book.
application/epub+zip String A URL to an ebook download of the book in a different format than above.

RESTful Service API Interaction

This Java package allows the service API interaction to be accessed via a restful API on localhost.

Endpoints

The following endpoints are available:

  • "air-quality"
  • "book"
  • "current-weather"
  • "charity-search"
  • "charity-by-city"
  • "dictionary"
  • "ingredient"
  • "joke"
  • "nearest-transport"
  • "news"
  • "random-recipe"
  • "recipe"
  • "recipe-instructions"
  • "stocks"
  • "transport-search"
  • "weather-forecast"

As per the service APIs included except any spaces in the service names are replaced with hyphens.

Parameters are to be supplied in the URL in lowercase form.

  • e.g., the dictionary service endpoint requires a WORD parameter (as per the outer README) and is supplied (in lowercase) as:
/dictionary?word=word_here
  • Services that require multiple parameters are supplied by an ampersand (&) separated list.

Note that there are no POST requests available (only GET), setting the request method to POST in the request header will result in an error.

Responses

All responses are of the form:

    {
       "service": "",
       "message": "",
       "metadata": {},
       "code": code
    }

Where

  • service - the name of the service; this is either the endpoint, for a recognised service or error if a client HTTP error occurs.
  • message - a natural language string representing the service response - useful for voice assistants.
  • metadata - extra data that may be useful, but unsuitable for natural language e.g., image/web links.
  • code - the HTTP status code using this standard.

Deployment

To start the application in a Docker container, you must first build the image with:

docker build --tag services .

And then to start the application on port 8080:

docker run --rm services services/services

Note that you must be running these docker commands from one level up, just outside this folder. You should navigate to the containing folder before building or running the image:

cd ..

To start the application, ensuring no service is currently using port 8080, run the following command in a terminal in the "services" directory (where the pom.xml is located):

mvn clean; mvn org.springframework.boot:spring-boot-maven-plugin:run

An executable jar file can be used instead, built and executed manually using:

mvn clean package

You can also start the application using a Python script with the following command:

python3 tools/run.py

For simplicity, a shell script is included to run the service interaction as a RESTful API:

./services

Depending on your system configuration, you may need to give the script execution permissions which can only be done with administrator privileges (sudo):

 chmod +x services

And then perform your HTTP requests. For example, after the application is running, open a terminal and enter:

curl "localhost:8080/current-weather?city=london"

This will return something similar to:

    {
        "service":"current weather",
        "message":"The weather in London today is broken clouds with the temperature being 7 degrees celsius but will probably feel like 4 degrees celsius. The high will be 7 degrees celsius and the low, 6 degrees celsius. Don't forget to dress warm today!",
        "metadata":{},
        "code":200
    }

Note that the URL must be quoted to escape the question marks and ampersands if performing HTTP requests from the command line.

Command Line Arguments

There are different execution options for the API, summarised below.

Note that these can only be enabled by passing them as command line arguments to the Python run script or running the application as a jar. Command line arguments are unavailable with Java if not executing using a jar file (using the java -jar ... command).

The following arguments are all optional.

  • A desired port can be specified using -port=PORT (or one of --port, -p and --p). Note that this must be an integer and is set to 8080 by default.
  • Logging information to the console can be enabled with the -l (or --l) flag - logging is disabled by default.
  • The application can be built into a single jar and executing using the -jar (or --jar) flag.
    • This option is only available using the Python run script.

When using the jar file (with java -jar ...):

  • The -l flag is supplied without the leading - character(s) - i.e. as l.
  • The -port flag is always supplied with a single - and the same goes for -p.

Running python3 tools/run.py -h gives you a similar breakdown of possible command line arguments and their aliases.

  • The -h flag is not available outside of the Python script.

Testing

To execute unit tests(served at: http://localhost:8000/surefire-report.html):

docker run -p 80:8000 -ti --rm services /services/tools/test

To execute PMD analysis(served at: http://localhost:8000/pmd.html):

docker run -p 80:8000 -ti --rm services /services/tools/analysis

To execute test coverage (served at: http://localhost:8000/jacoco):

docker run -p 80:8000 -ti --rm services /services/tools/coverage