Enrichissement d’une ressource
Permet au fournisseur d’API de modifier et de compléter le comportement attendu sur une ressource en particulier.
Déclaration d’un endpoint de production et/ou de sandbox
Principe de fonctionnement
L’API déclare dans sa configuration un endpoint et/ou un sandboxendpoint pour une ressource. Dès la déclaration réalisée, la Gateway applique les redirections.
Exemple illustré avec l’API Digiposte v3, qui a :
- Un "endpoint": "https://api.digiposte.fr/api/v3"
- Un "sandboxEndpoint": "https://api.interop.digiposte.io/api/v3"
- Et une ressource POST dont la route est "/partner/:partner_id/memberships/:partner_user_id/documents/certified"
En déclarant un endpoint et un sandboxendpoint sur cette route, le propriétaire de l’API modifie les API requêtées :
API requêtée initialement (sans déclaration d’un endpoint et d’un sandboxendpoint sur la route) | API requêtée après déclaration d’un endpoint et d’un sandboxendpoint sur la route | |
---|---|---|
Endpoint | https://api.digiposte.fr/api/v3/partner/:partner_id/memberships/:partner_user_id/documents/certified | https://api.digiposte.fr/api/v4/partner/:partner_id/memberships/:partner_user_id/documents/certified |
SandboxEndpoint | https://api.interop.digiposte.io/api/v3/partner/:partner_id/memberships/:partner_user_id/documents/certified | https://api.interop.digiposte.io/api/v4/partner/:partner_id/memberships/:partner_user_id/documents/certified |
Principe de mise en œuvre
- type: api
value:
name: My Api
urlContext: myapi
version: '1'
...
- type: resource
value:
name: My Resource
method: post
route: /official/route/dispayed
endpoint: /real/endpoint/joigned
sandboxendpoint: https://other.api.fr/real/sandboxendpoint/joigned
api:
urlContext: myapi
version: "1"
Ajout d’un Plugin
Permet au fournisseur d’API d’ajouter un traitement à une requête avant de l’envoyer vers l’API cible ou avant de faire suivre la réponse reçue de l’API cible vers le client.
Principe de fonctionnement des plugins
Il y a deux types de plugins :
- Les plugins lié à l'API : Ils permettent d'effectuer des traitements avant l'envoi ou après envoi sur toutes les requêtes de l'API. Ils sont déclarés dans la configuration de l'API via le champ
extra
. - Les plugins lié aux ressources: Ils permettent d'effectuer des traitements avant l'envoi ou après envoi sur une ressource de l'API. Ils sont déclarés dans la configuration de la ressource via le champ
extra
.
Le flow de chaque requête-réponse entre Okapi et l'API distante est le suivant :
Il est à noter que
Pour chaque requête / réponse d'une ressource, Okapi exécute la liste des plugins de l'api avant d'exécuter la liste des plugins de la ressource ciblée.
L'ensemble des plugins sera appliqué dès l'import du fichier de configuration Yaml ou après l'intervention du support Okapi.
La configuration finale prendra cette forme :
- type: api
value:
name: My Api
urlContext: myapi
version: '1'
...
extra :
plugins :
- before : |
my plugin code
- after : |
my plugin code
- type: resource
value:
name: My Resource
method: get
route: /route
extra :
plugins :
- before : |
my plugin javascript code
- after : |
my plugin javascript code
api:
urlContext: myapi
version: "1"
Principe de mise en œuvre des plugins
Un plugin est un code Javascript, qui peut être soit de type before, soit de type after.
- Dans le cas du before, nous pouvons modifier la variable
req
qui correspond aux infos de la requête HTTP.
- Dans le cas du after, nous avons accès a deux variables :
req
qui correspond aux infos de la requête HTTP.res
qui correspond aux infos de la réponse de l'API.
Il est à noter que
l'ensemble des variables sont présentes dans le context api
.
plugins:
# On déclare un plugin de type before
- before: |
api.req.headers['x-my-header'] = 'my value'
# On déclare un plugin de type after
- after: |
if (api.req.headers['x-my-header'] === 'my value') {
api.res.headers['x-my-header'] = 'my value'
}
Attention
Le code Javascript n'est pas une fonction, il est exécuté directement.
Le plugin peut aussi utiliser la bibliothèque Lodash via la variable _
.
Attention
Pour une mise en œuvre avancée du code Javascript, il est vivement recommandé de demander l'assistance de l'équipe Support Okapi.
Exemples de mise en œuvre des plugins
Quelques exemples de mise en œuvre pour vous mettre dans le bon chemin:
Un plugin
before
// Nous bénéficions de la bibliothèque Lodash pour ajouter des headers personnalisés à la liste
// des headers déjà envoyée avec la requête initiale
_.extend(api.req.headers, {
'x-example-header': 'example header value'
})
// Aussi, on peut ajouter des 'query string' personnalisés
_.extend(api.req.qs, {
example: 'example query string'
})Un plugin
after
// Un simple traitement qui fait un test sur le statut
// retourné par la ressource
const okValue = api.res.statusCode === 200
// On peut modifier ou ajouter un header personnalisé
api.res.headers['x-ok'] = okValue;
// On peut aussi faire retourner le résultat immédiatement
// avec un body modifié
res.json({
...api.body,
ok: okValue
})
La configuration finale avec les deux plugins sera comme suit :
...
- type: resource
value:
name: My Resource
method: get
route: /route
extra :
plugins :
- before: |
_.extend(api.req.headers, {
'x-example-header': 'example header value'
})
_.extend(api.req.qs, {
example: 'example query string'
})
- after: |
const okValue = api.res.statusCode === 200
api.res.headers['x-ok'] = okValue;
res.json({
...api.body,
ok: okValue
})
api:
urlContext: myapi
version: "1"
Cas d'usages
Filtrage IP
extra:
plugins:
- before: |
const allowedIps = ['127.0.0.1'] # Liste d'IPs
const emails = ['consommateur@email.com'] # Compte consommateur sur lequel appliquer le filtrage
const isSandbox = res.locals.appKey.sandbox # Pour savoir si c'est une requête sandbox
const email = res.locals.user.email # Récupération de l'email consommateur
if (!isSandbox && (emails.includes(email) && !allowedIps.includes(req.ip)))
return res.status(403).send('Forbidden')
Ajout d'un header suivant l'environnement
extra:
plugins:
- before: >
const isSandbox = res.locals.appKey.sandbox;
if (isSandbox) {
api.req.headers['authorization'] = 'Bearer [SANDBOX_ACCESS_TOKEN]';
} else {
api.req.headers['authorization'] = 'Bearer [PROD_ACCESS_TOKEN]';
}
Restriction d’accès par IP ou plage d’IP
Pour limiter l’accès à l’API à partir d’une ou plusieurs adresses IP spécifiques, ou d’une plage d’IP, vous pouvez implémenter le code suivant :
extra:
plugins:
- before: |
const blackListIps = ['127.0.*.*']; // A remplacer par vos valeurs
if (blackListIps.some(pattern => new RegExp('^' + pattern.replace(/\*/g, '\\d{1,3}') + '$').test(req.ip)))
return res.status(403).send('Forbidden');