-
Notifications
You must be signed in to change notification settings - Fork 72
API Functionality
The exposed API implements all JSON:API functionality:
- CRUD
- Relationships
- Filtering
- Sorting
- Pagination
- Resource Linkage
In addition, this functionality can be refined and extended in many different ways.
Database object such as the User class from the demo.py example can be extended to include relationships with other objects. The demo_relationship.py contains following extension of the User class where a relationship with the Book class is implemented:
class User(SAFRSBase, db.Model):
'''
description: User description
'''
__tablename__ = 'Users'
id = db.Column(db.String, primary_key=True)
name = db.Column(db.String, default='')
email = db.Column(db.String, default='')
books = db.relationship('Book', back_populates="user")
...
A many-to-one database association is declared by the back_populates relationship argument. The Book class is simply another subclass of SAFRSBase and db.Model, similar to the previous User class:
class Book(SAFRSBase, db.Model):
'''
description: Book description
'''
__tablename__ = 'Books'
id = db.Column(db.String, primary_key=True)
name = db.Column(db.String, default='')
user_id = db.Column(db.String, db.ForeignKey('Users.id'))
user = db.relationship('User', back_populates='books')
The User.book relationship can be queried in the API through the following endpoints:
- POST adds an item to the relationship
- DELETE removes an item from the relationship
- GET retrieves a list of item ids
The relationship API endpoints work similarly for one-to-many relationships.
Relationship members can also be included in the response when querying an instance, by specifying the relationship name in the include
query argument.
For example, to retrieve all items in the books_read
relationship from the People endpoint, you may add the include=books_read
url parameter:
http://thomaxxl.pythonanywhere.com/api/People/?include=books_read
To retrieve nested relationship items, you can specify the nested relationship name after the '.', to retrieve the authors of the books_read instances for instance, you can use
http://thomaxxl.pythonanywhere.com/api/People/?include=books_read.author
If you don't want any relationships to be included in the jsonapi response for an object, you can set the supports_includes
class attribute to False
The swagger shows the jsonapi filters that can be used in the url query arguments. Items with an exact match of the specified attribute value can be fetched by specifying the corresponding key-value query parameter. For example, suppose the User
class, exposed at /Users
has a name
attribute, to retrieve all
instances with the name "John", you can use a GET
request to
/Users?filter[name]=John
.
It is also possible to use more generic filters by specifiying a JSON string
filter=[{"name":"timestamp","op":"gt","val":"2020-08-01"},{"name":"timestamp","op":"lt","val":"2020-08-02"}]
Collection responses can be sorted on the attribute (or attribute csv list) specified in the "sort" url query argument.
e.g.
http://thomaxxl.pythonanywhere.com/api/People/?sort=name,id
Reverse sort is also possible by using a -
in front of the attribute you want to sort:
http://thomaxxl.pythonanywhere.com/api/People/?sort=-name
HTTP status codes are used to signal success or failure of a REST operation:
- 200 : OK
- 201 : The request has been fulfilled and resulted in a new resource being created.
- 204 : No Content, DELETE operation was successful
- 400 : The services raised an exception, for example in case of invalid input
- 500 : Internal Server Error
In case of errors( status codes 400+ ), the log file contains a stacktrace. Two custom exceptions are defined in errors.py: ValidationError and GenericError. In case of errors, the webservice will return a default HTTP status code 500 and a customizable error message, for example
{
"error": "Failed to execute query Entity '<class 'C2_server.Image'>' has no property 'namex'"
}