Skip to content
This repository has been archived by the owner on Mar 27, 2024. It is now read-only.

User documentation

Aurélien Labate edited this page May 29, 2017 · 3 revisions

This document will try to help you to use the API with any client. Even if you don't want to work on the server, it's recommanded to have a local instance of the server because unexpected error logs will not be sent to client for security reason, but you can always read them from server log.

HTTP protocol

Flux server is a simple REST API. You can easily access it via HTTP. All data sent to the server should be in json. You can send it via:

  • data parameter in uri. (eg: /login/jwt?data={"json": "my json"})
  • JSON in the body
  • Parameters in uri (eg /user/:id)

The server will merge thoses elements in the given order. That mean that, if json body define id and /user/:id also, then uri will have priority.

The answer of this request will be in JSON.

Websocket protocol

As explained before, you can access api endpoints by HTTP or by socket. But socket doen't have a built-in response system like HTTP, you can only get acknowledgment without data. This is why our data object contain a requestId parameter, which will be used to send response.

Note: client should implement their own timeout system (even if it should'nt happend).

Here is an example of a post request on /login/jwt with an object as data.

// RequestId should be unique per socket connection
let requestId = 23;

# We send a request and we give a requestId=23
io.emit('request', {
    method: 'post',
    url: '/auth/jwt',
    data: {
        'jwt': 'the jwt we want to send',
    },
    requestId: requestId,
});

# The server will answer on `response-23`
io.once('response-' + requestId, (data) => {
    console.log('response body ', data.data); // data body object
    console.log('HTTP code ', data.statusCode); // 200
    console.log('HTTP statusMessage ', data.statusMessage); // "OK"
    console.log('HTTP headers ', data.headers); // Headers object
})

Internally, all data is converted to JSON, but you shouldn't have to worry about that.

Response format

The reponse of the server will always be a JSON array or object in http body.

On error, server will return with statusCode != 200 and body will contain a json object with an _error attribute.

{
    _error: {
        code: 500,
        status: 'StatusShortText',
        message: 'Plain text english technical message',
        // Request data
        req: {
            method: req.method,
            uri: req.url,
            headers: req.headers,
            params: req.params,
            query: req.query,
            body: req.body,
            user: req.user ? req.user.id : null,
            team: req.team ? req.team.id : null,
        }
    }
}

When the error is due to a validation error (a field in your request has an invalid value), status will be ValidationError and _error.validation wil contain an array of invalid fields with reasons.

Endpoint documentation

You can easily clone Flux2-server project and generate api documentation by doing

npm install
npm run doc

An api documentation will be generated into /doc/index.html that you can open with your browser.

However this documentation may not be up to date or clean, because even if we write comments in our code to generate it, we don't really use the pretty html version, we just look into controllers. If something is missing or not understandable, try to open the /api/controllers/ directory of Flux2-server, and read comments in a controller.

Another problem you may face, is that Flux2-server will generate CRUD (create, read, update, delete) endpoints, for most of the models of the project. Thoses endpoints might not be documented. So we might not find documentation of thoses endpoints and model itself and its attributes will not be defined in the documentation.

Here is list of the endpoints generated for (nearly) each models:

# Get some items of this model
# This endpoint should throw no permission errors, it will only give you items
# that you can read (so it will answer you an empty array if you have no rights).
# Parameter:
# * `filters`: Object that can be underdand as a sequelize condtion to filter entries
GET /model

# Create a new item of this model
# Parameter: Every parameters will be an attribute of the new item (if the model has attributes of the given name)
POST /model

# Update an item of this model
# Parameter: Every parameters will be used as new value for given attributes (if the model has attributes of the given name)
# Replace :id by the model id you want to update
PUT /model/:id

# Destroy an item of this model
# Replace :id by the model id you want to update
DELETE /model/:id

# Subscribe to websocket events on this model
POST /model/subscribe

# Unsubscribe from websocket events on this model
POST /model/unsubscribe

If you need to know attributes of a model, you can open the /api/models directory and read a model. Attribute definition should be in the beggining, and not so hard to understand. Just pay attention by the fact that relation attributes will be in another function: buildReferences.

Authentication

To authenticate, you first have to get a JWT. This jwt containes an userId that you can use to get user informations later. To get a jwt, take a look at endpoints in AuthController, you can get one from IP, EtuUTT (Oauth2) or even another JWT.

Authenticate in HTTP

As this is a resftul stateless API, you will have to authenticate any request. To do that, you have to pass your jwt via an Authorization header.

Authorization : Bearer YourJWT

Authenticate in Websocket

Generally, you will keep your socket connexion open between request. So, we will not identify only the request like HTTP, but we will authenticate the whole socket until you (or something else) close it.

So, you have to call once one of the authentication endpoints. After this all your requests will be authenticated. To be able to authenticate again after a closed socket, you can keep the JWT return by any authentication endpoint and use it in /auth/jwt.