Remarque : Cette API pourrait remplacer l’API HTTP REST à moyen terme.
Sécurisation de l’accès à l’API et transmission du rôle de l’utilisateur final
La sécurisation de l’accès à l’API HTTP REST + TreeQL est effectué à l’aide d’un jeton d’identité au format JWT émis par l’application cliente.
Ce jeton transmet le rôle de l’utilisateur au moyen de la déclaration ’scope’ prenant l’une des valeurs ’admin’, ’writer’, ’reader’ and ’none’. Pour cela (voir Définition des scopes OIDC et généralités sur leur utilisation par les applications) :
l’application cliente doit utiliser OIDC et initialiser le flux d’autorisation avec code avec la demande d’autorisation (requested_scope) ’scope=privileges’,
L’application cliente doit avoir été enregistrée avec la valeur ’privileges’ dans la liste de Scopes disponibles (Available scopes),
une valeur parmi ’admin’, ’writer’, ’reader’ and ’none’ doit avoir été enregistrée dans la table users pour l’utilisateur final considéré.
Le jeton peut être passé dans l’URL (méthode GET), par POST ou par la méthode Authorization : Bearer.
Exemple d’appel avec la méthode GET :
https://oa.dnc.global/http.api/api.php/records/spip_users/1/?token=eyJ0eXAiOiJKV...
L’API valide le jeton JWT par introspection. OAuthSD garantit ainsi l’authenticité de l’application cliente. Voir : Vérification de l’origine de la requête reçue par un serveur de ressource.
En cas d’erreur d’authentification, l’API retourne un code HTTP 403 Forbidden et un corps vide.
Limitation de l’accès aux tables et aux champs
seules les tables ’users’, ’clients’, ’scopes’, ’oidc_logs’ sont accessibles.
L’authentification de l’utilisateur final conduit à définir les rôles ’admin’, ’writer’, ’reader’ et ’none’. Le rôle ’admin’ peut effectuer l’ensemble des opérations.
Pour le rôle "writer" :
dans la table ’public_keys’, la seule opération permise est la lecture de la clé clé publique.
dans la table ’oauth_clients’, l’accès au champ password est interdit.
dans la table ’oauth_users’, l’accès au champ client_secret est interdit.
Pour le rôle ’reader’ :
les restriction d’accès sont les mêmes que le rôle ’writer’,
seules les opérations ’read’ et ’list’ sont autorisées.
Le rôle ’none’ ne peut que lire la table ’oidc_logs’.
Opérations CRUD + List : Référence de l’API
Voyez également :
https://oa.dnc.global/http.api/spec/swagger/static/
https://editor.swagger.io/?url=https://oa.dnc.global/http.api/api.php/openapi
Sélections avancées
Sur les opérations de liste, vous pouvez appliquer des filtres et des jointures.
Les exemples suivants supposent la table suivante :
posts | ||
---|---|---|
id | ||
titre | ||
content | message |
Filtres
Les filtres fournissent une fonctionnalité de recherche sur les appels de liste, en utilisant le paramètre "filter". Vous devez spécifier le nom de la colonne, une virgule, le type de correspondance, une autre virgule et la valeur que vous souhaitez filtrer.
Types de match supportés :
"cs" : contient une chaîne (la chaîne contient une valeur)
"sw" : commence par (chaîne commence par valeur)
"ew" : se termine par (chaîne se termine par valeur)
"eq" : égal (la chaîne ou le nombre correspond exactement)
"lt" : inférieur à (nombre inférieur à la valeur)
"le" : inférieur ou égal (le nombre est inférieur ou égal à la valeur)
"ge" : supérieur ou égal (le nombre est supérieur ou égal à la valeur)
"gt" : supérieur à (nombre supérieur à la valeur)
"bt" : entre (le nombre est entre deux valeurs séparées par une virgule)
"in" : in (le nombre ou la chaîne est dans une liste de valeurs séparées par des virgules)
"is" : est null (le champ contient la valeur "NULL")
Vous pouvez annuler tous les filtres en ajoutant un caractère "n", afin que "eq" devienne "neq". Exemples d’utilisation du filtre :
GET / records / categories? Filter = nom, eq, Internet
GET / records / categories? Filter = nom, sw, Inter
GET / records / categories? Filter = id, le, 1
GET / records / categories? Filter = id, ngt, 2
GET / records / categories? Filter = id, bt, 1,1
Filtres multiples
Les filtres peuvent être appliqués en répétant le paramètre "filter" dans l’URL. Par exemple l’URL suivante :
GET / records / categories ? Filter = id, gt, 1 & filter = id, lt, 3
demandera toutes les catégories "où id> 1 et id <3". Si vous vouliez "où id = 2 ou id = 4", vous devriez écrire :
GET / enregistrements / catégories ? Filter1 = id, eq, 2 & filter2 = id, eq, 4
Comme vous le voyez, nous avons ajouté un numéro au paramètre "filter" pour indiquer que "OR" au lieu de "AND" doit être appliqué. Notez que vous pouvez également répéter "filter1" et créer un "ET" dans un "OU". Comme vous pouvez également aller plus loin en ajoutant une lettre (a-f), vous pouvez créer presque n’importe quel arbre de conditions relativement complexe.
Notes :
Vous ne pouvez filtrer que sur la table demandée (pas sur la table incluse) et les filtres ne sont appliqués qu’aux appels de liste.
Sélection de colonne
Par défaut, toutes les colonnes sont sélectionnées. Avec le paramètre "include", vous pouvez sélectionner des colonnes spécifiques. Vous pouvez utiliser un point pour séparer le nom de la table du nom de la colonne. Plusieurs colonnes doivent être séparées par des virgules. Un astérisque ("*") peut être utilisé comme caractère générique pour indiquer "toutes les colonnes". Semblable à "include", vous pouvez utiliser le paramètre "exclude" pour supprimer certaines colonnes :
GET / enregistrements / catégories / 1 ? Include = nom GET /records/categories/1 ?include=categories.name GET /records/categories/1 ?exclude=categories.id
Sortie :
{
"nom": "Internet"
}
Notes :
Les colonnes utilisées pour inclure des entités associées sont automatiquement ajoutées et ne peuvent pas être omises de la sortie.
Tri
Avec le paramètre "order", vous pouvez trier. Par défaut, le tri s’effectue par ordre croissant, mais en spécifiant "desc", cela peut être inversé :
GET / records / categories ? Order = nom, desc
GET / enregistrements / catégories ? Order = id, desc & order = name
Sortie :
{
"records": [
{
"id": 3
"name": "développement Web"
},
{
"id": 1
"nom": "Internet"
}
]
}
Notes :
Vous pouvez trier sur plusieurs champs en utilisant plusieurs paramètres "ordre". Vous ne pouvez pas commander sur des colonnes "jointes".
Taille limite
Le paramètre "size" limite le nombre d’enregistrements renvoyés. Ceci peut être utilisé pour les N premières listes avec le paramètre "order" (utilisez l’ordre décroissant).
GET / records / categories ? Order = id, desc & size = 1
Sortie :
{
"records": [
{
"id": 3
"name": "développement Web"
}
]
}
Notes :
Si vous souhaitez également connaître le nombre total d’enregistrements, vous pouvez utiliser le paramètre "page".
Pagination
Le paramètre "page" contient la page demandée. La taille de page par défaut est 20, mais peut être ajustée (par exemple à 50).
GET / records / categories ? Order = id & page = 1
GET / records / categories ? Order = id & page = 1,50
Sortie :
{
"records": [
{
"id": 1
"nom": "Internet"
},
{
"id": 3
"name": "développement Web"
}
],
"résultats": 2
}
Notes :
les pages non commandées ne pouvant pas être paginées, elles seront classées par clé primaire.
Jointures
Supposons que vous ayez une table des publications qui comporte des commentaires (formulés par les utilisateurs) et que les publications puissent avoir des balises. Les exemples suivants supposent le jeu de tables suivant :
posts | commentaires | utilisateurs | post_tags | tags |
---|---|---|---|---|
id | id | id | id | id |
titre | post_id | nom d’utilisateur | post_id | nom |
content | user_id | phone | tag_id | |
message | créé |
Lorsque vous souhaitez répertorier les publications avec leurs commentaires, les utilisateurs et les balises, vous pouvez demander deux chemins "arborescents" :
messages -> commentaires -> utilisateurs
posts -> post_tags -> tags
Ces chemins ont la même racine et cette demande peut être écrite au format URL comme suit :
GET / records / posts ? Join = commentaires, utilisateurs & tags = join
Ici, vous êtes autorisé à laisser de côté la table intermédiaire qui lie les publications aux balises. Dans cet exemple, les trois types de relation de table (hasMany, belongsTo et hasAndBelongsToMany) sont en jeu :
"post" a beaucoup de "commentaires"
"commentaire" appartient à "utilisateur"
"post" a et appartient à beaucoup de "tags"
Cela peut entraîner les données JSON suivantes :
{
"records": [
{
"id": 1,
"title": "Bonjour tout le monde!",
"content": "Bienvenue dans le premier message.",
"created": "2018-03-05T20: 12: 56Z",
"commentaires": [
{
id: 1,
post_id: 1,
identifiant d'utilisateur: {
id: 1,
nom d'utilisateur: "mevdschee",
téléphone: null,
},
message: "Salut!"
},
{
id: 2,
post_id: 1,
identifiant d'utilisateur: {
id: 1,
nom d'utilisateur: "mevdschee",
téléphone: null,
},
message: "Salut encore!"
}
],
"Mots clés": []
},
{
"id": 2,
"title": "Le noir est le nouveau rouge",
"content": "Ceci est le deuxième message.",
"created": "2018-03-06T21: 34: 01Z",
"commentaires": [],
"Mots clés": [
{
id: 1,
message: "drôle"
},
{
id: 2,
message: "informatif"
}
]
}
]
}
Vous voyez que les relations "belongsTo" sont détectées et la valeur de la clé étrangère est remplacée par l’objet référencé. Dans le cas de "hasMany" et "hasAndBelongsToMany", le nom de la table est utilisé comme nouvelle propriété de l’objet.
Opérations par lots
Lorsque vous souhaitez créer, lire, mettre à jour ou supprimer, vous pouvez spécifier plusieurs valeurs de clé primaire dans l’URL. Vous devez également envoyer un tableau au lieu d’un objet dans le corps de la demande pour créer et mettre à jour.
Pour lire un enregistrement de cette table, la demande peut être écrite au format URL sous la forme suivante :
GET / records / posts / 1,2
Le résultat peut être :
[
{
"id": 1,
"title": "Bonjour tout le monde!",
"content": "Bienvenue dans le premier message.",
"created": "2018-03-05T20: 12: 56Z"
},
{
"id": 2,
"title": "Le noir est le nouveau rouge",
"content": "Ceci est le deuxième message.",
"created": "2018-03-06T21: 34: 01Z"
}
]
De même, lorsque vous souhaitez effectuer une mise à jour par lot, la demande au format URL est écrite comme suit :
PUT / records / posts / 1,2
Où "1" et "2" sont les valeurs des clés primaires des enregistrements que vous souhaitez mettre à jour. Le corps devrait contenir le même nombre d’objets qu’il y a de clés primaires dans l’URL :
[
{
"titre": "Titre ajusté pour ID 1"
},
{
"titre": "Titre ajusté pour ID 2"
}
]
Ceci ajuste les titres des messages. Et les valeurs de retour sont le nombre de lignes définies :
1,1
Ce qui signifie qu’il y avait deux opérations de mise à jour et que chacune d’entre elles avait défini une ligne. Les opérations en mode batch utilisent des transactions de base de données, de sorte qu’elles réussissent ou échouent (les transactions réussies sont renvoyées).