This page documents information that is specific to the HTTP API. We try to adhere to the recommendations of RFC 2616 and to the principles of REST.
The HTTP API is accessible at fluiddb.fluidinfo.com on port 80. For secure access via HTTPS, use port 443.
During the private alpha of FluidDB you will need to have API access specifically enabled for your user name. Please mail us to request access. We’d love to hear what you’re thinking of building.
Please note that we will be proceeding very cautiously at first as we monitor FluidDB under increasing load, and also as we work to improve it.
Detailed documentation of the available URI hierarchy is provided at http://api.fluidinfo.com/fluidDB/api/*/*.
The two trailing * parts of that URI are wildcards which you can replace to restrict what you see. In order, they specify the desired top-level URI category, and the HTTP verb. I.e., the general format of an API documentation URI is
http://api.fluidinfo.com/fluidDB/api/TOPLEVEL/VERB
For example, you can visit http://api.fluidinfo.com/fluidDB/api/namespaces/GET to see the documentation for GET requests on namespaces. You can also use a comma separated list of top-levels and/or verbs, e.g., http://api.fluidinfo.com/fluidDB/api/namespaces,tags/GET,PUT.
There is only a single version of the FluidDB API. It used to be possible to request different API versions, but seeing as the FluidDB API is very stable it was decided to drop this support in favor of simpler code. To maintain backwards compatibility, if a request URI contains a numeric first component, that component will simply be ignored.
During the private alpha of FluidDB, applications must use HTTP Basic for authentication. This can be done (insecurely) over a regular HTTP connection, or securely via HTTPS. Credentials will normally be presented on each request. If credentials are not sent, the request will be attempted as the anonymous user.
An application that wants to carry out a particular action on behalf of a particular FluidDB user will need to send that user’s credentials. When a user gives their credentials to an application, they are allowing the application to authenticate as them to FluidDB and are also authorizing the application to make changes in FluidDB as them.
This is an unsatisfactory arrangement, not suitable for the longer term. Following the alpha stage of FluidDB, we will provide for enhanced authentication and a fine-grained authorization solution.
In the case of authorization, FluidDB has a strong built-in permissions model on tags and namespaces. This allows users to grant/restrict permission for other users to carry out actions. Because applications are users too, a user can pre-approve the actions that another (an application) may take on their behalf. Using this as the basis of an authorization scheme, a user intending to use an application will visit a Fluidinfo site to pre-approve an application to act on their behalf.
The HTTP interface currently only accepts payloads in JSON. In JSON all strings are unicode, so in sending or receiving a payload you likely will not have to think about unicode issues.
To send a unicode namespace or tag name as part of a URI however, you must first encode it into a sequence of UTF-8 octets, and then %-encode the result according to RFC2396 (section 2.4.1).
To give a simple example, suppose the FluidDB user sam has a namespace called música. To add a sub-namespace an application would POST to sam/m%C3%BAsica. That’s because ú when converted to UTF-8 is the two octet sequence \xC3\xBA and when that is %-encoded it becomes the 6-byte sequence %C3%BA.
Note: this section does not deal with tag values. For that see below.
Many HTTP API methods expect to receive their arguments and/or to return their results in a formatted payload. Currently, the only supported format is JSON.
When sending method arguments in a JSON payload to FluidDB you must set the Content-Type HTTP header of your request to application/json. You must also send a Content-Length header containing the number of octets in the serialized JSON.
If you are calling a method that returns JSON formatted results, you may send an Accept header indicating the content types you are willing to receive. Currently, the only recognized value is application/json. Seeing as this is also the default, it is also what you will get if you send no Accept header or if you send an Accept header with */*.
If you make any sort of payload error, you will receive a 400 error status (see below for details).
When doing a PUT or GET involving a tag value (API details) you will use Content-Type and (optionally, for GET) Accept headers to specify details of transmitted tag values. Before reading on, make sure you understand the difference between primitive and opaque Tag values.
Primitive values: To send a primitive tag value, first serialize it (i.e., the null, boolean, int, float, string, or list of strings you wish to send) as a single JSON value (use a JSON array in the case of a list of strings). Many programming languages have a JSON library available that can do this for you. Send the JSON in the request payload and set the Content-Length header to be the number of octets in the payload. To indicate that the payload contains a primitive value, you must set the Content-Type header to application/vnd.fluiddb.value+json. JSON is currently the only format by which you can send a primitive tag value.
Opaque values: To send an opaque value, set the Content-Type header to whatever is appropriate, put the tag content into the payload, and set the Content-Length header to be the number of octets in the payload. The Content-Type you use is up to you, as described in the document on Tag values.
When you GET a tag on an object, the response will contain a Content-Type header to indicate the type of the tag value.
Primitive values: The Content-Type will be set to application/vnd.fluiddb.value+json and the payload will be a serialized JSON object.
Opaque values: Content-Type will contain the type that was sent when the tag was originally added via PUT. I.e., if you PUT an application/pdf tag onto an object, you will get application/pdf back on a subsequent GET. The payload of the response will contain the tag value.
When retrieving tag values, you may optionally send an Accept header to indicate what kinds of values you are willing to receive from FluidDB. As detailed in RFC2616, sending no Accept header is equivalent to setting it to */*. Here are some notes on the use of the Accept header:
Some Accept header examples:
HTTP responses for requests that result in an error will (with one exception) always contain X-FluidDB-Error-Class and X-FluidDB-Request-Id headers. (The exception is with 401 errors due to sending an incorrect username / password combination.)
The X-FluidDB-Error-Class header will contain the name of the exception class that was raised in FluidDB. The names give a very clear indication of what went wrong. The X-FluidDB-Error-Class header can be your best guide to what’s going on, especially with generic errors such as 400 (Bad request).
The X-FluidDB-Request-Id header will contain a unique random id that you can tell us so we can easily locate logging information associated with your API request.
The status codes returned by FluidDB calls are shown in the detailed HTTP API documentation. Here though are some general comments on HTTP error statuses you might encounter.
There are a variety of simple request errors that will trigger a 400 error. These are listed below. In parentheses after each is the value that will be in the X-FluidDB-Error-Class header (see above section).
If you omit a Content-Length header when sending a payload, you will receive a 411.
FluidDB puts a limit on the number of objects that a query can return. This is necessary because without a limit it would be simple to send queries that returned all objects. The limit protects against accidents and denial of service attacks.
The current query limit is 1 million objects. If your query (or any intermediate sub-part of the query) exceeds this number, you will receive a 413 error.
JSONP is a trick that allows Javascript running in a web browser to obtain data from a server other than the one from which the browser initially downloaded the Javascript. JSONP provides a way to get around this same-origin policy. As a concrete example, suppose you visit a site called CoolApps and their HTML page contains Javascript. Your browser downloads the Javascript and begins to run it. The same-origin policy thereafter restricts that Javascript to only making network connections back to the CoolApps site. So if the Javascript application wants to interact with FluidDB, it cannot, unless the CoolApps site implements a proxy to receive FluidDB API calls, pass them on, and then return something that your browser can understand as Javascript. That’s a lot of work, and it’s work that would need to be done by all Javascript-using sites that wanted to interact with FluidDB.
JSONP takes advantage of the browser’s willingness to load Javascript code from other sites via the HTML script tag. If a page contains a <script src="http://fluiddb.fluidinfo.com/..."/> tag, a browser will send a GET request to FluidDB, and try to evaluate the result as Javascript. With a little help from the FluidDB HTTP servers, this small exception to the same-origin policy can be used to access the entire FluidDB HTTP API.
First of all, the browser is expecting a Javascript result that it can execute. To enable this, the author of the Javascript app arranges for the content of the normal reply from FluidDB to be passed as an argument to a Javascript function call. You do this by giving a callback argument in the URL. For example, an HTML tag like <script src="http://fluiddb.fluidinfo.com/objects/xxxx/mike/rating?callback=Window.alert"/> will result in a response from FluidDB with content Window.alert(6) if the value of the mike/rating tag on the object xxxx is 6 and the value was readable by everyone (the browser will send no authentication details to FluidDB). Of course the Javascript application programmer will likely want to call something more useful than Window.alert.
This is a neat trick, but what if you want to do something other than a GET request? It’s easy: you just specify the HTTP verb you actually want as another argument in the URL that you provide as the src attribute in your HTML. Continuing our example, to delete the mike/rating tag, you’d use <script src="http://fluiddb.fluidinfo.com/objects/xxxx/mike/rating?verb=DELETE"/>. You can even send a payload along with its length and type. E.g., <script src="http://fluiddb.fluidinfo.com/objects/xxxx/mike/rating?verb=PUT&payload=great&payload-length=5&payload-type=text%2Fplain"/>. In addition, the payload can be encoded, in which case the encoding you used must be specified via a payload-encoding argument.
FluidDB transforms these JSONP requests into normal requests. The payload-length you send becomes the Content-length header in the transformed request, payload-encoding becomes Content-encoding, and of course the decoded payload becomes the payload of the new request. The Content-type in the reply to JSONP requests is always set to text/javascript because that’s what the browser will be expecting, as it is expecting to receive and execute Javascript code.
With JSONP you have access to the entire FluidDB API, though there are some details that must be kept in mind:
JSONP can be useful in non-Javascript contexts too. Applications may be running in restrictive environments (e.g., behind proxies), or may be constrained to use older HTTP libraries that do not support all HTTP verbs. In these cases it may be possible to make FluidDB API calls using JSONP, including sending authentication details.