Fermer

juillet 25, 2019

Guide du débutant sur Feathers.js –


Dans cet article, vous allez apprendre à créer un serveur API RESTful dans Node.js à l'aide de Feathers.js .

Un serveur API, également appelé serveur d'applications . est un programme qui fournit des données aux applications front-end. Il gère également la logique métier dans le back-end et fournit un accès restreint à la base de données d’une organisation. Cela n'empêche pas uniquement des personnes non autorisées d'accéder aux données; il peut également empêcher les utilisateurs connectés d'accéder aux données ou de les modifier s'ils ne sont pas autorisés à le faire.

Chaque application que vous créez doit fournir un service à ses utilisateurs finaux. Pour cela, votre application aura besoin de données à traiter. Vous pouvez utiliser des API distantes pour créer un nouveau service. Cependant, pour la plupart des applications, vous devrez gérer votre propre magasin de données. Une option populaire consiste à utiliser des services de stockage de données en ligne tels que Firebase . De cette façon, vous n’aurez pas à vous occuper des détails fastueux de l’exécution d’un serveur de base de données répartie. Toutefois, les besoins de votre projet peuvent nécessiter l’utilisation d’un système de gestion de base de données interne à part entière, tel que MongoDB ou Oracle. Pour que votre application frontale puisse accéder aux données stockées dans la base de données, vous avez besoin d'une application serveur située entre la base de données et l'application frontale.

 architecture

Comme illustré dans. Dans le diagramme ci-dessus, le travail d'un serveur d'applications consiste à accéder aux données d'une base de données à l'aide de commandes SQL ou NoSQL et à les convertir dans un format lisible par les applications frontales (navigateur client), telles que JSON. En outre, le serveur d'applications peut utiliser divers protocoles de sécurité, tels que le cryptage HTTPS et l'autorisation de jeton, pour garantir la sécurité de la communication entre la base de données et l'application client. L'un des principaux avantages de cette architecture est que vous pouvez déployer des applications qui ciblent différentes plates-formes – ordinateurs de bureau, mobiles, Web, etc. – à l'aide du même serveur d'applications. Il est également très facile de faire évoluer votre application horizontalement afin de servir efficacement plus d'utilisateurs avec des temps de réponse rapides.

Nous allons créer un serveur d'API simple et démontrer les différentes fonctionnalités fournies par Feathers.

Conditions préalables

Avant de commencer à suivre ce didacticiel, vous devez avoir de bonnes bases dans les sujets suivants:

Feathers est construit sur Express un framework web minimaliste pour Node.js. Si vous avez terminé les didacticiels illustrés dans les liens, vous réaliserez qu’il est assez fatiguant de créer des API RESTful en utilisant uniquement Express. Avec Feathers, la plupart du travail répétitif est déjà fait pour vous. Vous devez seulement vous concentrer sur la configuration et la personnalisation du code. Parcourons le code et apprenons comment fonctionne ce framework Web.

Création du projet

Pour commencer à utiliser Feathers, vous devez installer son application de ligne de commande de manière globale:

 npm install -g @ feathersjs / cli

Créez ensuite un nouveau projet d'API à l'aide des commandes ci-dessous:

 mkdir contacts-api
cd contacts-api
les plumes génèrent une application

Voici les options que j'ai choisies. N'hésitez pas à choisir n'importe quel framework de test. Malheureusement, les tests ne sont pas au centre de cet article, ils ne seront donc pas abordés ici. Personnellement, j'aime la simplicité et c'est pourquoi j'ai choisi Jest .

 Créer une application Feathers en ligne de commande

Une fois l'installation terminée, vous pouvez vous ouvrir. éditeur de code préféré pour examiner les fichiers de projet.

 Structure du projet, telle qu’elle est visualisée dans un éditeur de code

Si vous avez terminé les didacticiels Express que j’ai énumérés dans la section des conditions préalables, vous ne devriez pas être intimidé par le code généré. Voici un bref résumé décrivant les dossiers et les fichiers.

 Les fichiers créés

