Semantic Turkey Web API

Semantic Turkey provides HTTP-based services for accessing all of its functionalities. These services can be used by those users needing some batch operations complementing the normal use of the application through its UI (e.g. VocBench or the old Semantic Turkey Firefox client), or by developers exploting the Semantic Turkey framework to power third-party applications.

This guide describes how to invoke the services exposed by Semantic Turkey through their Web API.

Invoking the services

We currently have not devised an automatic system for publishing the documentation about the services, and we do not have the manpower for manually maintaining it. However there is a 1-1 direct relationship between the services java code and their HTTP signature. While this might seem a trivial observation (well, indeed it is...), the good news is that this 1-1 relationship is quite explicit, and does not need deep diving into the code. Here we provide some information (and some) tricks for helping the interested user in understanding how to invoke the existing services.

Learning by Example

A good way to see actual http service calls in action is to use a client (e.g. VocBench) and log the calls made by the browser when each functionality is activated through interaction with the UI.

Inferring from Javascript docs and code

Explore VocBench API calls on its code.

work in progress

Inferring from Javadocs and Java code

From the system apidocs, most of the information about the service is already available. The set of core services of Semantic Turkey are all located in the st-core-services module of the project. The whole module is organized as an OSGi bundle and is not different from how a Semantic Turkey extension should look like. It can in fact be taken as an example for developing an extension.

Services Address structure

The address structure of any request (GET or POST) is the following:

http://<host_address>:<port>/semanticturkey/<groupId>/<artifactId>/<ClassName>/<methodName>?<parameters>

where:

Services in ST can be grouped in OSGi bundles and deployed inside Semantic Turkey, even extending the default set of services available in ST.

For those not familiar with Maven, the POM (project object model) is implemented in the pom.xml file at the root of the sources (there is one general pom.xml for the whole project, and one pom.xml for each module).

So, for instance, the core services, being hosted in the st-core-services module of Semantic Turkey, which has the following POM, have the following information:

groupID = it.uniroma2.art.semanticturkey (inherited from the parent project)
artifactID = st-core-services

and a simple request with default host address and port such as the listing of all available projects looks like the following:

http://127.0.0.1:1979/semanticturkey/it.uniroma2.art.semanticturkey/st-core-services/Projects/listProjects

Learning services through their javadoc description

In this section we provide two examples in which we learn how to invoke a service by reading its javadoc description. We will assume for the following examples the host address to be http://localhost and the port to have the default value of 1979

Invoking service skos:getNarrowerConcept()

The service skos:getNarrowerConcepts() returns the narrower concepts of a given concept. This service is in the java class SKOS.

By using the already explained address structure, and knowing the name of the service and the class it belongs to, we obtain the following:

http://localhost:1979/semanticturkey/it.uniroma2.art.semanticturkey/st-core-services/SKOS/getNarrowerConcepts

The method signature, that can be obtained from either its javadoc or the source code, is the following:

@STServiceOperation
@Read
@PreAuthorize("@auth.isAuthorized('rdf(concept, taxonomy)', 'R')")
public Collection<AnnotatedValue<Resource>> getNarrowerConcepts(@LocallyDefined Resource concept, @Optional @LocallyDefinedResources List<IRI> schemes)

From this source code, we see that the service has two parameters, concept and schemes. The first one must be an RDF Resource and it must be locally available (annotation: @LocallyDefined) in the dataset we are developing (its definition through the property rdf:type must an explicit RDF triple). The second parameter is optional (annotation: @Optional) and, if present, must identify a list of locally defined (annotation: @LocallyDefinedResources) RDF Resources.

Another importat information is whether the service has to be invoked through a GET or a POST. Since nothig is specified, the default is considered (GET), otherwise it would have been indicated through the following annotation

@STServiceOperation(method = RequestMethod.POST)

stating if such service is GET or a POST (when not present it is a GET)

The annotation:

@PreAuthorize("@auth.isAuthorized('rdf(concept, taxonomy)', 'R')")

states what are the capabilities required by the logged user in order to execute the service. In particular, the user must be able to read ('R' in the CRUD specification) information about concept taxonomies (subject: concept, scope: taxonomy). See the page on authorization for further details about the capability language.

The annotation

@Read

is used to indicate that a service can only read the semantic repository underneath (if a method need to change/add/delete something, the annotation @Write is used instead).

Invoking service classes:getSubClasses()

The service classes:getSubClasses() returns the narrower concepts of a given concept. This service is in the java class Classes.

We already know from the previous example how to build the url:

http://localhost:1979/semanticturkey/it.uniroma2.art.semanticturkey/st-core-services/Classes/getSubClasses?

The method signature, that can be obtained from either its javadoc or the source code, is the following:

@STServiceOperation
@Read
@PreAuthorize("@auth.isAuthorized('rdf(cls, taxonomy)', 'R')")
public Collection<AnnotatedValue<Resource>> getSubClasses(@LocallyDefined IRI superClass,
		@Optional(defaultValue = "true") boolean numInst)

From this source code we see that the service has two parameters, superClass and numInst. The first one must be an IRI and it must be locally defined in the dataset being developed. The second parameter is optional. We also see it has a default value: true, that is used when no value is passed.

The @PreAuthorize annotation

@PreAuthorize("@auth.isAuthorized('rdf(cls, taxonomy)', 'R')")

states what are the capabilities required by the logged user to execute the service. In particular, the user must be able to read ('R' in the CRUD specification) information about class taxonomies (subject: cls, scope: taxonomy). See the page on authorization for further details about the capability language.