
Partager:
Je suis développeur JavaScript et éducateur de développeurs chez Vonage. Au fil des ans, j'ai été très intéressé par les modèles, Node.js, les applications Web progressives et les stratégies offline-first, mais ce que j'ai toujours aimé, c'est une API utile et bien documentée. Mon objectif est de faire en sorte que votre expérience de l'utilisation de nos API soit la meilleure possible.
Construire une application Nexmo avec Express et React
Avec le JavaScript Nexmo Client SDK, vous pouvez fournir une application frontale qui permet aux utilisateurs de contrôler les conversations auxquelles ils participent. A conversation Nexmo peut inclure deux utilisateurs ou plusieurs, et utiliser plusieurs médias différents. Permettre aux participants de contrôler les éléments de la conversation ne fait qu'ouvrir davantage d'options pour ce que votre application peut fournir.
React est un choix très populaire pour construire des applications pour le front-end, et des concepts comme Conversations et Utilisateurs dans le Nexmo Client SDK s'adaptent bien aux composants React avec leurs propres contrôles avec état. Cependant, il y a certaines choses que le Client SDK Nexmo ne peut pas faire, et donc l'image complète de votre application n'émerge pas tant que nous ne considérons pas le back-end. En utilisant Express, vous pouvez ajouter quelques routes simples pour soutenir votre front-end dans la gestion des utilisateurs et faire tout autre travail que vous jugez préférable de garder sur le serveur.
Contrairement à une application traditionnelle fournie par un serveur, votre front-end React est une application à part entière, ce qui signifie que votre appli "full stack" est en réalité deux applications. Chacune écoutera sur son propre port et répondra aux requêtes sans vérifier avec l'autre partie. Du point de vue de la structure des fichiers, il s'agit d'une application dans une application. Vous configurerez votre serveur Express à la racine de votre répertoire, puis vous ajouterez l'application React - complète avec son propre port séparé - dans un sous-répertoire. package.jsondans un sous-répertoire.
Configuration de l'application
À la racine du répertoire du projet, vous commencerez par créer un fichier package.json pour votre application Express et un server.js qui la contiendra. Vous devrez également créer un fichier .env qui contiendra les informations d'identification de votre application et de votre Account. Vous aurez besoin d'installer quelques paquets à partir de npm: Express, body-parser, dotenvet bien sûr le Nexmo Node SDK:
Pour démarrer vos deux applications en même temps, vous aurez également besoin de concurrently installé en tant que dépendance de développement :
Ensuite, vous fournirez les clés, les identifiants et les secrets nécessaires à l'identification de votre application application Nexmoque vous pouvez stocker dans votre fichier .env fichier :
Vous pouvez trouver votre clé API et votre secret sur le site Web de la Démarrage de votre tableau de bord Nexmo. Vous pouvez obtenir un identifiant d'application et une clé privée générée à télécharger à partir de la page Créer une application (si votre application est destinée à la messagerie, vous pouvez utiliser la page Créer une application de messagerie à la place). Dans l'exemple, la clé privée est enregistrée à la racine de votre répertoire, veillez donc à mettre à jour le chemin d'accès dans .env si vous la déplacez ailleurs.
Une fois cette configuration terminée, vous pouvez passer à la création de l'application client.
Créer une application React
Vous pouvez rapidement créer un échafaudage pour votre client en utilisant l'outil très pratique create-react-app. Étant donné que cette application React vivra dans un sous-répertoire de votre projet, vous pouvez spécifier le nom de sous-répertoire que vous préférez lorsque vous exécutez la commande (bien que vous puissiez vouloir changer le nom de l'application en quelque chose de plus descriptif une fois qu'elle génère son. package.json). Dans notre exemple, nous avons appelé le sous-répertoire "client" :
Cela vous donnera la plupart de ce dont vous avez besoin sur le client, y compris les dépendances de React et un ensemble de scripts pour faire des choses comme démarrer et construire votre application. Le seul paquetage supplémentaire dont vous aurez besoin de la part de npm est le Client SDK Nexmo:
Dans votre client package.json vous devrez également ajouter un proxy, qui fera référence à votre serveur Express et au port sur lequel il fonctionne :
"proxy": "http://localhost:3001", Serveur Express
L'initialisation de votre serveur Express devrait vous sembler familière si vous avez déjà travaillé avec Express. Vous devrez également avoir besoin de dotenv et body-parserqui seront attachés à votre application en tant qu'intergiciel :
require('dotenv').config();
// init server
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
app.use(bodyParser.json());Ensuite, vous devez créer un nouveau client Nexmo, en lui fournissant les variables que vous avez enregistrées dans votre fichier .env qui dotenv les rendra accessibles en tant que membres de process.env:
// create a Nexmo client
const Nexmo = require('nexmo');
const nexmo = new Nexmo({
apiKey: process.env.API_KEY,
apiSecret: process.env.API_SECRET,
applicationId: process.env.APP_ID,
privateKey: __dirname + process.env.PRIVATE_KEY
}, {debug: true});Pour cet exemple simple, nous ne créerons que des points de terminaison pour obtenir un JWT et créer un nouvel utilisateur. Vous pouvez définir les signatures de vos points de terminaison maintenant, et nous fournirons la logique pour les deux applications ensemble dans une étape ultérieure. Enfin, bien sûr, vous voudrez que votre serveur Express écoute sur le port que vous avez spécifié dans la méthode React package.json:
app.post('/getJWT', function(req, res) {});
app.post('/createUser', function(req, res) {});
app.listen(3001); Composant d'application React
Lorsque vous avez exécuté create-react-appil a dû créer un point d'entrée vers votre application à l'adresse src/index.js dans votre sous-répertoire client. Cela charge le composant défini dans src/App.js et le rend comme le corps de votre page d'atterrissage. Ce composant est un endroit idéal pour effectuer des tâches administratives telles que l'obtention d'un JWT et la connexion à votre application Nexmo. C'est également un bon conteneur pour deux composants enfants : User et Conversation. Pour commencer, importez deux composants que vous allez créer dans un instant :
import React from 'react';
import User from './User';
import Conversation from './Conversation';
import nexmoClient from 'nexmo-client';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {};
this.login = this.login.bind(this);
this.getJWT = this.getJWT.bind(this);
this.userUpdated = this.userUpdated.bind(this);
}
login() {}
getJWT() {}
userUpdated() {}
render() {}
};
export default App;Pendant que nous y sommes, vous pouvez voir que nous avons également importé le Client SDK de Nexmo et nettoyé la classe créée afin qu'elle soit prête à recevoir notre logique. Nous avons également ajouté des espaces réservés pour les fonctions dont nous aurons besoin.
Maintenant que vous avez des références aux deux composants enfants (même si nous ne les avons pas encore créés), vous pouvez mettre à jour votre fonction de rendu pour les charger sur votre page :
render() {
return (
<div className="nexmo">
<User onUpdate={this.userUpdated} />
<Conversation app={this.state.app} loggedIn={!!this.state.token} />
</div>
);
}
Connexion à l'application Nexmo
Le composant User va appeler userUpdated lorsqu'il voudra signaler des modifications de son état, de sorte que cette fonction devient le premier maillon de votre chaîne d'exécution. Vous chercherez une propriété username sur l'objet d'état que vous recevez et, si elle existe, continuez pour obtenir un JWT pour cet utilisateur :
userUpdated(user) {
if (user.username) {
this.getJWT(user.username);
}
}Votre fonction getJWT consistera principalement en un fetch et à la gestion de sa réponse. Vous devrez POST le nom d'utilisateur que la fonction reçoit vers le serveur Express sous forme de JSON, puis analyser les données et enregistrer votre nouveau JWT en tant que propriété state token. Ceci fait, vous pouvez appeler la fonction login pour terminer l'initialisation de votre application :
getJWT(username) {
fetch('/getJWT', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({name: username})
})
.then(results => results.json())
.then(data => {
this.setState({
token: data.jwt
});
this.login();
});
}
Obtenir un JWT du serveur
Revenons rapidement à notre application Express dans server.js et fournissons le point de terminaison que la fonction getJWT sera appelée par la fonction côté client. En utilisant le Nexmo Node SDKNexmo, nous pouvons générer un JWT en fournissant à nouveau l'identifiant de notre application, le nom d'utilisateur que nous envoyons depuis le client, une date d'expiration en minutes et une date de péremption en secondes. subou le nom d'utilisateur que nous envoyons depuis le client ; une expiration en secondes ; et les autorisations que nous voulons que ce jeton ait. Dans le code ci-dessous, l'utilisateur peut faire des choses impliquant l'utilisateur, les conversations, les sessions et les applications, ce qui est suffisant pour notre application très simple :
app.post('/getJWT', function(req, res) {
const jwt = nexmo.generateJwt({
application_id: process.env.APP_ID,
sub: req.body.name,
exp: Math.round(new Date().getTime()/1000)+3600,
acl: {
"paths": {
"/v1/users/**":{},
"/v1/conversations/**":{},
"/v1/sessions/**":{}
}
}
});
res.send({jwt: jwt});
});Maintenant que votre serveur envoie un jeton à l'application React, vous pouvez retourner à App.js et fournir la logique de votre fonction finale, login. Il n'y a pas grand-chose à faire. En utilisant le nouveau jeton sauvegardé dans l'état du composant App, vous vous connectez au client Nexmo et recevez une référence à votre application Nexmo connectée. Vous pouvez l'enregistrer dans l'état du composant, et c'est ainsi que ce composant est terminé !
login() {
let nexmo = new nexmoClient();
nexmo.createSession(this.state.token).then(app => {
this.setState({
app: app
});
});
}
Composant utilisateur React
Puisque votre composant App attend que le composant User déclenche le flux de connexion, créons ce composant maintenant. Dans un nouveau fichier User.js dans le même répertoire que App.jsvous pouvez donner un aperçu du composant :
import React from 'react';
class User extends React.Component {
constructor(props) {
super(props);
this.state = {};
this.createUser = this.createUser.bind(this);
this.setUsername = this.setUsername.bind(this);
};
createUser() {}
setUsername() {}
render() {}
};
export default User;Dans une application réelle, vous souhaiteriez utiliser un système pour gérer et stocker vos utilisateurs, ainsi que pour les authentifier. Pour cet exemple minimal, cependant, vous allez simplement créer un nouvel utilisateur chaque fois que vous accédez à cette page. Dans votre fonction render vous pouvez vérifier si l'état du composant contient une propriété userId dans l'état du composant. Si c'est le cas, vous pouvez afficher un message confirmant que l'utilisateur est connecté. Si ce n'est pas le cas, vous pouvez afficher un champ de texte et un bouton pour créer le nouvel utilisateur :
render() {
if (this.state.userId) {
return (
<div className="userinfo userconnected">
Connected as <span className="username">{this.state.username}</span>
</div>
);
} else {
return (
<div className="userinfo">
<input type="text" onChange={evt => this.setUsername(evt)} />
<button onClick={this.createUser}>Create user</button>
</div>
);
}
}
Création de nouveaux utilisateurs
La création de l'utilisateur est en fait un processus en deux parties qui commence par l'écoute des modifications apportées au texte de votre champ de texte et le stockage de la valeur mise à jour. Si vous souhaitiez rendre cette application plus robuste, vous pourriez commencer par vérifier cette valeur par rapport à vos règles de nom d'utilisateur et à votre liste d'utilisateurs existants et signaler à l'utilisateur les problèmes de validité ou de duplication par le biais d'un changement de style. Mais pour cet exemple, nous nous contenterons de stocker naïvement le texte saisi par l'utilisateur :
setUsername(evt) {
this.setState({
username: evt.target.value
});
}Une fois que l'utilisateur a cliqué sur le bouton "Créer un utilisateur", vous pouvez envoyer une autre demande à votre serveur Express. Vous enverrez le nom d'utilisateur tel qu'il est stocké dans l'état par setUsernameet lorsque le serveur répondra, vous déclencherez la fonction onUpdate fournie par le composant App lors de l'instanciation de ce composant :
createUser() {
fetch('/createUser', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({name: this.state.username})
})
.then(results => results.json())
.then(data => {
this.setState({
userId: data.id
}, () => this.props.onUpdate(this.state));
});
}
Le point d'arrivée createUser est le dernier élément de votre serveur Express qu'il nous reste à fournir. server.js et complétons cette logique. Vous pouvez appeler users.create sur votre objet Nexmo, en passant le nom d'utilisateur du client et un nom d'affichage optionnel (que nous n'avons pas inclus dans le code du client pour cette application, mais que vous pourriez choisir de fournir plus tard). Si vous y parvenez, vous transmettrez l'identifiant du nouvel utilisateur au client :
app.post('/createUser', function(req, res) {
nexmo.users.create({
name: req.body.name,
display_name: req.body.display_name || req.body.name
},(err, response) => {
if (err) {
res.sendStatus(500);
} else {
res.send({id: response.id});
}
});
});
Maintenant, toute la logique dont vous avez besoin pour créer un utilisateur dans vos applications React et Express est disponible, et donc votre application React sera capable de se connecter et de faire des choses comme créer une conversation.
Composant de conversation React
Le dernier fichier que vous devez créer est Conversation.jsdans le même répertoire que App.js et User.js. Il est encore plus petit que les deux que vous avez déjà créés, mais dans une application réelle, il s'agirait probablement du composant contenant le plus de logique et probablement même plusieurs composants enfants :
import React from 'react';
class Conversation extends React.Component {
constructor(props) {
super(props);
this.state = {};
this.createConversation = this.createConversation.bind(this);
}
createConversation() {}
render() {}
};
export default Conversation;La fonction render n'a besoin de fournir qu'un bouton, mais vous pouvez la rendre un peu plus agréable en désactivant le bouton jusqu'à ce que le composant App notifie à ce composant Conversation qu'il a effectué son travail d'initialisation. Vous pouvez ensuite masquer le bouton une fois que la conversation est engagée et qu'une référence à celle-ci est stockée dans l'état du composant :
render() {
if (this.state.conversation) {
return (
<div className="conversation">Joined conversation!</div>
);
} else {
return (
<div className="conversation">
<button
onClick={this.createConversation}
disabled={!this.props.loggedIn}>Start conversation</button>
</div>
);
}
}
La majeure partie de la logique sur laquelle repose la fonction createConversation s'appuie sur les objets Nexmo Application et Conversation. Lorsque l'utilisateur clique sur le bouton, vous pouvez créer une nouvelle conversation en appelant la propriété app transmise à ce composant. Cela renverra une conversation, que vous pourrez rejoindre, puis enregistrer en tant que propriété d'état :
createConversation() {
this.props.app.newConversation().then(conv => {
conv.join().then(member => {
this.setState({
conversation: conv
});
});
});
}
À partir de là, vous pouvez inviter d'autres utilisateurs à participer à la conversation, commencer à fournir des gestionnaires pour les événements de la conversation ou ouvrir un flux audio pour permettre aux participants de se parler.
Démarrer les applications
Vous voulez pouvoir démarrer vos applications Express et React comme si elles ne faisaient qu'une, et donc la dernière chose à faire est de fournir le mécanisme pour qu'elles démarrent ensemble. Vous avez déjà modifié l'application React package.json de React pour qu'elle soit au courant de l'existence de l'application Express ; il est maintenant temps d'ajouter quelques scripts à l'application Express package.json afin que npm start démarre effectivement tout.
Dans le fichier package.json à la racine de votre projet, ajoutez ou modifiez trois scripts : start, client, et server:
"scripts": {
"client": "cd client && npm start",
"server": "node server.js",
"start": "concurrently --kill-others-on-fail \"npm run server\" \"npm run client\""
},
Le paquet concurrently que vous avez installé au début de ce tutoriel démarrera le serveur Express en même temps qu'il naviguera vers le répertoire client (notez que vous devez remplacer "client" par le nom de votre sous-répertoire React si vous l'avez appelé autrement) et exécutera le script start fourni par create-react-app. Si vous exécutez npm start maintenant, vous devriez être en mesure d'ouvrir un navigateur vers l'application React à l'adresse http://localhost:3000 et voir votre application s'exécuter.
Vous voulez voir une version un peu plus complexe de cette application en action ? Vous pouvez voir le code étendu sur Glitch et le remixer pour expérimenter davantage avec Nexmo Conversations. Et maintenant que vous avez les bases, vous pouvez continuer à construire une application de chat avec React et Nexmo.
Partager:
Je suis développeur JavaScript et éducateur de développeurs chez Vonage. Au fil des ans, j'ai été très intéressé par les modèles, Node.js, les applications Web progressives et les stratégies offline-first, mais ce que j'ai toujours aimé, c'est une API utile et bien documentée. Mon objectif est de faire en sorte que votre expérience de l'utilisation de nos API soit la meilleure possible.