Bonnes pratiques pour la conception et le développement de proxys d'API avec Apigee

Cette page s'applique à Apigee et à Apigee hybrid.

Consultez la documentation d'Apigee Edge.

Ce document fournit un ensemble de bonnes pratiques pour le développement de proxys d'API avec Apigee.

Les sujets abordés ici incluent la conception, le codage, l'utilisation des règles, la surveillance et le débogage. Ces informations ont été recueillies par les développeurs travaillant avec Apigee pour la mise en œuvre de programmes d'API efficaces. Il s'agit d'un document évolutif, mis à jour de temps en temps.

En plus des consignes ci-dessous, l'article Présentation des antimodèles peut également vous être utile.

Normes de développement

Commentaires et documentation

  • Fournissez des commentaires intégrés dans les configurations ProxyEndpoint et TargetEndpoint. Les commentaires améliorent la lisibilité d'un flux, en particulier lorsque les noms des fichiers de règles ne sont pas suffisamment descriptifs pour exprimer la fonctionnalité sous-jacente du flux.
  • Proposez des commentaires utiles. Évitez les commentaires évidents.
  • Veillez à la cohérence des mises en retrait, des espacements, des alignements verticaux, etc.

Codage de type framework

Le codage de type framework consiste à stocker des ressources de proxy d'API dans votre propre système de contrôle des versions pour les réutiliser dans des environnements de développement locaux. Par exemple, pour réutiliser une règle, stockez-la dans le contrôle des sources afin que les développeurs puissent la synchroniser et l'utiliser dans leurs propres environnements de développement de proxy.

  • Pour activer l'approche DRY (Don't Repeat Yourself – Ne vous répétez pas), dans la mesure du possible, les configurations de règles et les scripts doivent implémenter des fonctions spécialisées et réutilisables. Par exemple, une règle dédiée pour extraire les paramètres de requête des messages de requête peut s'appeler ExtractVariables.ExtractRequestParameters.
  • Nettoyez les règles et les ressources inutilisées (JavaScript, Java, Excel, etc.) par les proxys d'API, en particulier les ressources volumineuses pouvant ralentir les procédures d'importation et de déploiement.

Conventions d'attribution de noms

  • L'attribut name de la règle et le nom du fichier XML de la règle doivent être identiques.
  • L'attribut name de la règle ServiceCallout policy et du script et le nom du fichier de ressources doivent être identiques.
  • DisplayName doit décrire précisément la fonction de la règle à une personne qui n'a jamais travaillé avec ce proxy d'API auparavant.
  • Nommez les règles selon leur fonction. Apigee vous recommande d'établir une convention de dénomination cohérente pour vos règles. Par exemple, utilisez des préfixes courts suivis d'une séquence de mots descriptifs séparés par des tirets. Par exemple, AM-xxx pour la règle AssignMessage. Renseignez-vous également sur l'outil apigeelint.
  • Utilisez les extensions appropriées pour les fichiers de ressources : .js pour JavaScript, .py pour Python et .jar pour les fichiers JAR Java.
  • Les noms des variables doivent être cohérents. Si vous choisissez un style, tel que "camelCase" ou "under_score", utilisez-le sur l'ensemble du proxy d'API.
  • Si possible, utilisez des préfixes de variable afin d'organiser les variables en fonction de leur finalité, par exemple Consumer.username et Consumer.password.

Développement d'un proxy d'API

Éléments à prendre en compte lors de la conception initiale

  • Pour obtenir des conseils sur la conception d'une API RESTful, téléchargez l'e-book Web API Design: The Missing Link.
  • Exploitez autant que possible les règles et fonctionnalités Apigee pour créer des proxys d'API. Évitez de coder la logique de proxy dans les ressources JavaScript, Java ou Python.
  • Créez vos flux de manière organisée. Plusieurs flux, comportant chacun une seule condition, sont préférables à plusieurs rattachements conditionnels au même PreFlow et au même Postflow.
  • Pour ce faire, créez un proxy d'API par défaut avec un chemin d'accès de base ProxyEndpoint /. Cela peut être utilisé pour rediriger les requêtes d'API de base vers un site de développement, pour renvoyer une réponse personnalisée ou pour effectuer une autre action plus utile que de renvoyer la valeur par défaut messaging.adaptors.http.flow.ApplicationNotFound.
  • Utilisez les ressources TargetServer pour dissocier les configurations TargetEndpoint des URL concrètes, en autorisant la promotion dans l'ensemble des environnements.
    Consultez la section Équilibrage de charge sur les serveurs de backend.
  • Si vous avez plusieurs règles de routage, créez-en une servant de "valeur par défaut", c'est-à-dire sans condition. Assurez-vous que la règle de routage par défaut est définie en dernier dans la liste des routes conditionnelles. Les règles de routage sont évaluées de haut en bas dans ProxyEndpoint. Consultez la documentation de référence sur la configuration des proxys d'API.
  • Taille d'un groupe de proxys d'API : les groupes de proxys d'API ne peuvent excéder 15 Mo.
  • Gestion des versions d'API : pour obtenir des informations et des recommandations d'Apigee concernant la gestion des versions d'API, consultez la section Gestion des versions de l'e-book Web API Design: The Missing Link.

