AL!SE semantic Server contains a broad family of components that offer various semantic and smart functionalities.

First every developer gets in contact with Aglaia which is the Interface managing service of the AL!SE Framework that hosts an HTTP(S) server. It sits on top of Leto and provides a Web API for it, using HTTP bodies in JSON format.

Functionality

The AL!SE server provides:

  • HTTP methods for accessing the server (and the underlying Leto database)
  • Add/remove information from operations on the Leto Database (e.g. PDF Watermarking)
  • Semantic filtering
  • Managing User Access via Session control and encrypted security headers
  • Login/Logout via Leto Username and password
  • Login/Logout via License information

The following description of the API methods gives you the foundation to build your own semanticApp:

AL!SE Documentation and how to access via JSON (API v2)

This version provides functionality to authenticate, manage user data, apps and siles and ask questions.

Authentication

Auth column marked with "X" means the user has to be logged in to perform the request.

Auth Method Path Request Body Response Body Description
POST /login { email, password, ontology[opt]} { secret, uri } If login credentials match a user, create an authentication secret and return also the user URI along with it.
POST /login/license { deviceUri, serial} { secret, uri, validFrom, validTo, allowedDevices, registeredDevices } If device URI and corresponding client serial number match the database entries, create an authentication secret and return also the user URI and license data along with it (to check if there was an server-side update).
X GET /logout Secret is invalid from now on.
POST /register { email, password, firstname, lastname } { email } Create a new deactivated user and an activation key. Send an activation email.
X PATCH /register/pronto { email, password, firstname, lastname } { email } Create a new activated user.
X POST /fetch-key/redirect { appId } { key } Create and return a redirect key for the given app.
X POST /fetch-key/password { password } { key } If the password matches the current user, reate and return a password key.
POST /mail-key/password { email } { email } Create a password key and send it via email.
X POST /mail-key/email { email } { email } Create an email key and send it via email.
POST /use-key/activation { key } If the activation key exists (and is not too old), activate the corresponding user.
POST /use-key/redirect { key } { secret, email, uri } If key is valid, return a new secret along with the user’s email.
POST /use-key/password { key, password } If key is valid, set password of the user.
POST /use-key/email { key } If key is valid, set email of the user.
X PATCH /user/password { password } Changes the password of the authenticated user.

Requests get authorized via HMAC (hash based message authentication). The authentication header is created like this:


secret // came from Aglaia in login response
method // e.g. GET
path // e.g. /v2/apps
user // e.g. user@email.com
nonce // some number, increased in each request

digest = sha256(secret + method + path + nonce)
authenticationHeader = 'hmac ' + user + ':' + nonce + ':' + digest

The request then contains these headers:


GET /v2/apps HTTP/1.1
Host: appx.alise.systems
Authentication: hmac user@email.com:123456:ob23o4h89fo23u4of9h8324oh8f
Content-Type: application/json

Aglaia uses this information to do the following:

  • use the user name to get its current secrets from session
  • use the host to reduce the amount of possible secrets (secrets are only valid for one app)
  • check if the nonce is higher than the stored last nonce for the secret
  • build the digest from secret, method, path, date and nonce and compare it to the digest in the request

After that, the request is either rejected or the session is retrieved successfully.

Single role

A user can manage roles and assign other users to them.

Auth Method Path Request Body Response Body Description
X POST /role { roleId, readSlinks[opt], writeSlinks[opt], superRoleId[opt] } Role Create role and return Role details.
X PATCH /role/{roleId} { roleId, … } Role Change role details, e. g. to assign / unassign siles.
X GET /role/{roleId} Role Retrieve role details.

Multiple roles

Auth Method Path Request Body Response Body Description
X GET /roles [ Role, … ] Return all active roles of the user with their details.

Single app

A user can manage Apps and assign other users to them.

Auth Method Path Request Body Response Body Description
X POST /app { appId, appPath, ontPath } App Create app for specified repository and return app details.
X PATCH /app/{appId} { users, … } App Change app details, e. g. to assign / unassign users.
X GET /app/{appId} App Retrieve app details.

Multiple apps

Auth Method Path Request Body Response Body Description
X GET /apps [ App, … ] Return all active apps of the user with their details.

Ontologies

The OWL-files used for storing data can be retrieved in binary (Base64) form via the API. One method provides getting the identifying URIs of the ontologies, the other one is for retrieving the specified ontology OWL.

Auth Method Path Request Body Response Body Description
GET /ontology/list [ uri_1, uri_2, … ] Return all Ontology URIs wihtin a JSON Array.
POST /ontology/owl { uri } { uri, owl } Returns the Ontology URI as well as the Base64-coded owl file.

Ontology Specifications

The API provides funcitionality to retrieve single specifications from the used ontology.

Auth Method Path Request Body Response Body Description
GET /category/children/{category} [category1, category2, … ] Return all subcategories of the provided {category} name (excluding this super category)

License (re)activation

Since license siles must not require Username-authorized access, they have their own API function. However, the user has to authorise himself with various data that will be checked on the server.

Auth Method Path Request Body Response Body Description
POST /license/activate/{licenseId} { Bezeichnung, Seriennummer, Plattform, Mitarbeiter[opt] } [ key ] Returns the (encrypted) license key. Serial number and plattform info should be automatically grabbed by the client.
POST /license/reactivate/{licenseId} { Seriennummer } { key } Returns the (encrypted) license key.

Siles

Siles are objects that are specified by it’s URI and contain use data, a human-readable (or searchable) label can be specified. Attributes, Categories and Slinks (semantic links) to other objects are called metadata. Additionally, a Sile can contain binary content (e.g. an image).

