REST enables you to easily access your NextDB data, often with very little programming. The REST features are complimentary to our existing JavaScript API. Our REST system tries to follow the HATEOAS design principle. That is, Hypermedia As The Engine Of Application State. What that means is, for the most part you shouldn't have to construct REST URLs (though we explain the format of our permalinks throughout this wiki page). Rather, you should simply use the links that the server provides to you. For example, if you want to provide links allowing a user to access different pages of database content, rather than creating those links yourself, simply extract the links from the HTML representation, and use them as needed in your application.
To demonstrate these capabilities I have shared my database called 'testchars' and a table called 'lines'. This table contains some 7,000 lines of poetry from The Iliad, and a few random lines I threw in for testing. Example REST URLs that point to my database will be used throughout this wiki page.
Your table can be accessed without any programming. Simple go directly to the table's URL, or source it in an IFRAME. The general syntax is:
http://nextdb.net/nextdb/rest/home/{account}/db/{database}/tbl/{table}/
For example:
A more concise syntax is also allowed:
http://nextdb.net/nextdb/rest/{account]/{database}/{table}/
For example:
Your table can accept a variety of 'path parameters'. Some path parameters consist of a two items, separated by a slash, like "NAME/{VALUE}". The curly braces are the part you supply dynamically. Some parameters don't require a NAME part. For example, in the URL below, the {account} and {db} and {tbl} are recognized simply by their fixed position in the URL. On the other hand, the {number} is understood to be part of the row/{number} pair.:
http://nextdb.net/nextdb/rest/{account}/{db}/{tbl}/row/{number}
formats can be applied to tables, and to queries.
html tables are the default format for returned data
you can change the response to application/json by using /format/json in your URL.
http://nextdb.net/nextdb/rest/{account}/{db}/{tbl}/pg/{page-number}/format/json
To access query results as JSON (or any other format):
http://nextdb.net/nextdb/rest/{account}/{db}/q/{queryname}/pg/{page-number}/format/json/?<query-params>
JSONP allows you to access NextDB and get around cross-domain browser restrictions. This is possible because JSONP actually returns a javascript (content-type: text/javascript) that will call a JavaScript function in your webpage. You can then access NextDB REST from JQueryAjax. To access JSONP:
http://nextdb.net/nextdb/rest/{account}/{db}/{tbl}/pg/{page-number}/format/jsonp;callback=myFunc
As you can see below, the returned JavaScript will actually call the callback function that you declare with the 'callback' matrix parameter:
myFunc([{"PK":21,"line":"with a suppliant's wreath and he besought the Achaeans, but most of","wordcount":12,"date":null},{"PK":22,"line":"all the two sons of Atreus, who were their chiefs. ","wordcount":11,"date":null},{"PK":23,"line":"\"Sons of Atreus,\" he cried, \"and all other Achaeans, may the gods","wordcount":12,"date":null},{"PK":24,"line":"who dwell in Olympus grant you to sack the city of Priam, and to reach","wordcount":15,"date":null},{"PK":25,"line":"your homes in safety; but free my daughter, and accept a ransom for","wordcount":13,"date":null},{"PK":26,"line":"her, in reverence to Apollo, son of Jove.\" ","wordcount":9,"date":null},{"PK":27,"line":"On this the rest of the Achaeans with one voice were for respecting","wordcount":13,"date":null},{"PK":28,"line":"the priest and taking the ransom that he offered; but not so Agamemnon,","wordcount":13,"date":null},{"PK":29,"line":"who spoke fiercely to him and sent him roughly away. \"Old man,\" said","wordcount":13,"date":null},{"PK":30,"line":"he, \"let me not find you tarrying about our ships, nor yet coming","wordcount":13,"date":null}]);
JSONPX is the same idea as JSON, except that the content of the JSON object passed into your callback is an HTML string. This is useful if an AJAX app simply wants to access portions of an HTML DOM, and sprinkle them around in the application.
http://nextdb.net/nextdb/rest/{account}/{db}/{tbl}/pg/{page-number}/format/jsonpx;callback=myFunc
As you can see below, the result comes back as HTML inside of JSON:
myFunc({"html":"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<html xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n <head>\n <title><\/title>\n <style type=\"text\/css\">\n <!--\n @import url(\"\/nextdb\/static\/style.css\");\n -->\n <\/style>\n <!--style type=\"text\/css\">\n #resizable { width: 150px; height: 150px; padding: 0.5em; }\n #resizable h3 { text-align: center; margin: 0; }\n <\/style>\n <link rel=\"stylesheet\" type=\"text\/css\"
You can add CSS styles to the table by selecting some of the pre-made CSS styles.
http://nextdb.net/nextdb/rest/geoff/testchars/lines/style/[newspaper-a|gradient-style|...]
All your data can be easily accessed simply by adding the "edit/true" path parameter pair. For example, you here is an interactive graffiti wall. Go ahead and mark it up:
In the security section we will show how to control table access so that you can assign usernames and passwords so you can safely give write access to selected individuals.
Set the current page:
http://nextdb.net/nextdb/rest/{account}/{db}/{tbl}/pg/{page-number}
Set the page size:
http://nextdb.net/nextdb/rest/{account}/{db}/{tbl}/pgsz/{page-size}
pg and pgsz can be used separately or together:
Examples:
From the examples above it should be clear that the pg/{page-no}, pgsz/{page-size}, and style/{style-name} path parameters can be ordered any way you like, as long as they appear to the right of the tablename.
A matrix parameter can be added to the table name in order to include or exclude colums.
Files, images and all other content can be accessed directly, by treating a single column as if it holds a file.
http://nextdb.net/nextdb/rest/{account}/{db}/{tbl}/<constraints>/{column-name}.{ext}
The portion of the URL above labeled 'constraints' is any set of path parameters that constrains the expression to a single row. If you do not constrain the URL to a single column, then the server will serve up the column from the first row that meets the constraint. Examples:
Resources are available for constrained subsets of the available data. Individual rows may be retrieved by their row id (the primary key), for example:
The row/{rownum} syntax is a special shortcut. In general, a specific column can be constrained by
col/{colname}/[eq|lt|gt|contains]/{value}
Using the more general syntax we can rewrite the URL above as:
To find a row whose value is exactly equal to a desired quantity, use the 'eq' path paramter. For example to find all lines with a value in the 'wordcount' column equal to 10:
'eq' is the default constraint, so you can omit 'eq' if you want an exact equals comparison. For example, the following URL addresses exactly the same content as the previous URL:
or to find a an exact text string:
For example, suppose you wanted to to see only rows that have a value in the 'line' column, whose line of poetry begins with a letter greater than (gt) 'y':
To find all rows with 'lines' value less than 'y':
The gt and lt path parameters can be applied to any column whose type is primitive (TEXT, DATE, LONGINTEGER, etc). For example, to show all rows with a primary key greater than 100:
To perform case-insensitive substring searching, use the 'contains' path parameter
Working with dates is easy. Internally NextDB stores a composite date-and-time. Typically this is known as a TIMESTAMP. However, you'll often find the need to compare things based on just a part of their timestamp. For example, you might need to compare based solely on the year, or on the month and year, etc. Working with DATE in NextDB REST is easy because you can access the day, month, and year as path parameters.
http://nextdb.net/nextdb/rest/{account}/{db}/{tbl}/date-col/[on|before|after]/yr/{yyyy}/day/{dd}/mo/{mm}
Examples: Although most of the lines don't have a value in the 'date' column, I inserted a few with valid dates, just to show this feature:
Aggregates can be applied to compute an aggregate value from an entire table:
http://nextdb.net/nextdb/rest/{account}/{db}/{tbl}/{column-name}/[min|max|avg]
example:
Aggregates can also be applied to compute aggregate values over a specific set of rows
http://nextdb.net/nextdb/rest/{account}/{db}/{tbl}/{column-name}/[eq|gt|lt|on|before|after]/{constraint}/[min|max|avg]
Example:
Result can be ordered using the 'ascending' or 'descending' path parameters.
.../[ascending|descending]/{colname}
For example:
Note that it is not usuall necessary to manually specify the ordering, because the "lt" and "gt" path parameters set an implicit ordering. For example, if you use "lt" (Less Than) on a date column (or any other column for that matter), an implicit ordering of "descending" is used. Conversely, if you specify "gt" (Greater Than), an implicit ordering of 'ascending' is applied to the results sets. You can override the implicit ordering by manually setting 'ascending' or 'descending' on any column of the table.
Sometimes you don't want your data presented in the tabular way that NextDB's REST URLs default to. For example, you may want to create a "gallery" style layout, or a "newsfeed" or "blog" style of presentation. In these cases you can pass the URL to an XSLT stylsheet as a matrix_parameter to the nextdb REST URL.
http://nextdb.net/nextdb/rest/{account]/{database}/{table};xslt={URL-ENCODED-URL|name}/...
The easiest way to specify an XSLT is to use NextDB's built-in support for XSLT provided by the SYS_XSLT table. The SYS_XSLT table is automatically created for new databased, and has the following columns:
If you use the SYS_XSLT table, be sure to use the SYS_ACL table to give read access to "*" (public) for the SYS_XSLT table. If you fail to do this, you will get a HTTP 401 Unauthorized error because the XSLT processor won't be able to retrieve the XSLT file.
Alternatively, your XSLT stylesheet can be retrieved by the server from any URL that you specify. Because you are passing the URL to nextdb as as matrix parameter, the XSLT URL must itself by URL encoded. There are numerous online URL encoders that you can use, such as this one: http://meyerweb.com/eric/tools/dencoder/
XSLT takes a source XML document, and performs a transformation to produce the destination document. The transformation instructions are placed in a file (usually a ".xsl", ".xslt", or just plain ".xml" file) to provide processing instructions. The input (source document) must be valid HTML. This means that all your tags must be closed properly -- essentially your source document must be a valid XML file, which XHTML is.
Source->Processor->destination
XHTML ->[apply .xslt file] ->XHTML
NextDB includes the ability to act as an XSLT processor. NextDB can transform a default XHTML file (like this) for any table or query, into a totally different looking XHTML file. To do this, NextDB downloads your XSLT file either from the SYS_XSLT table (via REST) or via the URL you provide as a matrix parameter described here, and uses its XSLT processor to apply the transformation. NextDB then serves up the transformed output.
An identity transformation is one that has no effect on the source document. Here is an identity transformation that defines a template named "copy-node". The "copy-node" template is then called for each <html> element in the source document. Since HTML documents have just one html root element, this entire HTML file is copied to the destination.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0"
xmlns:ht="http://www.w3.org/1999/xhtml"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xpath-default-namespace="http://www.w3.org/1999/xhtml">
<xsl:output method="xml"/>
<xsl:template match="@*|node()" name="copy-node">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="html">
<xsl:for-each select=".">
<xsl:call-template name="copy-node"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Here is an example database in which the identity transform has been stored in the SYS_XSLT column.
Notice that the SYS_ACL table has been set to allow public access to the SYS_XSLT table
Now that an XSLT transformation has been stored and given a name in the SYS_XSLT table, the transformation can be applied by name using a matrix parameter:
We can use any NextDB path parameter in conjunction with the xslt matrix parameter. For example, the following URL applies the XSLT transformation to page 5:
http://nextdb.net/nextdb/rest/geoff/testchars/lines;xslt=identity/pg/5
If need be, you can store you XSLT at an arbitrary URL, instead of using the SYS_XSLT table, for example, we can store an XSLT on a Wiki: http://www.nextdb.net/wiki/upload/2009/12/identityTransform-07201732.xml
To apply this Identity Transformation to a default source document produced by NextDB, such as this source HTML document we must first URL encode the URL to the Identity Transformation's XSLT file. Here is the URL encoded URL:
http%3A%2F%2Fwww.nextdb.net%2Fwiki%2Fupload%2F2009%2F12%2FidentityTransform-07201732.xml
We can now take the URL encoded link, and pass the URL encoded link itself to NextDB URL whose content we want to transform. We do this by passing the encoded link as a Matrix Parameter, like this:
http://nextdb.net/nextdb/rest/geoff/testchars/lines;xslt=http%3A%2F%2Fwww.nextdb.net%2Fwiki%2Fupload%2F2009%2F12%2FidentityTransform-07201732.xml
As you might expect, clicking on the http://nextdb.net/nextdb/rest/geoff/testchars/lines;xslt=http%3A%2F%2Fwww.nextdb.net%2Fwiki%2Fupload%2F2009%2F12%2FidentityTransform-07201732.xml produces exactly the same output as the original table. Which is of course the point: an Identity Transformation doesn't change the source document at all.
Let's make an XSLT that takes our data from The Ilyiad, and reformats the lines of The Ilyiad into 10-line paragraphs. In other words, our objective is to create a web page that presents a simple paragraph that looks like this. We don't want the output to contain any semblance of a table. It's a totally customized output, albeit a simple one:
Our source HTML document (which is the starting point that our XSLT will be applied to) looks like this when rendered in the browser:
Here is th XSLT file. Keep in mind that the source document in an HTML file that serves up a simple HTML table element. So our goal is to extract the appropriate
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns:ht="http://www.w3.org/1999/xhtml"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml"/>
<xsl:template match="ht:html/ht:body/ht:table">
<html>
<body>
<p>
<xsl:for-each select="ht:tbody">
<xsl:for-each select="ht:tr">
<xsl:value-of select="ht:td[@column='line']"/><br/>
</xsl:for-each>
</xsl:for-each>
</p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Notice how the XSLT selects the column named 'line' with the ht:td[@column='line] xpath selector.
We'll make this xslt file available in the SYS_XSLT table and name it 'text-only' http://nextdb.net/nextdb/rest/geoff/testchars/SYS_XSLT/name/text-only Then we can provide the name of the XSLT as a matrix parameter http://www.nextdb.net/nextdb/rest/geoff/testchars/lines;xslt=text-only
if you click the link above, you'll see it has transformed the first page of database rows into a paragraph of text.
The XSLT file matches against the <table> html element that is present in the default HTML tabular representation of a nextdb table. Inside the table element it looks for a <tbody> element (a 'table body'), and inside each that, it looks for each <tr> element. Another way of saying it, more succinctly is that this XSLT file iterates over each row of the table.
By default, if you attempt to access a REST URL that has not been made public, the server will return an HTTP WWW-Authenticate header. If you are accessing the date through a web browser, the browser will challenge the user to enter the account's username and password.
HTTP Basic Authentication can be disabled by setting the restPermission attribute to "public" or "read:public" in the TableMetaInf. This is accomplished using nextDB's web based admin tool. At present, the TableMetaInf XML element can be edited via the tab called Email Triggers as shown below (Note: the tab in the UI should probably be named "table poperties", but originally email triggers were all that could be set, which is why the tab is named "Email Triggers").
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <TableMetaInf xmlns="http://nextdb.net/MetaInf" restPermission="public"> <Notifications/> </TableMetaInf>
As of the time of this writing, creating a database automatically creates a SYS_USERS and a SYS_ACL table. The SYS_USERS table is used to define "system users" for your database. For example, suppose you build a website powered by nextdb, and you have several employees. You may want to give Tom access to the PRODUCTS table for reading, while Bob gets access for reading and writing. In the SYS_USERS table you can define usernames and passwords for Tom and Bob. In the SYS_ACL table you can name the tables that Tom and Bob are allowed to read and/or write. "ACL" means "Access Control List".
Here is an example of an entry in SYS_ACL that allows everyone to read the SYS_XSLT table (click the link to see the row): http://nextdb.net/nextdb/rest/geoff/testchars/SYS_ACL/table/SYS_XSLT
SYS_ACL has these columns that you muse put data into to form an access control policy:
SURIDs are currently integrated with NextDB REST. URLs served up by NextDB as links to binary data, or relationship links, are now protected by a cryptographic hash which is manifested as a ".../securekey/<crypthash>". This prevents the URL from being modified to point to a different resource (for example, modified to point to a different photo than the one returned in a query result).
NextDB REST works nicely with NextDB queries. You write your queries using the NextQuery language via the online admin interface. You can execute your queries through REST via the "q" (for "query") resource:
http://nextdb.net/nextdb/rest/{account]/{database}/q/{queryname}[/pg/{#}|/pgsz/{#}]?{query-params}
For example, here is a query named 'lines' (it doesn't require any query parameters)
Here is another query named "login". It requires two query parameters (username, password)
Here is an example combining the 'lines' query with paging: