REST API’s with PatternQueries

REST is a very simple industry-standard request-response protocol supported by InfinityDB Server. Each REST access targets a specific URL, providing a request content in JSON and receiving back a JSON response content, somewhat like HTTP. In InfinityDB Server, each such URL is handled by a specific PatternQuery, so accesses are like remote procedure calls. Here is a simple example with the syntax of the database in this case being i code:

Database Names

Above, the URL includes the database name ‘my/db’ which is always two words separated by a single slash, where the words are a letter followed by letters, digits, dot, dash, and underscore. The server can contain any number of databases, each being a single InfinityDB Embedded file or else a remoted database on another server. The server admin user can create and manage databases and remoting, as well as managing users. Not shown are the user name and password passed transparently in the request (in the same way as an HTTP Basic Authentication).

Query Name

After the database name are two strings for the query name – the “interface name” and the “method name”. Queries are stored inside the database that they apply to, so a database describes its own API, thereby isolating client applications from the internal structure of the data. It is therefore easy for the database to be restructured, extended, simplified, combined, or secured without affecting client applications. API can be added by storing new queries, and new ‘parameters’ or ‘returned data’ can be added by adding a few Items to queries. Queries can only be executed when they are directly under the Query class.

BLOBs

It is possible also to communicate BLOBs or ‘Binary Long Objects’ instead of JSON, according to the ‘Content-Type’ parameter of the request, following the mime type naming rules of HTTP. For this, the ‘action’ URL parameter is “execute-get-blob-query” or “execute-put-blob-query”. Transfer rate is very high for such binary data.

If a user has read or write access to a database, then the database can also be accessed directly by a URL without any query being involved, and with no ‘action’ URL parameter. In that case, the part of the URL after the database name is translated directly into an Item prefix and all of the suffixes of that Item prefix are marshalled and transmitted in as the request content or out as the response content in JSON form. In case the Item suffixes are formatted in a particular way, a URL can be used to get or put a BLOB also without a PatternQuery or by using the ‘action=get-blob’ or ‘action=put-blob’ URL query parameters.

An example URL to get some JSON is https://infinitydb.com:37411/infinitydb/data/demo/readonly/Documentation (user name ‘testUser’ password ‘db’, database ‘demo/readonly’, Item prefix ‘Documentation’). For an example BLOB see https://infinitydb.com:37411/infinitydb/data/demo/readonly/Pictures/%22pic2%22.

InfinityDB stores BLOBs that are to be associated with a mimetype in this way (actually this is binary internally):

... com.infinitydb.blob {
    com.infinitydb.data [
         Bytes(xx_xx_xx..._xx)
         Bytes(xx_xx_xx..._xx)
    ]
    com.infinitydb.mimetype "text/plain"
} 

Any unlimited length series of bytes or chars can be represented by a list of short byte array or char array components as above under the attribute com.infinitydb.data. The byte arrays are all of length 1024 except the last, which is one to 1024 as necessary.

Permissions

Users can be given permission to read, write, or execute queries on individual databases. If a user is limited to executing queries, then the database is protected according to the query definitions.. Each user can be assigned to a set of groups, and each group is given a set of permissions to access particular sets of databases. If a user is the ‘owner’ of a database, then all access is permitted. (A future feature will be the ability to limit groups to executing only queries with a particular set of interface names.)

Python infinitydb.access Module

Python has special optional support for REST. The infinitydb.access module provides many features, such has helpers for formatting JSON-communicated data as dicts. There are classes for EntityClass and Attribute and so on. (infinitydb.access.py is in the trial download until we post it on github.) Also, the database can be navigated bidirectionally by Item.

Here is some code using the Python access.py library:

from infinitydb.access import *

# port 37411 is usual
infinitydb_url = 'https://infinitydb.com:37411/infinitydb/data'
#infinitydb_url = 'http://localhost:37411/infinitydb/data'

""" Database names (URI components) """

# Databases have one slash separating two names each like
# [A-Za-z][A-Za-z0-9._-]*
# An infinitydb server by default has these available for the testUser
#database_uri = 'demo/writeable'
database_uri = 'demo/readonly'

""" The User Name and Password """

# A public guest user for browsing and experimentation, in the
# 'guest' role. Contact us for your own experimentation login and db.
user = 'testUser'
password = 'db'

""" The connection to the database """

infdb = InfinityDBAccessor(infinitydb_url, db=database_uri, user=user, password=password)
    
""" Get JSON given a prefix Item from the connection """

# To see the documentation as JSON in the demo/readonly database, go to:
# https://infinitydb.com:37411/infinitydb/data/demo/readonly/Documentation
# Here we read that JSON into content, with success being a boolean.
# The success only indicates that some data was read, not that there was an error.
# Real errors raise InfinityDBError
# The JSON is represented by nested dicts and lists.
# We use a path prefix of ['Documentation'] which is an Item with a single string component:
success, content, content_type = infdb.get_json(['Documentation'])