Ne vous inquiétez pas trop de ce que fait chaque fichier. Vous allez comprendre comment ils fonctionnent dans le cours de ce tutoriel. Pour l’instant, confirmons que les tests fonctionnent.

Linting

Pour que notre projet soit conforme aux règles définies ESLint il suffit d’exécuter la commande npm test . Si vous utilisez une plate-forme Unix ou Linux, cela devrait fonctionner correctement. Si vous êtes sous Windows, vous avez peu de choses à régler pour que les tests fonctionnent correctement.

Commencez par aller à package.json et consultez la section des scripts. Modifiez la ligne test en ceci:

 "scripts": {
  "test": "npm run eslint && SET NODE_ENV = npm run jest",
},

Ensuite, si vous avez installé Prettier dans Visual Studio Code, vous devez modifier le paramètre guillemets simples en true dans l'onglet Paramètres de l'espace de travail:

 {
  "prettier.singleQuote": true
}

Enfin, assurez-vous que, lorsque vous créez ou modifiez un fichier, la fin de la ligne est LF . Si vous utilisez Visual Studio Code ou un éditeur similaire, vous pouvez vérifier le style de fin de ligne actuel dans la barre d’état. Si on dit CRLF remplacer par LF . Ces modifications vous aideront à réussir les tests de peluche. Malheureusement, la réussite des tests nécessitera un peu plus de travail, qui ne sera pas traité ici.

Voyons comment générer une interface CRUD RESTful.

Générer un service

Création d'une API CRUD reposante l'interface dans Express nécessite un peu de travail. Dans Feathers, tout ce que vous avez à faire est d’exécuter une seule commande, de répondre à quelques questions et de faire générer le code pour vous:

 $ feathers generate service
? De quel type de service s'agit-il? NeDB
? Quel est le nom du service? Contacts
? Sur quel chemin le service doit-il être enregistré? /Contacts
? Quelle est la chaîne de connexion à la base de données? nedb: //../data
    force config  default.json
   créez src  services  contacts  contacts.service.js
    force src  services  index.js
   crée src  models  contacts.model.js
   créez src  services  contacts  contacts.hooks.js
   créer test  services  contacts.test.js

Nous utiliserons la base de données NeDB pour ce didacticiel. Feathers prend en charge les bases de données SQL telles que MySQL et les bases NoSQL telles que MongoDB . Cependant, l’installation d’un système de base de données – sur votre ordinateur ou sur un serveur cloud – nécessite un certain temps pour le configurer. NeDB, en revanche, est une base de données en mémoire 100% JavaScript et prend en charge un sous-ensemble de l’API MongoDB. Aucune configuration n’est nécessaire; vous venez de l'installer. C’est une excellente base de données pour le prototypage et le test de nouvelles applications. C’est ce que nous allons utiliser dans ce didacticiel.

Voyons brièvement quelques fichiers générés à l’aide de cette commande:

  • services / contacts / contact.service.js . Il s'agit d'un service Feathers qui fournit les points de terminaison de l'API CRUD pour / contacts . Assez petit, n'est-ce pas? C'est parce que Feathers fait le gros du travail pour nous. Cela nous évite d’écrire du code CRUD standard

  • services / contacts / contact.hooks.js . C'est ici que nous personnalisons le comportement de la logique CRUD. Nous avons la section avant où nous pouvons vérifier ou modifier les données avant que Feathers ne lise ou n'écrit dans la base de données. Nous avons également une section après dans laquelle nous pouvons vérifier ou modifier les résultats de la base de données avant qu’elle ne soit envoyée à l’application cliente. Nous pouvons faire des choses comme restreindre l'accès, la validation des données, effectuer des opérations de jointure et calculer des valeurs pour des champs ou des colonnes supplémentaires.

  • models / contacts.model.js . C'est ici que nous définissons un modèle et l'attachons à une table de base de données. C'est également ici que nous définissons un schéma pouvant être utilisé pour valider les champs lorsqu'un nouvel enregistrement est inséré ou mis à jour. Malheureusement, NeDB ne supporte pas les schémas. Cependant, j’ai fourni un exemple de modèle connecté à MongoDB, qui prend en charge la fonctionnalité de schéma via l’adaptateur mongoose :

 "use strict";

