Mon père aime à me rappeler qu'en tant qu'ingénieur en informatique dans les années 1970, " il était programmeur avant que la programmation ne soit à la mode ". Il a même montré à plusieurs reprises d'anciens scripts Fortran et COBOL. Après avoir lu ce code, je peux affirmer avec confiance que la programmation est définitivement plus cool aujourd'hui .
Une caractéristique des langages de programmation et des environnements de développement modernes est la quantité de code qu'un développeur doit écrire en moins. En utilisant des langages de haut niveau ainsi que les nombreuses API disponibles, les packages open source et les services payants, les applications, même celles avec des exigences complexes, peuvent être créées assez rapidement.
Une comparaison pour démontrer l'évolution du développement logiciel est la construction. Il était une fois, la construction de n'importe quelle maison a commencé par l'abattage d'arbres sur votre site. Cependant, les matériaux, les outils et les méthodes sont rapidement apparus, de sorte que la construction a été achevée plus rapidement, les objets sont devenus plus solides et les travailleurs ont été libérés de certaines tâches élémentaires.
Combien de gratte-ciel seraient construits si les constructeurs exploitaient leur propre acier?
Les développeurs de logiciels, qui continuent à travailler à ce jour, à l'aube de leur carrière "coupent leurs propres arbres". Dans le même temps, des innovations sans précédent de la dernière décennie ont conduit au fait que l'industrie du logiciel a commencé à se développer à peu près de la même manière que la construction.
En termes simples, les développeurs d'aujourd'hui disposent désormais des outils, des techniques et des meilleures pratiques pour mener à bien des projets plus rapidement, obtenir des applications stables et éviter aux développeurs des tâches de bas niveau.
Comment créer une application de chat
Créons rapidement quelque chose qui prenait des jours ou des semaines. Nous allons créer une application Public Chat Room qui utilise WebSockets pour la messagerie en temps réel.
Les WebSockets sont pris en charge nativement par tous les navigateurs modernes. Cependant, notre objectif est de découvrir quels outils nous pouvons utiliser au travail, pas de les réinventer . Dans cette optique, nous utiliserons les technologies suivantes:
- 8base  - API GraphQL gérée
- VueJS - Framework  JavaScript
Le projet de démarrage et le fichier README complet se trouvent dans ce référentiel GitHub . Si vous ne voulez voir que l'application terminée, jetez un œil à la branche public-chat-room.
De plus, la vidéo ci-dessous (en anglais) explique chaque étape plus en détail.
Commençons.
Sept étapes pour créer une application de chat:
1. Configuration du projet
Clonez le projet de démarrage et accédez au répertoire de discussion de groupe. Vous pouvez décider vous-même d'utiliser yarn ou npm pour installer les dépendances de projet. Dans tous les cas, nous avons besoin de tous les packages NPM spécifiés dans le fichier package.json.
#
git clone https://github.com/8base/Chat-application-using-GraphQL-Subscriptions-and-Vue.git group-chat
#
cd group-chat
#
yarn
Pour interagir avec l'API GraphQL, nous devons configurer trois variables d'environnement. Créez un fichier .env.local dans le répertoire racine avec la commande suivante, et l'application Vue, après l'initialisation, définira automatiquement les variables d'environnement que nous avons ajoutées à ce fichier. Les deux valeurs et ne doivent pas être modifiées. Il vous suffit de définir la valeur . Si vous disposez d'un espace de travail 8base que vous souhaitez utiliser pour créer une application de chat à l'aide de notre didacticiel, mettez à jour le fichier .env.local avec votre ID d'espace de travail. Sinon, obtenez l'ID de l'espace de travail en suivant les étapes 1 et 2 de 8base Quickstart .
echo 'VUE_APP_8BASE_WORKSPACE_ID=<YOUR_8BASE_WORKSPACE_ID>
VUE_APP_8BASE_API_ENDPOINT=https://api.8base.com
VUE_APP_8BASE_WS_ENDPOINT=wss://ws.8base.com' \
> .env.local
VUE_APP_8BASE_API_ENDPOINT
VUE_APP_8BASE_WS_ENDPOINT
VUE_APP_8BASE_WORKSPACE_ID
2. Importer le schéma
Nous devons maintenant préparer le côté serveur. À la racine de ce référentiel, vous devriez trouver le fichier
chat-schema.json
. Pour l'importer dans l'espace de travail, il vous suffit d'installer la ligne de commande 8base et de vous connecter, puis d'importer le fichier de schéma.
# 8base CLI
yarn global add 8base-cli
# CLI
8base login
#
8base import -f chat-schema.json -w <YOUR_8BASE_WORKSPACE_ID>
3. Accès API
La dernière tâche du backend est d'autoriser l'accès public à l'API GraphQL.
Dans la console 8base, accĂ©dez Ă
App Services > Roles > Guest
. Mettez à jour les autorisations définies pour les publications et les utilisateurs afin qu'elles soient vérifiées ou définies comme Tous les enregistrements (comme indiqué dans la capture d'écran ci-dessous).
Le rôle Invité détermine ce que l'utilisateur qui effectue une demande d'API non authentifiée est autorisé à faire.
Éditeur de rôle dans la console 8base.
4. Écriture de requêtes GraphQL
Dans cette étape, nous allons définir et écrire toutes les requêtes GraphQL dont nous aurons besoin pour notre composant de chat. Cela nous aidera à comprendre quelles données nous allons lire, créer et écouter (via WebSockets) à l'aide de l'API.
Le code suivant doit être placé dans un fichier
src / utils / graphql.js
. Lisez les commentaires au-dessus de chaque constante exportée pour comprendre ce que fait chaque requête.
/* gql graphQL */
import gql from "graphql-tag";
‍
/* 1. - 10 */
export const InitialChatData = gql`
{
usersList {
items {
id
email
}
}
messagesList(last: 10) {
items {
content
createdAt
author {
id
email
}
}
}
}
`;
‍
/* 2. */
export const CreateUser = gql`
mutation($email: String!) {
userCreate(data: { email: $email, roles: { connect: { name: "Guest" } } }) {
id
}
}
`;
‍
/* 3. */
export const DeleteUser = gql`
mutation($id: ID!) {
userDelete(data: { id: $id, force: true }) {
success
}
}
`;
‍
/* 4. */
export const UsersSubscription = gql`
subscription {
Users(filter: { mutation_in: [create, delete] }) {
mutation
node {
id
email
}
}
}
`;
‍
/* 5. */
export const CreateMessage = gql`
mutation($id: ID!, $content: String!) {
messageCreate(
data: { content: $content, author: { connect: { id: $id } } }
) {
id
}
}
`;
‍
/* 6. . */
export const MessagesSubscription = gql`
subscription {
Messages(filter: { mutation_in: create }) {
node {
content
createdAt
author {
id
email
}
}
}
}
`;
5. Configuration du client Apollo pour les abonnements
Avec nos requĂŞtes GraphQL Ă©crites, il est temps de configurer nos modules API.
Tout d'abord, abordons le client API
ApolloClient
avec ses valeurs par défaut requises. Pour createHttpLink
nous, nous fournissons notre point de terminaison d'espace de travail entièrement formé. Ce code est en src/utils/api.js
.
import { ApolloClient } from "apollo-boost";
import { createHttpLink } from "apollo-link-http";
import { InMemoryCache } from "apollo-cache-inmemory";
‍
const { VUE_APP_8BASE_API_ENDPOINT, VUE_APP_8BASE_WORKSPACE_ID } = process.env;
export default new ApolloClient({
link: createHttpLink({
uri: `${VUE_APP_8BASE_API_ENDPOINT}/${VUE_APP_8BASE_WORKSPACE_ID}`,
}),
cache: new InMemoryCache(),
});
// Note: , // ApolloClient, .
Ensuite, nous traiterons le client d'abonnement en utilisant
subscriptions-transport-ws
et isomorphic-ws
. Ce code est un peu plus long que le précédent, il vaut donc la peine de prendre le temps de lire les commentaires dans le code.
Nous initialisons en
SubscriptionClient
utilisant notre point de terminaison WebSockets et workspaceId
dans les paramètres connectionParams
. Nous utilisons ensuite celui-ci subscriptionClient
dans deux méthodes définies dans l'export par défaut: subscribe()
et close()
.
subscribe
nous permet de créer de nouveaux abonnements avec des rappels de données et d'erreur. La méthode close est ce que nous pouvons utiliser pour fermer la connexion lorsque nous quittons le chat.
import WebSocket from "isomorphic-ws";
import { SubscriptionClient } from "subscriptions-transport-ws";
‍
const { VUE_APP_8BASE_WS_ENDPOINT, VUE_APP_8BASE_WORKSPACE_ID } = process.env;
/**
* ,
* .
*/
const subscriptionClient = new SubscriptionClient(
VUE_APP_8BASE_WS_ENDPOINT,
{
reconnect: true,
connectionParams: {
/**
* Workspace ID ,
* Websocket
*
*/
workspaceId: VUE_APP_8BASE_WORKSPACE_ID,
},
},
/**
* WebSocket, W3C. * , *WebSocket (, NodeJS)
*/
WebSocket
);
‍
export default {
/**
* , *'data’ 'error’
*/
subscribe: (query, options) => {
const { variables, data, error } = options;
‍
/**
* .
*/
const result = subscriptionClient.request({
query,
variables,
});
‍
/**
* * , ,
* subscriptionClient
*/
const { unsubscribe } = result.subscribe({
/**
*
* , .
*/
next(result) {
if (typeof data === "function") {
data(result);
}
},
/**
* , .
*/
error(e) {
if (typeof error === "function") {
error(e);
}
},
});
‍
return unsubscribe;
},
‍
/**
* subscriptionClient .
*/
close: () => {
subscriptionClient.close();
},
};
// . SubscriptionClient ,
// , .
6. Ecriture d'un composant Vue
Nous avons maintenant tout ce dont nous avons besoin pour créer un chat public. Il ne reste qu'un seul composant à écrire
GroupChat.vue
.
Chargez le composant en utilisant le service de fil et continuons.
Note importante: chacun a sa propre idée de la beauté, donc je n'ai fait que les styles minimaux nécessaires pour que le composant soit fonctionnel.
Script de composant
Tout d'abord, nous devons importer nos modules, styles simples et requĂŞtes GraphQL. Tout cela est dans le nĂ´tre
src / utils
.
DĂ©clarez les importations suivantes dans
GroupChat.vue
.
/* API */
import Api from "./utils/api";
import Wss from "./utils/wss";
/* graphQL */
import {
InitialChatData,
CreateUser,
DeleteUser,
UsersSubscription,
CreateMessage,
MessagesSubscription,
} from "./utils/graphql";
‍
/* */
import "../assets/styles.css";
Données des composants
Nous pouvons définir les propriétés de données que nous voulons utiliser dans la fonction de données de notre composant. Tout ce dont nous avons besoin est un moyen de stocker les utilisateurs du chat, les messages, le nom de l'utilisateur "actuel" et tout message qui n'a pas encore été envoyé. Ces propriétés peuvent être ajoutées comme suit:
/* imports ... */
export default {
name: "GroupChat",
‍
data: () => ({
messages: [],
newMessage: "",
me: { email: "" },
users: [],
}),
};
Crochets de cycle de vie
Nos hooks de cycle de vie s'exécutent à différents moments de la vie d'un composant Vue. Par exemple, lorsqu'il est monté ou mis à jour. Dans ce cas, nous ne nous intéressons qu'à la création et au
beforeDestroy
composant. Dans de tels cas, nous souhaitons soit ouvrir les abonnements au chat, soit les fermer.
/* ... */
export default {
/* ... */
/**
* , .
*/
created() {
/**
* ,
*/
Wss.subscribe(UsersSubscription, {
data: this.handleUser,
});
/**
* ,
*/
Wss.subscribe(MessagesSubscription, {
data: this.addMessage,
});
/**
* ( 10 )
*/
Api.query({
query: InitialChatData,
}).then(({ data }) => {
this.users = data.usersList.items;
this.messages = data.messagesList.items;
});
/**
* ,
*/
window.onbeforeunload = this.closeChat;
},
‍
/**
* , .
*/
beforeDestroy() {
this.closeChat();
},
};
MĂ©thodes des composants
Nous devons ajouter quelques méthodes pour traiter chaque réponse appel / API (
createMessage
, addMessage
, closeChat
, etc.). Tous seront stockés dans l'objet méthode de notre composant.
Il faut
noter une chose: la plupart des mutations n'attendent pas et ne gèrent pas les réponses. C'est parce que nous avons des abonnements qui suivent ces mutations. Après un lancement réussi, les données d'événement sont traitées par l'abonnement.
La plupart
de ces méthodes parlent d'elles-mêmes. Quoi qu'il en soit, lisez les commentaires dans le code suivant.
/* ... */
export default {
/* ... */
‍
methods: {
/**
* , .
*/
createUser() {
Api.mutate({
mutation: CreateUser,
variables: {
email: this.me.email,
},
});
},
/**
* ID.
*/
deleteUser() {
Api.mutate({
mutation: DeleteUser,
variables: { id: this.me.id },
});
},
/**
* ,
*
* .
*
* , ,
* , .
*/
handleUser({
data: {
Users: { mutation, node },
},
}) {
({
create: this.addUser,
delete: this.removeUser,
}[mutation](node));
},
/**
* users, , * .
*/
addUser(user) {
if (this.me.email === user.email) {
this.me = user;
}
this.users.push(user);
},
/**
* users ID.
*/
removeUser(user) {
this.users = this.users.filter(
(p) => p.id != user.id
);
},
/* */
createMessage() {
Api.mutate({
mutation: CreateMessage,
variables: {
id: this.me.id,
content: this.newMessage,
},
}).then(() => (this.newMessage = ""));
},
/**
* . * , , *.
*/
addMessage({
data: {
Messages: { node },
},
}) {
this.messages.push(node);
},
/**
* . beforeDestroy .
*/
closeChat () {
/* */
Wss.close()
/* */
this.deleteUser();
/* */
this.me = { me: { email: '' } }
}
},
‍
/* ... */
}
Modèle de composant
Dernier point mais non le moindre, nous avons un composant
GroupChat.vue
.
Il existe des
milliers d'excellents tutoriels sur la création de superbes interfaces utilisateur. Ce n'est pas l'un d'eux.
Le
modèle suivant Le rendre beau ou pas, c'est à vous. Cela dit, passons rapidement en revue le balisage clé que nous avons implémenté ici.
Comme
toujours, lisez les commentaires en ligne sur le code.
<template>
<div id="app">
<!--
, . ..
-->
<div v-if="me.id" class="chat">
<div class="header">
<!--
, , , , .
-->
{{ users.length }} Online Users
<!--
, closeChat..
-->
<button @click="closeChat">Leave Chat</button>
</div>
<!--
, , div. , , me.
-->
<div
:key="index"
v-for="(msg, index) in messages"
:class="['msg', { me: msg.participant.id === me.id }]"
>
<p>{{ msg.content }}</p>
<small
><strong>{{ msg.participant.email }}</strong> {{ msg.createdAt
}}</small
>
</div>
<!--
newMessage.
-->
<div class="input">
<input
type="text"
placeholder="Say something..."
v-model="newMessage"
/>
<!--
, createMessage.
-->
<button @click="createMessage">Send</button>
</div>
</div>
<!--
. , createUser.
-->
<div v-else class="signup">
<label for="email">Sign up to chat!</label>
<br />
<input
type="text"
v-model="me.email"
placeholder="What's your email?"
@blur="createUser"
required
/>
</div>
</div>
</template>
Et maintenant, le chat public est construit. Si vous l'ouvrez sur votre réseau local, vous pouvez commencer à envoyer et à recevoir des messages. Cependant, pour prouver qu'il s'agit d'une vraie discussion de groupe, ouvrez plusieurs fenêtres et regardez la progression de la conversation.
7. Conclusion et tests
Dans ce didacticiel, nous avons exploré comment l'utilisation d'outils de développement modernes nous permet de créer des applications du monde réel en quelques minutes.
J'espère que vous avez également appris à initialiser
ApolloClient
et Ă SubscriptionClient
exécuter efficacement des requêtes, des mutations et des abonnements GraphQL dans un espace de travail 8base, ainsi qu'un peu plus sur VueJS.
Que vous travailliez sur un jeu mobile, des messageries instantanées, des applications de notification ou d'autres projets nécessitant des données en temps réel, les abonnements sont un excellent outil. Et maintenant, nous commençons à peine à les considérer.
Créez une application de chat avec 8base
8base est un backend sans serveur clé en main en tant que service conçu par des développeurs pour des développeurs. La plateforme 8base permet aux développeurs de créer des applications cloud époustouflantes à l'aide de JavaScript et GraphQL. En savoir plus sur la plateforme 8base ici .