Architecture
The back-end runs on the server. It stores data in SQL server and prepares the data to be sent to the front-end. The front-end runs within the user’s browser.
Back-end
The back-end provides REST API distributing the data and the meta-information associated with the data to the client. The data are stored in PostgreSQL tables. The meta-information comprises how the data are structured, their type (integer, date etc), how to display them to users and how users can input/edit them. The structure of the data is composed of nested level(s). Each level is stored in separate table in the database.
The back-end handles different types of requests. Some user requests are sending an output to the front-end (GET) while others are only requiring some input (POST). All requests are handled by handlers. LabxDB provides 5 different types of handlers characterized by their input(s) and output(s). For each type of handler corresponds one Python class. When implementing a specific request in a database, the class that implements this request is inheriting from one of these generic classes. The 5 generic classes of handlers are (source code in handlers/generic.py
):
Class | HTTP request | GET returns | Usage |
---|---|---|---|
GenericHandler |
GET and POST | HTML page | Main handler providing the data to the client (GET request). The search_criterion , sort_criterion and limit parameters submitted with POST request are used to search, sort or limit the data respectively. |
GenericQueriesHandler |
GET and POST | HTML page | Handler used to create new data. Compatible with creating single or multiples records. GET request provides meta-information while the POST request handles adding the data to the database. |
GenericRecordHandler |
GET and POST | HTML page | Similar handler to GenericQueriesHandler but for a single record. The record_id is mandatory for both GET and POST requests. |
GenericGetHandler |
GET | JSON | Simple handler to get a record identified by its record_id . |
GenericRemoveHandler |
GET | JSON | Simple handler to remove a record identified by its record_id . |
The back-end is written in Python with queries written in SQL and PL/pgSQL.
Front-end
For displaying the data, LabxDB defines the Board
class (source code in board.js
). This class is inherited by two classes: the Table
and TreeBlock
classes. The Table
class displays within a table a single level of a database. To display multiple levels, the TreeBlock
class has been implemented. The Toolbar
class (source code in toolbar.js
) can be used with a Board
to allow users to filter, sort etc data.
To edit the data, LabxDB defines the Form
class (source code in form.js
). If users are required to input manually each field, the TableForm
class is appropriate. It can be used to edit a single or multiple records. In case users can provide input as, for example, tabulated text, the BatchForm
class is recommended.
The back-end is written in plain ES6 Javascript with no external dependencies.
Communications between back-end and front-end
Data are sent as JSON data by the back-end to the front-end. Most data are produced as JSON directly by the PostgreSQL server.
The meta-information is defined in the back-end. It is transmitted to the client as Javascript code. Transformation is done using the Jinja2 template engine. To one front-end class and one back-end class corresponds a template. For example, the template defined in generic_tree.jinja
is designed to be used with front-end TreeBlock
and the back-end GenericHandler
. Templates include code to instantiate these classes on the client.
Extending features of generic classes
On the back-end, classes written for specific database inherit the generic handlers. By design each handler inherits from a single generic handlers.
On the front-end, classes such as TreeBlock
can be used directly. If some of the methods of these classes needs to be overloaded, developer can write a new class inheriting or not from theses provided classes. The class to be used is defined in the back-end. The template in the back-end includes automatically the necessary code to load the file defining the class and the code to instantiate it in the client browser.