const mangouste = require ("mangouste");
const Schema = mongoose.Schema;
require ("mongoose-type-email");

const contactsSchema = new Schema ({
  prénom: {
    first: {type: String, requis: [true, "First Name is required"]},
    last: {type: String, requis: false}
  },
  email: {
    type: mongoose.SchemaTypes.Email,
    requis: [true, "Email is required"]
  },
  téléphone: {
    type: chaîne,
    requis: [true, "Phone is required"],
    valider: {
      validateur: fonction (v) {
        return / ^  + (?: [0-9]?) {6,14} [0-9] $ /. test (v);
      },
      message: "{VALUE} n'est pas un numéro de téléphone international valide!"
    }
  },
  createdAt: {type: Date, par défaut: Date.now},
  updatedAt: {type: Date, par défaut: Date.now}
});

const contactsModel = mongoose.model ("contacts", contactsSchema);

module.exports = contactsModel;

Malgré les limites de l’utilisation de NeDB, c’est toujours une excellente base de données pour le prototypage. La plupart des bases de données NoSQL vous permettront de soumettre des données en utilisant n'importe quelle structure sans avoir à définir un schéma au préalable. Il est plus sage de mettre en place un schéma une fois que les exigences du projet ont été réalisées. Avec un schéma en place, Feathers procédera à une validation sur le terrain en utilisant les règles que vous avez définies. Vous aurez besoin d’une base de données prête pour la production telle que MongoDB pour pouvoir définir un schéma. Notez que la configuration de la base de données de développement est définie dans config / default.json :

 "nedb": "../data"

C'est ici que les informations d'identification de la base de données sont fournies. Nous avons également un autre fichier de configuration appelé config / production.json . Il s'agit de la configuration de la base de données de production utilisée lors du déploiement de votre application Feathers. Il est important d’utiliser une base de données distincte pendant le développement. Sinon, vous courez le risque de supprimer ou de corrompre les données opérationnelles de la base de données de production.

Maintenant que nous avons mis en place notre service CRUD pour les contacts il est temps de l'essayer. Vous pouvez démarrer le serveur Feather à l’aide de la commande npm start . Notez que ce serveur ne prend pas en charge le rechargement à chaud. Vous devrez donc le redémarrer chaque fois que vous apportez une modification au code. Pour interagir avec notre application Feathers, nous avons besoin d’un navigateur API, tel que Postman ou Insomnia . J'utiliserai Insomnia dans ce didacticiel, mais vous pourrez facilement suivre Postman ou tout autre outil.

Créez une nouvelle requête GET (appuyez sur Ctrl + N ). donnez-lui le titre «Liste des contacts». Dans la section URL, entrez http: // localhost: 3030 / contacts . Lorsque vous appuyez sur le bouton Envoyer vous devez avoir la vue suivante:

 Répertorier les demandes de contacts: la vue dans votre éditeur de code après avoir appuyé sur le bouton Envoyer

Rien! Notre base de données est actuellement vide, nous devons donc créer de nouveaux contacts. Créez une nouvelle demande appelée Create Contact . Remplissez les autres champs comme indiqué ci-dessous:

 Formulaire de création du nouveau contact

Si vous avez oublié de modifier METHOD en POST dans le formulaire ci-dessus, vous pouvez le faire ultérieurement. Changez la méthode en POST et changez l'onglet Body en JSON. Copiez les données suivantes dans l'onglet JSON:

 {
  "prénom": {
    "premier": "Jack",
    "dernier": "Bauer"
  },
  "email": "jack@ctu.mail",
  "phone": "+1234567"
}

