ADS-based Web Services
ADS provides a powerful way of implementing web services for downstream systems to access TopBraid asset collections.
These web services are defined in an ontology and are exposed via the tbl/service
framework.
Web services are mainly defined in ontologies, meaning that they will be automatically available to the asset collections that include ontologies with such services.
Defined web services are exposed through the /tbl/service/
servlet.
Each web service can be invoked as follows: /tbl/service/{dataGraphId}/{servicePrefix}/{serviceLocalName}
.
EDG will automatically create Swagger documentation in asset collections which displays what web services can be executed for that particular collection, this can be found in the Reports tab. The Swagger documentation allows you to test the defined web services as well, whilst providing the exact URI and parameters that are required.
Note
From version 7.8 onwards, services that are defined using ADS can be exposed from a TopBraid server as public, meaning that no authentication is required to access them. For security reasons, this feature can only be activated by system administrators in the setup file (publicServices field). Contact TopQuadrant staff if you want to use this option.
There are two types of web services one can create:
dash:GraphService
: Web services that can be executed over the whole graph (for example when creating importers)
dash:ResourceService
: Web services that can be executed on particular instances, thus a resource is given as an input and used as the focus node
In both types of web services, the following properties can be defined:
parameters - A number of parameters can be defined as input to the web service. These parameters can be accessed in the JavaScript code using a name derived from the local name of the
sh:path
.deactivated - Activates or deactivates a web service. By default a defined web service is activated, if a value is not defined for the predicate, or the value is false.
can write - Indicates whether the web service has permission to write to the asset collection.
response content type - By default the response’s content type is
application/json
, however, this can be overridden by defining the content type in this field, for example:text/turtle
,text/csv
, andapplication/zip
amongst others.javascript code - The business logic for the web service is defined in this predicate.
The following subsections include examples of such web services. Further examples can be found in the Extension Development guide at Web Services.
Example: Retrieving data on a instance data
Web services can be defined to retrieve or modify a particular instance.
These are done by defining a web service as a type of dash:ResourceService
and attaching it to a node shape in an ontology via the dash:resourceService
predicate.
This example depicts the definition of a web service that is attached to the Continent node shape.
The code logic retrieves all countries in a selected continent (focusNode
) and returns the JSON representation of each country using the defined .toJSON(...)
method.
1let arr = focusNode.narrower.map(country => g.asCountry(country).toJSON(lang))
2arr
Note
There is no need to implement error handling in the business logic to ensure that the focusNode
has the correct type.
EDG handles all checks in resource services, therefore, if the API is given an instance with a different node shape type, EDG will prompt an error.
As soon as the web service instance is saved, EDG automatically creates the following web service: /tbl/service/geo/g/ContinentInformation/{namePart1}/{namePart2}
, where {namePart1}
is replaced by the instance prefix, and {namePart2}
is replaced by the local name.
For example /tbl/service/geo/g/ContinentInformation/g/Asia
.
Alternatively, if you do not want to use prefixes, {namePart1}
can be URI
and {namePart2}
can be the full URI of the resource.
Note in this case that some web service containers will by default reject URLs that contain %2F
escaping the slash, see
this article <https://stackoverflow.com/questions/4069002/receive-an-http-400-error-if-2f-is-part-of-the-get-url-in-jboss>
.
As a work-around, you may use @@@
to escape slashes, for example
/tbl/service/geo/g/ContinentInformation/URI/http%3A@@@@@@topquadrant.com@@@ns@@@examples@@@geography%23Asia
.
Example: Creating a Data Importer
Graph services dash:GraphService
are used to define asset-wide web services, for example, to create importers and exporters.
Unlike resource services, these are not attached to any node shape, but are simply defined in the ontology (or file) that is subsequently included in the asset collection.
The self-described code below defines the logic for importing a spreadsheet into EDG using ADS.
The system handles all file operations such as importing and loading (line 15).
Above these operations, ADS provides convenience functions to convert the imported data to more usuable JavaScript objects.
In this example, the uploaded file is converted to an object using the spreadsheet mapper, using the first row as the header and thus keys for the objects’ values.
The assignment let countryConcept = g.asCountry(countryURI)
ensures that the variable countryConcept
can access all getters and setters for the Country node shape, whilst the snippets in lines 36 to 41, demonstrates ADS ability to create instances with values extracted from the spreadsheet.
1/**
2 * This converts the spreadsheet file into the appropriate object.
3 * This function assumes that the first row is the header row, therefore
4 * each row is converted to an object:
5 * [
6 * {
7 * Country: "Malta",
8 * City: "Birkirkara",
9 * Population: "24,356"
10 * },
11 * { ... },
12 * ...
13 * ]
14 */
15let s = IO.uploadedFile(file).asSpreadsheet()
16
17// Loop through all values/rows in array s, using the first sheet (rows(0))
18s.rows(0).forEach(row => {
19 // Get all variables for the current row
20 let country = row.Country;
21 let city = row.City;
22 let population = row.Population ;
23
24 // This will create the URI for the country and city
25 let countryURI = "http://topquadrant.com/ns/examples/geography#"+country;
26 let cityURI = "http://topquadrant.com/ns/examples/geography#"+city;
27
28 // This will get the country concept thus the country's methods can be accessed.
29 // This example assumes that the country exists.
30 let countryConcept = g.asCountry(countryURI)
31
32 let cityConcept = null
33
34 // if city does not exists then create it
35 if (!(graph.contains(cityURI, rdf.type, g.City))){
36 cityConcept = g.createCity({
37 uri: cityURI,
38 prefLabel: city,
39 population: parseInt(population),
40 broader: countryConcept // this will connect the city to the country
41 })
42 } else {
43 cityConcept = g.asCity(cityURI);
44
45 // since the city already exists, then the population value can be assigned
46 cityConcept.population = parseInt(population)
47 }
48})
The only parameter required for this importer is the file
.
This figure below shows how the parameter is defined within the form editor:
Finally, the web service should be able to write to the asset collection, therefore, the predicate can write
must have a value of true.
This figure below shows the graph service instance in the ontology.
This creates the following web service: /tbl/service/geo/g/SpreadsheetImporter
.
Using Swagger or any data transfer application, when the following spreadsheet is imported via the API:
Country |
City |
Population |
---|---|---|
Malta |
Birkirkara |
24,356 |
Malta |
Qormi |
16,324 |
Malta |
Mosta |
20,988 |
Malta |
Victoria |
6,901 |
Malta |
Sliema |
22,591 |
Malta |
Valletta |
5,827 |
these concepts are created: