Rendez votre configuration NGINX encore plus modulaire et réutilisable avec njs 0.7.7

NGINX | 20 octobre 2022


Depuis le lancement du module JavaScript de NGINX (njs) en 2015 (initialement appelé nginScript) et sa mise à disposition générale en 2017<.htmla>, nous n’avons cessé d’ajouter de nouvelles fonctionnalités et d’améliorer notre implémentation au fil de dizaines de mises à jour de version. Habituellement, nous attendons la sortie d’une version de NGINX Plus pour présenter les fonctionnalités d’une nouvelle version de NGINX JavaScript, mais la version 0.7.7 nous enthousiasme tellement que, cette fois-ci, nous ne pouvons pas attendre !

Les améliorations majeures apportées à njs 0.7.7 contribuent à rendre votre configuration NGINX encore plus modulaire, structurée et réutilisable :

Pour en savoir plus sur njs et consulter la liste des cas d’utilisation pour lesquels nous proposons des exemples de code, lisez « Exploiter la puissance et la simplicité de JavaScript pour chaque requête avec le module JavaScript de NGINX » sur notre blog.

Pour obtenir la liste complète des nouvelles fonctionnalités et des corrections de bogues de njs 0.7.7, consultez la documentation relative aux modifications.

Déclaration de code JavaScript et de variables dans des contextes locaux

Dans les versions précédentes de njs, vous devez importer votre code JavaScript et déclarer les variables concernées – à l’aide des directives « js_import », « js_path », « js_set » et « js_var » – dans le contexte de niveau supérieur « http » ou « stream », ce qui revient à déclarer des variables globales au début d’un fichier principal. Cependant, les directives qui appellent effectivement les fonctions et variables JavaScript figurent dans un contexte enfant – par exemple, la directive « js_content » dans un bloc HTTP « location{} » et la directive « js_access » dans un bloc Stream « server{} ». Cela pose deux problèmes :

  1. Pour une personne qui parcourt la configuration, les déclarations dans les contextes http et stream constituent essentiellement du bruit, car rien n’indique où le code et les variables associés sont réellement utilisés.
  2. Dans le contexte enfant, il n’est pas évident de savoir où le code et les variables ont été importés et déclarés. Bien que nous recommandions d’inclure les blocs http{} et stream{} uniquement dans le fichier de configuration principal (nginx.conf) et d’utiliser la directive include pour charger des fichiers de configuration plus petits et propres à chaque fonction depuis les répertoires /etc/nginx/conf.d et /etc/nginx/stream.d, la configuration de NGINX est flexible : vous pouvez inclure des blocs http{} et stream{} dans plusieurs fichiers. Cela peut s’avérer particulièrement problématique dans les environnements où plusieurs personnes travaillent sur votre configuration NGINX et ne respectent pas toujours les conventions établies.

Dans njs 0.7.7 et les versions ultérieures, vous pouvez importer du code et déclarer des variables dans les contextes où ils sont utilisés :

Le fait de regrouper toute la configuration njs correspondant à un cas d’usage spécifique dans un seul fichier rend également votre code plus modulaire et portable.

Par exemple, dans les versions précédentes de njs, lorsque vous ajoutiez un nouveau script, vous deviez modifier à la fois nginx.conf (en ajoutant js_import et éventuellement js_path, js_set et js_var) et le fichier dans lequel la fonction JavaScript est appelée (ici, jscode_local.conf).

Chargement de l’exemple de code…

Chargement de l’exemple de code…

Dans njs 0.7.7 et les versions ultérieures, toute la configuration relative à la fonction util se trouve dans un seul fichier, « jscode_integrated.conf » :

Chargement de l’exemple de code…

Modifier le comportement en fonction du contexte d’exécution

Plusieurs nouvelles fonctionnalités de njs 0.7.7 vous permettent de modifier le comportement de votre code JavaScript en fonction du contexte (phase de traitement) dans lequel il s’exécute.

La propriété HTTP « r.internal »

La propriété HTTP « r.internal » est un indicateur booléen défini sur « true » pour les requêtes internes (qui sont traitées par des blocs location{} incluant la directive « internal »). Vous pouvez utiliser l’indicateur r.internal pour adapter la logique lorsqu’un script utilise un gestionnaire d’événements générique pouvant être appelé aussi bien dans des contextes internes que non internes.

Les requêtes suivantes sont considérées comme des requêtes internes :

  • Requêtes redirigées par les directives « error_page », « index », « random_index » et « try_files »
  • Requêtes redirigées par l’en-tête de réponse X-Accel-Redirect provenant d’un serveur en amont
  • Sous-requêtes appelées par les directives « auth_request » et « mirror », par les directives du module ngx_http_addition_module, ou par la commande Server Side Include (SSI) « include virtual » (prise en charge par le module ngx_http_ssi_module)
  • Requêtes modifiées par la directive « rewrite »

Amélioration de la méthode de flux « s.send() »

Dans les versions antérieures de njs, la méthode Stream s.send() dépend du contexte, car le sens dans lequel elle envoie les données est déterminé par l’emplacement (en amont ou en aval) de la fonction de rappel dans laquelle la méthode est appelée. Cela fonctionne correctement avec les fonctions de rappel synchrones – pour lesquelles s.send() a été conçue à l’origine –, mais échoue avec les fonctions asynchrones telles que ngx.fetch().