Lorsque vous appuyez sur le bouton Envoyer, vous devriez obtenir la réponse suivante. Notez qu'un _id a été généré pour votre nouveau contact.

 Réponse avec un nouvel ID

Retournez à la List Contacts et appuyez sur la touche ] Envoyez à nouveau le bouton . Vous devriez obtenir le résultat suivant:

 {
  "total": 1,
  "limite": 10,
  "sauter": 0,
  "data": [
    {
      "name": {
        "first": "Jack",
        "last": "Bauer"
      },
      "email": "jack@ctu.mail",
      "phone": "+1234567",
      "_id": "ybnRxL6s2QEGhj4i"
    }
  ]
}

Retournez à Créez un contact et publiez deux nouveaux enregistrements:

 {
  "prénom": {
    "premier": "Chloé",
    "dernier": "O'Brian"
  },
  "email": "chloe@ctu.mail",
  "téléphone": "+1987654"
}
 {
  "prénom": {
    "premier": "Renée",
    "dernier": "Walker"
  },
  "email": "renee@fbi.mail",
  "phone": "+150505050"
}

Maintenant, effectuons une mise à jour. Pour cela, nous n’utilisons pas la méthode UPDATE HTTP. Cette méthode écrasera complètement un enregistrement. Ce que nous voulons faire, c'est simplement écraser un seul champ, pas l'intégralité de l'enregistrement. Pour cela, nous utiliserons PATCH. Créez une nouvelle demande, Mise à jour du contact comme illustré ci-dessous:

 Mise à jour d'un contact

Dans le champ URL, entrez http: // localhost: 3030 / contacts / {_ id} . Remplacez {_ id} par l'ID du premier enregistrement. Placez les données suivantes dans l'onglet JSON:

 {
  "email": "jack.bauer@gmail.com"
}

Appuyez sur le bouton Envoyer . Vous devriez obtenir le résultat suivant:

 08-Patch-Jack-Email

Remarquez comment le reste des champs reste intact. Ensuite, nous allons supprimer un enregistrement. Celui-ci est facile. Créez simplement une nouvelle demande DELETE et nommez-la Delete Contact . Dans le champ URL, utilisez le format http: // localhost: 3030 / contacts / {_id} . Comme auparavant, remplacez {_ id} par l'ID de l'enregistrement que vous souhaitez supprimer. Frapper Envoyer supprimera cet enregistrement pour vous. Vous pouvez confirmer en exécutant à nouveau la demande List Contact .

Nous venons de vérifier que toutes les opérations CRUD fonctionnaient correctement. Dans la section suivante, nous allons apprendre à configurer l'authentification.

Authentification

Actuellement, notre point de terminaison API / contacts n'est pas protégé. Si nous déployions notre application sur un serveur cloud, toute personne disposant de l'URL peut accéder à nos enregistrements et les manipuler. Pour restreindre l'accès, nous devons configurer l'authentification. Nous allons utiliser le JSON Web Token pour implémenter l’authentification sur notre application API. Exécutez la commande suivante pour le configurer:

 les plumes génèrent une authentification

Comme vous pouvez le voir ci-dessous, Feathers prend en charge différentes méthodes d'authentification des utilisateurs. Le plus simple à configurer est l'option “Nom d'utilisateur local + Mot de passe”.

 Options de configuration de l'authentification dans Feathers

Choisissez les options suivantes pour le reste des questions.

 Options pour les questions restantes

Vous pouvez consulter les fichiers générés par la commande que vous venez d'exécuter:

 fichiers d'authentification

L'étape suivante consiste à créer un nouvel utilisateur. . Nous pouvons le faire en utilisant Insomnia ou tout autre outil de navigateur API. Créez une nouvelle demande et appelez-le Créer un utilisateur :

 Créer un formulaire d'utilisateur

Dans l'onglet JSON, envoyez les données suivantes:

 {
  "email": "admin@example.com",
  "mot de passe": "secret"
}

