Requests and responses

Requests and responses are all in the JSON API format, so each request must include an Accept header whose value is application/vnd.api+json and any request that contains content must include a Content-Type header whose value is application/vnd.api+json. If they do not, the client will receive an error response.

This section of the documentation assumes some familiarity with the JSON API specification.

Resource ID must be a string

As required by the JSON API, the ID (and type) of a resource must be a string in request and response documents. This does not mean that the primary key in the database must be a string, only that it will appear as a string in communications between the client and the server. For more information, see the Identification section of the JSON API specification.

Trailing slashes in URLs

API endpoints do not have trailing slashes. A GET request to, for example, /api/person/ will result in a 404 Not Found response.

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 units 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

Flask-Restless returns the error responses required by the JSON API specification, and most other server errors yield a 400 Bad Request. Errors are included in the errors element in the top-level JSON document in the response body.

If a request triggers certain types of errors, the SQLAlchemy session will be rolled back. Currently these errors are

JSONP callbacks

Flask-Restless responds to JavaScript clients that request JSONP responses. Add a callback=myfunc query parameter to the request URL on any request that yields a response that contains content (including endpoints for function evaluation; see 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.

The Content-Type of a JSONP response is application/javascript instead of application/vnd.api+json because the payload of such a response is not valid JSON API.

For example, a request like this:

GET /api/person/1?callback=foo HTTP/1.1
Host: example.com
Accept: application/vnd.api+json

will produce a response like this:

HTTP/1.1 200 OK
Content-Type: application/javascript

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

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

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

JSON API extensions

Flask-Restless does not yet support the official JSON API extension. For progress on the implementation of the official extensions, see GitHub issues #478 and #477.

Cross-Origin Resource Sharing (CORS)

Cross-Origin Resource Sharing (CORS) is a protocol that allows JavaScript HTTP clients to make HTTP requests across Internet domain boundaries while still protecting against cross-site scripting (XSS) attacks. If you have access to the HTTP server that serves your Flask application, I recommend configuring CORS there, since such concerns are beyond the scope of Flask-Restless. However, in case you need to support CORS at the application level, you should create a function that adds the necessary HTTP headers after the request has been processed by Flask-Restless (that is, just before the HTTP response is sent from the server to the client) using the flask.Blueprint.after_request() method:

from flask import Flask
from flask.ext.restless import APIManager

def add_cors_headers(response):
    response.headers['Access-Control-Allow-Origin'] = 'example.com'
    response.headers['Access-Control-Allow-Credentials'] = 'true'
    # Set whatever other headers you like...
    return response

app = Flask(__name__)
manager = APIManager(app)
blueprint = manager.create_api_blueprint('mypersonapi', Person)
blueprint.after_request(add_cors_headers)
app.register_blueprint(blueprint)