À partir de njs 0.7.7, la direction est stockée dans un indicateur interne distinct, que s.send() peut ensuite utiliser.

Des opérations sur les fichiers plus efficaces grâce au nouvel objet « fs.FileHandle() »

Le module de système de fichiers (fs) permet d’effectuer des opérations sur les fichiers. Le nouvel objet FileHandle du module fs encapsule un descripteur de fichier numérique. Les instances de l’objet FileHandle sont créées par la méthode fs.promises.open().

Utilisez l’objet « FileHandle » pour obtenir un descripteur de fichier, qui peut ensuite servir à :

  • Effectuer des opérations telles que read() et write() sur le fichier
  • Ouvrir un fichier et effectuer des opérations de lecture et d’écriture à un emplacement précis sans lire l’intégralité du fichier

Les propriétés suivantes de FileHandle ont été implémentées (pour plus d’informations sur les arguments obligatoires et facultatifs de chaque propriété, consultez la documentation ):

  • filehandle.fd
  • filehandle.read()
  • filehandle.stat()
  • filehandle.write()
  • filehandle.write()
  • filehandle.close()

Ces méthodes ont été mises à jour pour prendre en charge FileHandle (consultez la documentation correspondante pour en savoir plus sur les arguments de chaque méthode) :

Utilisez njs pour améliorer votre configuration

Avec njs 0.7.7, nous avons facilité le travail de vos équipes sur le code njs ainsi que son partage. Grâce à l’extension des contextes pris en charge par les directives njs, il est encore plus simple d’enrichir la configuration de NGINX avec du code JavaScript personnalisé. Vous pouvez ainsi faire un premier pas vers la création d’une passerelle API, d’un proxy inverse ou d’un serveur web qui ne soit pas un simple middleware ou composant périphérique de plus. Vous pouvez l’intégrer à votre application à l’aide de JavaScript, TypeScript ou de modules Node tiers, sans ajouter de composant supplémentaire à votre pile. Tout ce dont vous avez besoin, c’est de NGINX !

Vous avez des questions ? Rejoignez le Slack de la communauté NGINX et consultez le canal #njs-code-review pour en savoir plus, poser vos questions et obtenir des retours sur votre code njs.


Partager
Mots-clés : F5 NGINX, News, Tech, 2022

Articles de blog associés

Tendances actuelles des technologies cloud natives, de l’ingénierie de plateforme et de l’IA
NGINX | 13/10/2025

Tendances actuelles des technologies cloud natives, de l’ingénierie de plateforme et de l’IA

Découvrez les principaux enseignements tirés des réponses à l’enquête annuelle F5 NGINX sur les dernières tendances en matière de technologies cloud natives, de sécurité, d’ingénierie de plateforme et d’IA.

Quels contrôleurs Ingress NGINX sont affectés par les vulnérabilités CVE-2022-4886, CVE-2023-5043 et CVE-2023-5044 ?
NGINX | 03/11/2023

Quels contrôleurs Ingress NGINX sont affectés par les vulnérabilités CVE-2022-4886, CVE-2023-5043 et CVE-2023-5044 ?

Lorsque de nouvelles CVE sont signalées, il est facile de ne plus savoir si elles concernent un outil de contrôleur Ingress NGINX particulier, car il existe plusieurs projets. Cet article présente les CVE et explique comment distinguer les différents projets de contrôleurs Ingress afin de dissiper toute confusion.

Votre API est-elle en temps réel ? Testez sa latence avec l’outil rtapi de NGINX
NGINX | 11/03/2020

Votre API est-elle en temps réel ? Testez sa latence avec l’outil rtapi de NGINX

Votre API répond-elle aux requêtes en moins de 30 ms ? Si ce n’est pas le cas, il ne s’agit pas d’une API en temps réel offrant la faible latence exigée par la grande majorité des organisations. Mesurez la latence de votre API avec l’outil rtapi de NGINX et découvrez comment NGINX peut l’aider à offrir une réactivité en temps réel.

Un testeur d’expressions régulières pour NGINX et NGINX Plus
NGINX | 11/06/2019

Un testeur d’expressions régulières pour NGINX et NGINX Plus

Le testeur d’expressions régulières (regex) pour NGINX et NGINX Plus vous évite de tâtonner en vous indiquant si une expression régulière utilisée dans un bloc location ou map correspond aux valeurs comme prévu. Il génère la configuration appropriée et affiche les valeurs des groupes de capture.

Caches partagés avec les clusters de cache NGINX Plus, partie 1
NGINX | 24/01/2017

Caches partagés avec les clusters de cache NGINX Plus, partie 1

Optimisez la capacité de votre cache web en le répartissant entre plusieurs serveurs de cache web NGINX ou NGINX Plus. Découvrez comment procéder dans cet article.

Introduction aux microservices
NGINX | 19/05/2015

Introduction aux microservices

Les microservices suscitent actuellement beaucoup d’intérêt. Cet article de blog est le premier d’une série de sept consacrée à la conception, au développement et au déploiement de microservices.