Activer CORS

Avant de publier vos API, vous devez ajouter la règle CORS au PreFlow de requête du ProxyEndpoint afin de prendre en charge les requêtes multi-origines côté client.

CORS (Cross-Origin Resource Sharing) est un mécanisme standard qui permet aux appels XMLHttpRequest (XHR) exécutés sur une page Web d'interagir avec des ressources extérieures au domaine d'origine. CORS est une solution couramment mise en œuvre à la règle de même origine appliquée par tous les navigateurs. Par exemple, si vous effectuez un appel XHR à l'API Twitter à partir de code JavaScript exécuté dans votre navigateur, l'appel échoue. En effet, le domaine qui diffuse la page vers votre navigateur est différent du domaine diffusant l'API Twitter. CORS offre une solution à ce problème en autorisant des serveurs à accepter explicitement le partage de ressources entre origines multiples.

Pour en savoir plus sur l'activation de CORS sur vos proxys d'API avant la publication des API, consultez la section Ajouter la prise en charge de CORS à un proxy d'API.

Taille de la charge utile des messages

Pour éviter les problèmes de mémoire dans Apigee, la taille de la charge utile des messages est limitée à 10 Mo. Le dépassement de ce quota entraîne une erreur protocol.http.TooBigBody.

Ce problème est également abordé dans la section Erreur lors de la demande/du renvoi d'une charge utile importante avec un proxy Apigee.

Voici les règles recommandées pour gérer des tailles de messages importantes dans Apigee :

  • Diffuser un flux de requêtes et de réponses. Notez que lorsque vous diffusez un flux continu, les règles n'ont plus accès au contenu du message. Consultez la section Requêtes et réponses en flux continu.

Gestion des erreurs

  • Utilisez les règles FaultRules pour gérer les erreurs. (Les règles RaiseFault sont utilisées pour interrompre le flux de messages et déléguer le traitement au flux FaultRules.)
  • Dans le flux FaultRules, utilisez une règle AssignMessage pour créer la réponse à l'erreur, et non une règle RaiseFault. Exécutez les règles AssignMessage de manière conditionnelle en fonction du type d'erreur.
  • Incluez toujours un gestionnaire d'erreurs "catch-all" par défaut pour pouvoir mapper les erreurs générées par le système aux formats de réponse d'erreur définis par le client.
  • Si possible, faites en sorte que les réponses d'erreur soient toujours conformes aux formats standards disponibles dans votre entreprise ou votre projet.
  • Utilisez des messages d'erreur explicites et intelligibles, qui suggèrent une solution à la condition d'erreur.

Consultez la page Gérer les erreurs.

Persistance

Mappages clé-valeur

  • Utilisez des mappages clé-valeur uniquement pour des ensembles de données limités. Ceux-ci ne sont pas conçus pour stocker des données sur le long terme.
  • Tenez compte des performances lors de l'utilisation de mappages clé-valeur, car ces informations sont stockées dans la base de données Cassandra.

Consultez la section Règle KeyValueMapOperations.

Mise en cache des réponses

  • Ne remplissez pas le cache de réponse si la réponse n'est pas réussie ou si la requête n'est pas une requête GET. Les créations, les mises à jour et les suppressions ne doivent pas être mises en cache. <SkipCachePopulation>response.status.code != 200 or request.verb != "GET"</SkipCachePopulation>
  • Complétez le cache avec un seul type de contenu cohérent (par exemple, XML ou JSON). Après avoir récupéré une entrée responseCache, convertissez-la au type de contenu requis avec JSONtoXML ou XMLToJSON. Vous évitez ainsi de stocker le double, le triple ou plus encore de données.
  • Assurez-vous que la clé de cache est suffisante pour la mise en cache. Dans de nombreux cas, la valeur request.querystring peut être utilisée comme identifiant unique.
  • N'incluez pas la clé API (client_id) dans la clé de cache, sauf si elle est explicitement requise. Le plus souvent, les API sécurisées uniquement par une clé renvoient les mêmes données à tous les clients pour une requête particulière. Il est inefficace de stocker la même valeur pour un certain nombre d'entrées en fonction de la clé API.
  • Définissez des intervalles d'expiration pour le cache afin d'éviter les opérations de lecture intensive.
  • Dans la mesure du possible, essayez de faire en sorte que la règle de cache de réponse qui remplit le cache soit exécutée lors de la réponse PostFlow le plus tard possible. En d'autres termes, faites en sorte qu'elle s'exécute après les étapes de traduction et de médiation, y compris la médiation et la conversion basées sur JavaScript entre JSON et XML. En mettant en cache les données ayant fait l'objet d'une médiation, vous évitez les coûts de performances liés à l'exécution de l'étape de médiation chaque fois que vous récupérez des données mises en cache.

    Notez que vous pouvez également mettre en cache des données non résolues si la médiation génère une réponse différente selon les requêtes.

  • La règle de cache de réponse de recherche d'entrée de cache doit intervenir dans la requête PreFlow de ProxyEndpoint. Évitez de mettre en œuvre trop de logique autre que la génération de clé de cache avant de renvoyer une entrée de cache. Sinon, les avantages de la mise en cache sont minimes.
  • En général, vous devez toujours faire en sorte que la consultation du cache de réponse soit aussi rapprochée que possible de la demande du client. Inversement, vous devez faire en sorte que le remplissage du cache de réponse soit aussi rapproché que possible de la réponse du client.
  • Lorsque vous utilisez plusieurs règles de cache de réponses différentes dans un proxy, suivez les consignes ci-dessous pour que chacune se comporte discrètement :
    • Exécutez chaque règle en fonction de conditions qui s'excluent mutuellement. Cela permet de garantir l'exécution d'une seule règle de cache de réponse.
    • Définissez des ressources de cache différentes pour chaque règle de cache de réponse. Vous spécifiez la ressource de cache dans l'élément <CacheResource> de la règle.

Consultez la page concernant la règle ResponseCache.

Règle et code personnalisé

Règle ou code personnalisé ?

  • Utilisez avant tout les règles intégrées (si possible). Les règles Apigee sont renforcées, optimisées et compatibles. Par exemple, utilisez les règles standards AssignMessage et ExtractVariables au lieu de JavaScript (si possible) pour créer des charges utiles, extraire des informations des charges utiles. (XPath, JSONPath), etc.
  • JavaScript est préférable à Python et Java. Toutefois, si les performances sont l'exigence principale, Java doit être utilisé via JavaScript.

JavaScript

  • Utilisez JavaScript s'il est plus intuitif que les règles Apigee (par exemple, lorsque vous définissez target.url pour de nombreuses combinaisons d'URI différentes).
  • Analyse complexe de charge utile telle que l'itération d'un objet JSON et le codage/décodage en Base64.
  • La règle JavaScript possède une durée limite. Les boucles infinies sont donc bloquées.
  • Toujours utiliser les étapes JavaScript et placer les fichiers dans le dossier de ressources jsc. Les règles de type JavaScript précompilent le code au moment du déploiement.

Java

  • Utilisez Java si les performances sont prioritaires ou si la logique ne peut pas être mise en œuvre via JavaScript.
  • Incluez les fichiers source Java dans le suivi du code source.

Consultez la page sur la règle JavaCallout pour plus d'informations sur l'utilisation de Java dans les proxys d'API.

Python

  • N'utilisez pas Python à moins d'y être absolument obligé. Les scripts Python peuvent introduire des goulots d'étranglement affectant les performances des exécutions simples, car ils sont interprétés au moment de l'exécution.

Appels de scripts (Java, JavaScript, Python)

  • Utilisez un try/catch global ou équivalent.
  • Générez des exceptions pertinentes et interceptez-les correctement pour les utiliser dans les réponses d'erreur.
  • Générez et interceptez les exceptions de manière anticipée. N'utilisez pas de try/catch global pour gérer toutes les exceptions.
  • Effectuez des vérifications NULL et non définies, si nécessaire. Par exemple, lorsque vous récupérez des variables de flux facultatives.
  • Évitez d'effectuer des requêtes HTTP/S dans un appel de script. Utilisez plutôt la règle ServiceCallout, car elle gère les connexions sans interruption.

