Total.js API routing: The game changer
Tags: totaljs, api, node, webdev
Published: 2023-03-12 13:37:11

**API routing** is Total.js internal mechanism used to expose API endpoints in a very simple way. The mechanism is designed to focus on handling a maximum number of internal operations with a minimum number of external endpoints. Therefore API routing only works with Total.js Schema and their operations.

**How does it work?**

You can create one endpoint (e.g `/api/`) and use it to target an infinite number of operations within your application. All you have to do is call that endpoint with the POST method and have in the body of the request, a JSON payload to specify what operation of what schema to target.

Example :

_Download empty project_

```bash
$ git clone https://github.com/totaljs/emptyproject-restservice api
$ cd api
$ npm install total4
$ node index.js
```

_Declare your API routes_

```js
// in /controllers/api.js


// Users
ROUTE('API  /api/   -users_query            *Users    --> query');
ROUTE('API  /api/   -users_read/{id}        *Users    --> read');
ROUTE('API  /api/   +users_insert           *Users    --> check insert (response)');
ROUTE('API  /api/   +users_update/{id}      *Users    --> update');
ROUTE('API  /api/   -users_remove/{id}      *Users    --> remove');
ROUTE('API  /api/   -users_refresh          *Users    --> refresh');

// ...
Create Schema and operations


// in /schemas/users.js

NEWSCHEMA('Users', function(schema) {

    // Fields definition

    schema.setQuery(function($) { 
        $.callback([]);
    });

    schema.setRead(function($) { 
        $.callback({}); 
    });

    schema.setInsert(function($, model) { 
        $.done(model.id) 
    });

    schema.setUpdate(function($, model) { 
        $.done(model.id) 
    });

    schema.setRemove(function($) { 
        $.success();
    });

    // Async/Await workflow

    schema.addWorkflow('refresh', async function ($) {
        var data = await FUNC.fetchData();

        if (!data) {
            $.invalid(404);
            return;
        }

        $.callback(data);

    });
    // Custom workflows
});
```
_Call endpoint from external_

```json
POST /api/
Content-Type: application/json

{
    "schema": "users_query?page=1",
    "data": {}
}
```

_Output_

   

```js
[]
```
**Required** The request body is in JSON format and expects two parameters:

schema ---> `(schema_name/{dynamic_arg_1}/{dynamic_arg_2}?query=arguments)` to specify schema (supports params and query).
data ---> data payload (optional).


**Good to know**

The routing can contain two times +/- characters.
**First** : `ROUTE('+API ...')` or `ROUTE('-API ...')` for authorization purpose. (Read more here).
**Second**: `+schema_name` or `-schema_name` to specify if data reception is expected or not.

**Websocket API**

Yes. The API Routing supports the WebSocket protocol and we recommend it too. Its declaration is the same as the standard API Routing, except that the route must contain identifiers in the form `@YOUR_NAME` instead of the relative URL address. Let us try it:

_Declare your Websocket API routes_

```js

// Users
ROUTE('API  @api   -users_remove/{id}   *Users --> remove');

// ...

// IMPORTANT: socket route
ROUTE('SOCKET / @api');
Websocket message:

{
    "TYPE": "api",
    "callbackid": "CUSTOM_CALLBACK_ID", // The value will be returned back
    "data": {
        "schema": "schema_name/{dynamic_arg_1}/{dynamic_arg_2}?query=arguments",
        "data": {}
    }
}
```
[Documentation](https://docs.totaljs.com/total4/cc674001rr51c/)