Sile Query Parameters

The following API calls (except for DELETE) always return a sile (or, by using the filter, multiple siles) where the amount of contained information can be specified by using a query parameter: Just add ?content= and a corresponding value at the end of the API call.

Specifier ID Returned Content
uri (only multiple siles) JSON Array with URIs
date (only multiple siles) JSON Array with JSONObjects containing URI and according update date
label uri and label
metadata uri, label, attributes, categories and slinks (default)
binary uri, label and data
all complete sile as specified in Sile structure below

For example, GET /sile/uri:example1234?content=binary will return a JSON object with information from the sile with URI=uri:example1234. It will contain the URI, the label and the binary data as Base64-encoded String.

If the query parameter is not defined, the default value (metadata) will be used. Using more query parameters (as it is possible when filtering and retrieving multiple siles, see below), query parameters are seperated by "&".

Single sile

Method Path Body Description
GET /sile/{id} Get sile with this ID
POST /sile Sile Create sile for unspecified ID
PATCH /sile/{id} { …changes } Change the given values in the sile with this ID
DELETE /sile/{id} Delete sile with this ID (or keep but set ‘deleted’ timestamp)

The response is always the latest JSON representation of the sile, containing its classes and ID.

Sile structure

{
    "uri": "234r-23s2-234r-df54",
    "label": "Sile Label",
    "binaryArray": "lsadf89a43q4...",
    "attributes": {
        "attributeLabel1": [
            "Value 1",
            "Value 2"
        ],
        ...
    },
    "categories": [
        "category1",
        "category2",
        ...
    ],
    "slinks": {
        "dependsOn": [
            {
                "uri": "h39k-i9jn-826j-52ee",
                "label": "Linked sile 1"
            },
            ...

        ],
        ...
    }
}

Multiple siles

Additional query parameters "limit" and "offset" are allowed to avoid big data chunks. They are seperated by "&". (Example: POST /sile/filter/{filter}?limit=10&offset=20&content=label)

Auth Method Path Request Body Response Body Description
X POST /sile/filter {filter} [siles] Returns an array of siles that match the specified filter
X POST /sile/filter/uris ["uri_1", "uri_2", …] [siles] Returns an array of siles that match the specified uris

The response is an array of all matching siles. It is crucial that every JSON Object contains exactly one filter.

Filter structure

[
    {
        "and": [
            {
                "or": [
                    {
                        "type": "category",
                        "label": "Person"
                    },
                    {   
                        "type": "category",
                        "label": "Topic"
                    },
                    {
                        "type": "attributetypevalue",
                        "label": "FirstName",    
                        "value": "Franz"
                    }
                ]
            },
            {
                "type": "attributetyperange",
                "label": "AvgHeartRate",
                "minvalue": "80",
                "maxvalue": "120"
            }
            ...
        ]
    },
    {
        "or": [
            ...
        ]
    },
    {
        "not": {
            "type": "category",
            "label": "Company"
        }
    },
    ...
]

AND and OR filters are compound filters and each contain an array of atomic or futher compound filters. The JSON array transmitted represents an AND filter. The NOT filter negates results of an underlying filter.

Atomic Filter types

The following atomic filters are available, ‘X’s denote required JSON attributes.

type sileuri label value minvalue maxvalue description
attributerange X X An attribute range filter selects siles which are annotated with an attribute (of any type) whose value is within a specific range
attributetype X An attribute type filter passes all siles that have at least one attribute with the specified attribute type URI, regardless of its value and datatype
attributetyperange X X X An attribute type range filter selects siles which are annotated with a specific attribute type and a value that is within a specific range
attributetypevalue X X Extends the AttributeFilter by not only considering the attribute type but also its value (ie. textual representation of the value and the datatype URI)
category X Checks whether a sile is annotated with a specific category
fulltextpattern X A TagPatternFilter matches tag annotations based on a regular expression pattern. A tag pattern filter is case-insensitive per default
labelvalue X A NotFilter inverts the selection of the underlying (atomic) filter
null A NullFilter holds no specific information and matches for all siles
sileinoutbound X A SileInOutboundFilter is a filter that checks for siles that are slinked by, or that slink to, the specified sile
sileinbound X A SileInboundFilter is a filter that checks for siles that slink to the the searched sile
sileoutbound X A SileOutboundFilter is a filter that checks for siles that are slinked by the searched sile
sileslinkinbound X X A SileSlinkInboundFilter is a filter that checks for siles that are "incoming" linked by a specified other sile with a specified slink type
sileslinkoutbound X X A SileSlinkOutboundFilter is a filter that checks for siles that link to a specified other sile with a specified slink type
slinkinoutbound X A SlinkInOutboundFilter is a filter that searches for siles that are slinked to or from by a specified slink type
slinkinbound X A SlinkInboundFilter is a filter that searches for siles that are slinked to by a specified slink type
slinkoutbound X A SlinkOutboundFilter is a filter that searches for siles that slink to other siles by a specified slink type

Filter query parameters (?key=value)

key type required Default description
limit int no infinity How many objects should be retrieved in one call
offset int no 0 How many objects should be left out before the first one

Links

http://restcookbook.com/HTTP%20Methods/put-vs-post/ – PUT if you know the URL, POST if you don’t https://blog.restcase.com/restful-api-authentication-basics/ – basics of different authorization methods

Notes

According to the redirect pattern, changing/creating requests would respond with the entity’s URL. In our case though, it is more practical to return the entity directly.

A DELETE request returns the latest representation of the deleted entity, because it can be used by the client to undo the operation by a new PUT request.