Vous devriez obtenir une réponse similaire à celle ci-dessous:

 Utilisateur créé

Nous avons maintenant un utilisateur. Confirmons cela en créant une nouvelle requête Lister les utilisateurs et en envoyant l’URL http: // localhost: 3030 / users . Malheureusement, vous obtiendrez la réponse suivante:

 Échec de la liste des utilisateurs

Nous devons nous authentifier pour pouvoir accéder à ces données. Comme nous n’avons pas développé d’application frontale que nous puissions utiliser pour nous connecter, nous allons continuer à utiliser le navigateur API. Créez une nouvelle demande et appelez-la «Obtenir un jeton JWT». Remplissez le formulaire comme indiqué ci-dessous:

 Obtenez le formulaire de jeton JWT

Cette demande utilise la méthode POST. Peut-être que vous pouvez renommer la demande "Login" pour plus de clarté. Dans l'onglet JSON, copiez les données suivantes:

 {
  "stratégie": "local",
  "email": "admin@example.com",
  "mot de passe": "secret"
}

Vous devez obtenir la réponse suivante après avoir appuyé sur le bouton d’envoi:

 Jeton d’accès généré

Copiez le code de jeton (sans les guillemets). Allez à la page de demande List Users sélectionnez l'onglet Auth et sélectionnez Bearer . Collez ce code de jeton dans le champ TOKEN .

 Répertorier les utilisateurs avec le jeton