JavaScript

  • JavaScript sur la plate-forme d'API est compatible avec XML via E4X.

Consultez la page Modèle d'objet JavaScript.

Java

  • Lorsque vous accédez aux charges utiles des messages, essayez d'utiliser context.getMessage() plutôt que context.getResponseMessage ou context.getRequestMessage. Cela garantit que le code peut récupérer la charge utile dans les flux de requête et de réponse.
  • Importez des bibliothèques dans l'organisation ou l'environnement Apigee et ne les incluez pas dans le fichier JAR. Cela réduit la taille du groupe et permet aux autres fichiers JAR d'accéder au même dépôt de bibliothèque.
  • Importez des fichiers JAR à l'aide de l'API de ressources Apigee au lieu de les inclure dans le dossier des ressources de proxy d'API. Cela réduit les temps de déploiement et permettra aux fichiers JAR d'être référencés par plusieurs proxys d'API. Autre avantage : l'isolation du chargeur de classe.
  • N'utilisez pas Java pour le traitement des ressources (par exemple, la création et la gestion de pools de threads).

Python

  • Générez des exceptions pertinentes et interceptez-les correctement pour les utiliser dans les réponses d'erreur d'Apigee.

Consultez la règle PythonScript.

ServiceCallouts

  • Il existe de nombreux cas d'utilisation valides du chaînage de proxys, qui consiste à utiliser un appel de service dans un proxy d'API pour appeler un autre proxy d'API. Si vous utilisez la chaînage de proxys, veillez à éviter les appels récursifs en boucle infinie dans le même proxy d'API.

    Si vous connectez des proxys au sein d'une même organisation et d'un même environnement, assurez-vous de consulter la page Chaîner des proxys d'API pour en savoir plus sur la mise en œuvre d'une connexion locale permettant d'éviter une surcharge inutile du réseau.

  • Créez un message de requête ServiceCallout à l'aide de la règle AssignMessage et attribuez l'objet de la requête à une variable de message. (Cela inclut la définition de la charge utile de la requête, du chemin et de la méthode.)
  • L'URL configurée dans la règle requiert la spécification du protocole, ce qui signifie que la partie protocole de l'URL, https:// par exemple, ne peut pas être spécifiée par une variable. De plus, vous devez utiliser des variables distinctes pour la partie domaine de l'URL et pour le reste de l'URL. Exemple : https://example.com.
  • Stockez l'objet de réponse d'un ServiceCallout dans une variable de message séparée. Vous pouvez alors analyser la variable de message et préserver la charge utile du message d'origine pour l'utiliser dans d'autres règles.

Consultez la stratégie ServiceCallout.

Accéder aux entités

Règle AccessEntity

  • Pour de meilleures performances, recherchez les applications par uuid plutôt que par leur nom.

Consultez la page Règle AccessEntity.

Logging

  • Utilisez une règle syslog commune entre les groupes et dans un même groupe. Cela conserve un format de journalisation cohérent.

Consultez la page Règle MessageLogging.

Surveillance

Les clients cloud ne sont pas tenus de vérifier les composants individuels d'Apigee (routeurs, processeurs de messages, etc.). L'équipe de développement internationale d'Apigee contrôle minutieusement tous les composants et vérifie l'état des API à la demande du client.

Apigee Analytics

Analytics peut assurer un suivi non critique des API en mesurant les pourcentages d'erreur.

Consultez la page Tableaux de bord Analytics.

Debug

L'outil de traçage de l'interface utilisateur d'Apigee est utile pour déboguer les problèmes d'exécution des API lors de leur développement ou de leur exploitation en production.

Consultez la section Utiliser l'outil Debug.

Sécurité

Logique personnalisée dans les proxys d'API

Lors de la création de proxys d'API, l'inclusion d'une logique pour le traitement des requêtes et/ou des réponses est souvent exigée. Bien que de nombreuses exigences puissent être remplies à partir d'un ensemble prédéfini d'étapes/d'actions/de règles telles que la vérification d'un jeton, l'application d'un quota ou la réponse avec un objet mis en cache, il est souvent nécessaire d'avoir accès à la programmation. Par exemple, la recherche d'un emplacement (point de terminaison) à partir d'une table de routage basée sur une clé trouvée dans une requête et l'application dynamique d'un point de terminaison cible ou d'une méthode d'authentification personnalisée/propriétaire, etc.

