Build your solution
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 “&”.
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.