Format of requests and responses

Requests and responses are all in JSON format, so the mimetype is application/json. Ensure that requests you make that require a body (:http:method:`patch` and :http:method:`post` requests) have the header Content-Type: application/json; if they do not, the server will respond with a :http:statuscode:`415`.

Suppose we have the following Flask-SQLAlchemy models (the example works with pure SQLALchemy just the same):

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)

class Person(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Unicode, unique=True)
    birth_date = db.Column(db.Date)
    computers = db.relationship('Computer',
                                backref=db.backref('owner',
                                                   lazy='dynamic'))

class Computer(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Unicode, unique=True)
    vendor = db.Column(db.Unicode)
    owner_id = db.Column(db.Integer, db.ForeignKey('person.id'))
    purchase_time = db.Column(db.DateTime)

Also suppose we have registered an API for these models at /api/person and /api/computer, respectively.

Note

API endpoints do not have trailing slashes. A request to, for example, /api/person/ will result in a :http:statuscode:`404` response.

Note

For all requests that would return a list of results, the top-level JSON object is a mapping from "objects" to the list. JSON lists are not sent as top-level objects for security reasons. For more information, see this.

Date and time fields

Flask-Restless will automatically parse and convert date and time strings into the corresponding Python objects. Flask-Restless also understands intervals (also known as durations), if you specify the interval as an integer representing the number of seconds that the interval spans.

If you want the server to set the value of a date or time field of a model as the current time (as measured at the server), use one of the special strings "CURRENT_TIMESTAMP", "CURRENT_DATE", or "LOCALTIMESTAMP". When the server receives one of these strings in a request, it will use the corresponding SQL function to set the date or time of the field in the model.

Errors and error messages

Most errors return :http:statuscode:`400`. A bad request, for example, will receive a response like this:

HTTP/1.1 400 Bad Request

{"message": "Unable to decode data"}

If your request triggers a SQLAlchemy DataError, IntegrityError, or ProgrammingError, the session will be rolled back.

Function evaluation

If the allow_functions keyword argument is set to True when creating an API for a model using APIManager.create_api(), then an endpoint will be made available for :http:get:`/api/eval/person` which responds to requests for evaluation of functions on all instances the model.

Sample request:

GET /api/eval/person?q={"functions": [{"name": "sum", "field": "age"}, {"name": "avg", "field": "height"}]} HTTP/1.1

The format of the response is

HTTP/1.1 200 OK

{"sum__age": 100, "avg_height": 68}

If no functions are specified in the request, the response will contain the empty JSON object, {}.

Note

The functions whose names are given in the request will be evaluated using SQLAlchemy’s func object.

Example

To get the total number of rows in the query (that is, the number of instances of the requested model), use count as the name of the function to evaluate, and id for the field on which to evaluate it:

Request:

GET /api/eval/person?q={"functions": [{"name": "count", "field": "id"}]} HTTP/1.1

Response:

HTTP/1.1 200 OK

{"count__id": 5}

JSONP callbacks

Add a callback=myfunc query parameter to the request URL on any :http:method:`get` requests (including endpoints for function evaluation) to have the JSON data of the response wrapped in the Javascript function myfunc. This can be used to circumvent some cross domain scripting security issues. For example, a request like this:

GET /api/person/1?callback=foo HTTP/1.1

will produce a response like this:

HTTP/1.1 200 OK

foo({"meta": ..., "data": ...})

Then in your Javascript code, write the function foo like this:

function foo(response) {
  var meta, data;
  meta = response.meta;
  data = response.data;
  // Do something cool here...
}

The metadata includes the status code and the values of the HTTP headers, including the Link headers parsed in JSON format. For example, a link that looks like this:

Link: <url1>; rel="next", <url2>; rel="foo"; bar="baz"

will look like this in the JSON metadata:

[
  {"url": "url1", "rel": "next"},
  {"url": "url2", "rel": "foo", "bar": "baz"}
]

The mimetype of a JSONP response is application/javascript instead of the usual application/json, because the payload of such a response is not valid JSON.