217 lines
6.7 KiB
Markdown
217 lines
6.7 KiB
Markdown
# sequelize-middleware
|
|
|
|
[![pipeline status](https://framagit.org/dbroqua/sequelize-middleware/badges/develop/pipeline.svg)](https://framagit.org/dbroqua/sequelize-middleware/commits/develop) [![coverage report](https://framagit.org/dbroqua/sequelize-middleware/badges/develop/coverage.svg)](https://framagit.org/dbroqua/sequelize-middleware/commits/develop)
|
|
|
|
Sequelize-middleware est un module NodeJS permettant d'automatiser la création d'une API REST utilisant Sequelize comme SGBD.
|
|
|
|
Sequelize-middleware s'appuie également sur Joi pour valider les données reçues ainsi que les appels API effectuées.
|
|
|
|
## Fonctionnalités
|
|
|
|
Ce module est découpé en 3 fonctionnalités principales :
|
|
* Le `Middleware`, partie centrale du projet
|
|
* `ErrorBuilder` qui permet de surcharger la méthode `new Error()`
|
|
* `ResponseFormater` qui se charge de formater les données retournée au client final
|
|
|
|
### Middleware
|
|
|
|
Méthode par défaut, permettant de générer tout le code propre à un endpoint.
|
|
|
|
```js
|
|
import Middleware from "sequelize-middleare";
|
|
|
|
import models from "../models";
|
|
import params from "../rules/Endpoint";
|
|
|
|
const middleware = new Middleware(params, models);
|
|
|
|
middleware.getAll(req, callback);
|
|
```
|
|
|
|
#### Initilisation
|
|
|
|
Le constructeur doit recevoir 2 paramètres :
|
|
* params
|
|
* models
|
|
|
|
`params` représente le fichier des règles pour cet endpoint.
|
|
`models` fait référence au fichier `models/index.js` généré par Sequelize.
|
|
|
|
Le fichier params doit ressembler à ceci :
|
|
|
|
```js
|
|
import Joi from "@hapi/joi";
|
|
const models = require("../models"); // Facultatif
|
|
|
|
const Rules = {
|
|
model: "Areas", // Nom de la collection Sequelize
|
|
crud: { // Liste des rôles (req.user.roles) autorisés en fonction de l'action
|
|
read: ["installer", "admin", "user"],
|
|
write: ["installer", "admin"],
|
|
edit: ["installer", "admin"],
|
|
delete: ["installer", "admin"]
|
|
},
|
|
includes: [ // Liste des inclusions à faire lors d'un getOne/getAll
|
|
{
|
|
collection: "Devices", // Nom de la collection à inclure
|
|
requiredRole: ["installer", "admin", "user"], // Rôles autorisés à voir cette inclusion
|
|
required: false, // Sauf cas particulier toujours mettre false
|
|
model: models.AreasDevices, // Nom du modèle Sequelize à inclure
|
|
include: [ // Liste des sous-inclusions
|
|
{
|
|
collection: "Device",
|
|
requiredRole: ["installer", "admin", "user"]
|
|
}
|
|
]
|
|
}
|
|
],
|
|
format: { // Formatage des données en fonction du rôle de l'utilisateur (dans le cas ou l'on veut surcharger le formatage du modèle)
|
|
user: {
|
|
idRetourne: "_idSql", // Clé retournée: Clé du modèle
|
|
id: "id",
|
|
nom: "name"
|
|
}
|
|
},
|
|
itemId: "areaId", // Id de l'item dans la req.params
|
|
validate: { // Définition des des règles de valeurs acceptées en fonction du verbe
|
|
// Création d'un nouvele élément
|
|
create: Joi.object({
|
|
name: Joi.string().required(),
|
|
type: Joi.string()
|
|
.valid("OFFICE", "COMMUNAL-AREAS")
|
|
.required()
|
|
}),
|
|
// Mise à jour d'un élément
|
|
update: Joi.object({
|
|
name: Joi.string(),
|
|
type: Joi.string().valid("OFFICE", "COMMUNAL-AREAS")
|
|
}),
|
|
// Sélection d'un élément (req.params)
|
|
item: Joi.object({
|
|
areaId: Joi.number().required()
|
|
}),
|
|
// Sélection d'une liste d'éléments (req.query)
|
|
list: Joi.object({
|
|
limit: Joi.number()
|
|
.integer()
|
|
.min(1)
|
|
.max(50),
|
|
page: Joi.number()
|
|
.integer()
|
|
.min(1),
|
|
type: Joi.string().valid("OFFICE", "COMMUNAL-AREAS"),
|
|
sort: Joi.string()
|
|
.valid("id", "name", "type", "createdAt", "updatedAt")
|
|
.only(),
|
|
order: Joi.string()
|
|
.valid("asc", "desc")
|
|
.only()
|
|
})
|
|
.with("limit", "page")
|
|
.with("page", "limit")
|
|
.with("sort", "order")
|
|
.with("order", "sort")
|
|
},
|
|
removeKeys: {
|
|
// Permet de supprimer automatiquement des valeurs de requêtes
|
|
item: ["partnerId"] // Sur la sélection d'un item on supprime req.params.partnerId
|
|
},
|
|
override: {
|
|
list: { // Permet de convertir des paramètres reçus via req.query pour en générer des filtres complexes
|
|
filters: {
|
|
'category': { // On converti req.query.category
|
|
$or: [
|
|
{
|
|
categoryId: '_TERM_',
|
|
},
|
|
{
|
|
categoriesId: {
|
|
$contains: '_TERM_',
|
|
},
|
|
},
|
|
],
|
|
},
|
|
'countryId': { // On converti req.query pour dire à Sequelize que ça correspond à $Details.countryId$
|
|
'$Details.countryId$': '_TERM_',
|
|
}
|
|
},
|
|
},
|
|
create: {
|
|
// Création d'un nouvel item
|
|
body: [
|
|
// On modifie req.body
|
|
{
|
|
append: "offerId", // On rajoute un attribut offerId
|
|
from: "params", // Que l'on prends dans req.params
|
|
value: "offerId" // Et dont la clé est offerId
|
|
}
|
|
]
|
|
}
|
|
},
|
|
restrictOn: { // Permet de rajouter des restrictions en fonction des rôles
|
|
update: [ // Lors d'une mise à jour au autorise l'utilisateur à modifier uniquement les éléments donc state est égal à NEW.
|
|
{
|
|
roles: ['user'],
|
|
type: 'raw', // raw permet de forcer une valeur, sinon user/params/body/query
|
|
field: 'state',
|
|
value: 'NEW',
|
|
},
|
|
],
|
|
delete: [],
|
|
list: [],
|
|
create: []
|
|
},
|
|
};
|
|
|
|
export default Rules;
|
|
```
|
|
|
|
### ErrorBuilder
|
|
|
|
```js
|
|
import { ErrorBuilder } from "sequelize-middleare";
|
|
```
|
|
|
|
Ce module permet de remplacer la méthode `new Error()` de JS en ajoutant la possibilité de générer un code d'erreur qui sera ensuite retourné via `res.status().json()`.
|
|
|
|
Le code reçu doit être un `float` dont la partie entière représente un code HTTP valide et la partie réelle représente un code d'erreur plus détaillé de l'erreur.
|
|
|
|
Exemples d'utilistion :
|
|
|
|
|
|
```js
|
|
import { ErrorBuilder } from "sequelize-middleare";
|
|
|
|
new ErrorBuilder(406.0, "Erreur générique de type 406");
|
|
new ErrorBuilder(406.1, "Le champs mot de passe est absent");
|
|
new ErrorBuilder(406.2, "Le champs mot de passe doit contenir 8 caractères minimum");
|
|
...
|
|
```
|
|
|
|
### ResponseFormater
|
|
|
|
```js
|
|
import { ResponseFormater } from "sequelize-middleare";
|
|
```
|
|
|
|
Ce module permet de formater à la fois le json ainsi que le code http retourné au client une fois que le middleware à fini son traitement.
|
|
|
|
Exemples d'utilisation :
|
|
|
|
```js
|
|
import { ResponseFormater } from "sequelize-middleare";
|
|
|
|
router
|
|
.route("/")
|
|
.get(passport.authenticate(["jwt"]), function(req, res, next) {
|
|
middleware.getAll(req, (err, response) => {
|
|
ResponseFormater(req, res, next, err, response);
|
|
});
|
|
})
|
|
.post(passport.authenticate(["jwt"]), function(req, res, next) {
|
|
middleware.createOne(req, (err, response) => {
|
|
ResponseFormater(req, res, next, err, response);
|
|
});
|
|
});
|
|
```
|
|
|