Apigee fournit aux développeurs plusieurs options pour traiter cette logique personnalisée. Ce document explore ces options et à quel moment les utiliser :

Règle Cas d'utilisation des règles
JavaScript et PythonScript

À quel moment l'utiliser ?

  • Les règles JavaScript et PythonScript ont une capacité équivalente. La maîtrise d'un des langages par le développeur est généralement la raison pour laquelle il est préférable de choisir l'un plutôt que l'autre.
  • Les règles JavaScript et PythonScript sont particulièrement adaptées au traitement intégré de logique qui n'est pas trop complexe et ne nécessite pas l'utilisation de bibliothèques tierces.
  • Ces règles ne sont pas aussi performantes que la règle JavaCallout.

À quel moment ne pas l'utiliser ?

  • La passerelle API d'Apigee n'est pas un serveur d'applications (elle ne fournit pas non plus l'environnement d'exécution JavaScript complet, tel que node.js). Si le traitement de l'appel prend toujours plus d'une seconde, la logique n'appartient probablement pas à la passerelle et doit faire partie du service sous-jacent.

Bonne pratique : Apigee recommande JavaScript plutôt que PythonScript, car JavaScript offre de meilleures performances.

JavaCallout

À quel moment l'utiliser ?

  • Les performances de traitement intégré de la logique sont essentielles.
  • Les bibliothèques Java existantes fournissent une grande partie de la logique.

À quel moment ne pas l'utiliser ?

  • La passerelle API d'Apigee n'est pas un serveur d'applications et n'est pas conçue pour charger des frameworks tels que Spring, JEE, etc. Si l'appel prend généralement plus d'une seconde, la logique peut être considérée comme fonctionnelle (logique métier). Envisagez d'externaliser en tant que service.
  • Pour protéger la passerelle API Apigee contre toute utilisation abusive, des restrictions sont appliquées au type de code pouvant être exécuté. Par exemple, l'exécution de code Java qui tente d'accéder à certaines bibliothèques cryptographiques ou au système de fichiers est bloquée.
  • Les applications Java, en particulier celles qui reposent sur des bibliothèques tierces, peuvent importer de nombreux (et volumineux) fichiers JAR. Cela peut ralentir le démarrage des passerelles.
ExternalCallout

À quel moment l'utiliser ?

  • Idéalement adapté pour externaliser la logique personnalisée et permettre à la logique personnalisée d'accéder au contexte du message (et de le modifier si nécessaire).
  • Les appels externes mettent en œuvre gRPC et peuvent offrir de meilleures performances que ServiceCallout.
  • Lorsque vous utilisez Apigee ou Apigee Hybrid sur Google Cloud, envisagez d'utiliser Cloud Functions ou Cloud Run pour héberger une telle logique.
  • Pour remplacer efficacement la fonctionnalité Cibles hébergées dans Apigee Edge.

À quel moment ne pas l'utiliser ?

  • Pour une logique légère pouvant s'exécuter rapidement et de manière intégrée.
ServiceCallout

À quel moment l'utiliser ?

  • Il est préférable de mettre en œuvre une logique complexe en dehors de la passerelle. Cette logique peut avoir son propre cycle de vie (versions et gestion des versions) et n'affecte pas le fonctionnement de la passerelle.
  • Lorsque le point de terminaison REST/SOAP/GraphQL existe déjà ou peut être facilement mis en œuvre.
  • Lorsque vous utilisez Apigee ou Apigee Hybrid sur Google Cloud, envisagez d'utiliser Cloud Functions ou Cloud Run pour héberger une telle logique.
  • Pour remplacer efficacement la fonctionnalité Cibles hébergées dans Apigee Edge.

À quel moment ne pas l'utiliser ?

  • Pour une logique légère pouvant s'exécuter rapidement et de manière intégrée.
  • Le proxy d'API doit transférer le contexte (comme les variables) ou recevoir du contexte à partir de la mise en œuvre externe.

En résumé :

  1. Si la logique est simple ou triviale, utilisez JavaScript (de préférence) ou PythonScript.
  2. Si la logique intégrée nécessite de meilleures performances que JavaScript ou PythonScript, utilisez JavaCallout.
  3. Si la logique doit être externalisée, utilisez ExternalCallout.
  4. Si vous avez déjà des mises en œuvre externes et/ou que les développeurs connaissent bien REST, utilisez ServiceCallout.

La figure suivante illustre ce processus :