Lorsque vous cliquez sur le bouton Envoyer vous devriez obtenir une liste de utilisateurs. Notez que notre système d'authentification n'est pas complètement sécurisé. Toute personne possédant le point de terminaison URL / users peut créer un nouveau compte et accéder à notre système. Pour empêcher la création non autorisée de nouveaux comptes, nous devons également limiter ce terminal. Ouvrez le fichier services / users / users.hooks.js et mettez à jour le code suivant:

 module.exports = {
  avant: {
    // ...
    créer: [ hashPassword(), authenticate('jwt') ],
    // ...

Cela garantira que seuls les utilisateurs authentifiés peuvent créer de nouveaux comptes. L'étape suivante consiste également à protéger le point final / contacts . Ouvrez simplement le fichier services / contacts / contacts.hooks.js et mettez-le à jour en conséquence:

 const {authenticate} = require ('@ feathersjs / authentication'). Hooks;

module.exports = {
  avant: {
    tout: [authenticate('jwt')],
    // ...
  },

Redémarrez le serveur Feathers pour que les modifications de code prennent effet. Si vous essayez d'exécuter la demande List Contacts vous obtiendrez la réponse suivante:

 {
  "name": "NotAuthenticated",
  "message": "Pas de jeton d'authentification",
  "code": 401,
  "className": "non authentifié",
  "Les données": {},
  "les erreurs": {}
}

Pour vous authentifier, vous devez définir le jeton Bearer comme vous l’avez fait auparavant. Une fois que vous avez terminé, vous pouvez envoyer votre demande et recevoir votre liste de contacts. Notez que le jeton que vous avez acquis précédemment expirera après un jour. Par souci d’efficacité, il est préférable d’utiliser les variables d’environnement pour faciliter la mise à jour simultanée de tous vos paramètres de requête d’API. Lors de la création d’une application frontale, vous devez stocker ce jeton dans le stockage local . N'utilisez pas de cookies. Sinon, votre application sera susceptible d'attaques CSRF . Consultez la documentation de Feathers sur la sécurité pour en savoir plus sur les autres risques de sécurité dont vous devriez être au courant.

Maintenant que vous avez configuré l'authentification, tout nouveau service que vous créez après vous donnera l'option de protéger votre nouveau point de terminaison. Voyons maintenant le sujet final de ce didacticiel dans la section suivante.

Les crochets

Les crochets sont des fonctions de middleware attachées à avant après ou sur . erreurs d'une méthode de service. Ils sont généralement utilisés pour gérer des tâches telles que la journalisation, la restriction d'accès, la protection des champs, le remplissage des entités associées, l'envoi de notifications, etc. Si vous regardez services / utilisateurs / utilisateurs.hooks.js vous pouvez voir que certains crochets Feathers intégrés sont utilisés. Nous allons créer notre propre crochet personnalisé. Tout d’abord, arrêtez le serveur et supprimez la table de base de données data / contacts.db . Créez ensuite un nouveau crochet en le générant à l'aide de la commande suivante:

 les plumes génèrent des crochets.

Utilisez les options suivantes pour créer le crochet personnalisé processus-contact :

 Créer un processus de contact dans Hook

Ce que nous voulons faire dans ce crochet consiste à injecter deux nouveaux champs juste avant la demande Créer un contact est traité.

  • createdBy : lien vers l'utilisateur actuellement connecté par _id
  • createdOn : ajouter une date de création

. fichier hooks / process-contact.js et mettez à jour le fichier comme suit:

 module.exports = fonction (options = {}) {
  retourne le contexte async => {
    contexte de retour;
  };
};
 module.exports = fonction (options = {}) {
  retourne le contexte async => {
    // Obtenir un utilisateur authentifié
    const user = context.params.user;

    // Extraire les données soumises
    const {data} = context;

    // Ajouter de nouveaux champs
    context.data = {
      ... data, // Conserver les données soumises
      createdBy: user._id,
      createdOn: new Date ()
    };
    contexte de retour;
  };
};

Créez ensuite un autre crochet, populate-user qui associera un objet à chaque enregistrement de contact à la demande. Suivez les instructions de la capture d'écran ci-dessous:

 peupler l'utilisateur hook

Ouvrez le fichier hooks / populate-user et insérez le code suivant:

 // eslint -disable-next-line sans-vars-non-utilisés
module.exports = fonction (options = {}) {
  retourne le contexte async => {
    const {app, méthode, résultat, params} = contexte;

    // Assure que les contacts sont un tableau. S'il s'agit d'un contact unique, enveloppez-le dans un tableau
    const contacts = method === "find"? résultat.data: [result];

    // Récupère l'objet utilisateur de chaque contact createdBy
    attend Promise.all (
      contacts.map (async contact => {
        contact.user = wait app
          .service ("utilisateurs")
          .get (contact.createdBy, params);
      })
    )

    contexte de retour;
  };
};

Lisez les commentaires pour comprendre comment cela fonctionne. Vous pouvez maintenant démarrer le serveur. Créez à nouveau les trois contacts à l'aide de la demande Créer un contact . Définissez le jeton porteur, si vous ne l’avez pas déjà fait. Sinon, vous recevrez une erreur d’autorisation. Voici le type de réponse que vous devriez obtenir lorsque vous créez un nouveau contact:

 Créé par with auth

Résumé

J'espère que vous avez maintenant appris à créer rapidement votre propre serveur API RESTful . Nous n’avons abordé que les bases et vous devriez parcourir le guide complet pour découvrir plus de fonctionnalités que Feathers peut vous fournir pour vous aider à implémenter des fonctionnalités avancées avec un minimum d’effort. Vous devriez également consulter la page Awesome Feathers qui contient un trésor de ressources. Que vous ayez besoin d’un plugin, d’un exemple de projet ou d’un tutoriel, vous y trouverez probablement un lien. Vous devriez également consulter Feather-plus CLI qui est Feathers on steroids. Il ajoute de nouvelles fonctionnalités à celles déjà fournies par la CLI de Feathers, telles que la génération de code pour l'ensemencement et le support GraphQL.

Si vous souhaitez faire progresser le projet contacts-api vous encourage à créer une nouvelle application frontale en utilisant un cadre de votre choix. Créez un écran de connexion et des pages CRUD pour les terminaux / contacts et / users . Amuse-toi à mettre en oeuvre le défi.




Source link