Comment créer un blog avec Nest.js, MongoDB et Vue.js

L'auteur a sélectionnéSoftware in the Public Interest Inc pour recevoir un don dans le cadre du programmeWrite for DOnations.

introduction

Nest.js est un framework JavaScript évolutif côté serveur construit avec TypeScript qui préserve toujours la compatibilité avec JavaScript, ce qui en fait un outil efficace pour créer des applications back-end efficaces et fiables. Son architecture modulaire fournit un modèle de conception structurel et mature au monde du développement de Node.js.

Vue.js est un framework JavaScript frontal pour la création d'interfaces utilisateur. Il possède une API simple, mais très puissante, ainsi que de grandes performances. Vue.js is capable of powering the front-end layer and logic of any web application irrespective of the size. La facilité d'intégration avec d'autres bibliothèques ou des projets existants en fait un choix parfait pour la plupart des applications Web modernes.

Dans ce didacticiel, vous construirez une application Nest.js pour vous familiariser avec ses blocs de construction ainsi que les principes fondamentaux de la création d’applications Web modernes. Vous aborderez ce projet en séparant l’application en deux sections différentes: l’interface et l’arrière-plan. Tout d’abord, vous allez vous concentrer sur l’API d’arrière-plan RESTful construite avec Nest.js. Vous vous concentrerez ensuite sur l’interface que vous construirez avec Vue.js. Les deux applications fonctionneront sur des ports différents et fonctionneront comme des domaines distincts.

Vous allez créer une application de blog avec laquelle les utilisateurs peuvent créer et enregistrer un nouveau message, afficher les messages sauvegardés sur la page d'accueil et exécuter d'autres processus tels que la modification et la suppression de messages. En outre, vous connecterez votre application et conserverez ses données avecMongoDB, qui est une base de données NoSQL sans schéma qui peut recevoir et stocker des documents JSON. Ce tutoriel se concentre sur la construction de votre application dans un environnement de développement. Pour un environnement de production, vous devez également envisager l'authentification de l'utilisateur pour votre application.

Conditions préalables

Pour compléter ce tutoriel, vous aurez besoin de:

  • Une installation locale deNode.js (au moins v6) etnpm (au moins v5.2). Node.js is a JavaScript run-time environment that allows you to run your code outside of the browser. Il est livré avec un gestionnaire de packages pré-installé appelénpm, qui vous permet d'installer et de mettre à jour des packages. Pour les installer sur macOS ou Ubuntu 18.04, suivez les étapes deHow to Install Node.js and Create a Local Development Environment on macOS ou de la section «Installation à l'aide d'un PPA» deHow To Install Node.js on Ubuntu 18.04.

  • MongoDB installé sur votre machine. Suivez les instructionshere pour le télécharger et l'installer selon le système d'exploitation de votre choix. Pour réussir l'installation de MongoDB, vous pouvez soit l'installer en utilisantHomebrew surMac, soit en le téléchargeant depuis leMongoDB website.

  • Une compréhension de base de TypeScript et deJavaScript.

  • Un éditeur de texte installé, tel queVisual Studio Code,Atom ouSublime Text.

[.note] #Note: Ce didacticiel utilise une machine macOS pour le développement. Si vous utilisez un autre système d'exploitation, vous devrez peut-être utilisersudo pour les commandesnpm tout au long du didacticiel.
#

[[step-1 -—- Installing-nest-js-and-other-dependencies]] == Étape 1 - Installation de Nest.js et d'autres dépendances

Dans cette section, vous allez commencer à utiliser Nest.js en installant l’application et ses dépendances requises sur votre ordinateur local. Vous pouvez facilement installer Nest.js en utilisant lesCLI fournis par Nest.js ou en installant le projet de démarrage à partir de GitHub. Pour les besoins de ce didacticiel, vous utiliserez la CLI pour configurer l’application. Pour commencer, exécutez la commande suivante à partir du terminal pour l’installer globalement sur votre ordinateur:

npm i -g @nestjs/cli

Vous verrez une sortie semblable à celle-ci:

Output@nestjs/[email protected]
added 220 packages from 163 contributors in 49.104s

Pour confirmer votre installation de l'interface de ligne de commande Nest, exécutez cette commande à partir de votre terminal:

nest --version

La sortie affiche la version actuelle installée sur votre ordinateur:

Output5.8.0

Vous utiliserez la commandenest pour gérer votre projet et l’utiliserez pour générer des fichiers pertinents, tels que le contrôleur, les modules et les fournisseurs.

Pour commencer le projet de ce didacticiel, utilisez la commandenest pour créer un nouveau projet Nest.js nomméblog-backend en exécutant la commande suivante à partir de votre terminal:

nest new blog-backend

Immédiatement après l'exécution de la commande,nest vous demandera de fournir des informations de base telles que lesdescription,version etauthor. Allez-y et fournissez les détails appropriés. Appuyez surENTER sur votre ordinateur pour continuer après avoir répondu à chaque invite.

Ensuite, vous choisirez un gestionnaire de paquets. Pour les besoins de ce didacticiel, sélectionneznpm et appuyez surENTER pour commencer l'installation de Nest.js.

Alt Creating a Nest project

Cela générera un nouveau projet Nest.js dans un dossierblog-backend de votre dossier de développement local.

Ensuite, accédez au dossier du nouveau projet à partir de votre terminal:

cd blog-backend

Exécutez la commande suivante pour installer d'autres dépendances de serveur:

npm install --save @nestjs/mongoose mongoose

Vous avez installé@nestjs/mongoose, qui est un package dédié Nest.js pour un outil de modélisation d’objet pour MongoDB, etmongoose, qui est un package pour Mongoose.

Vous allez maintenant lancer l’application à l’aide de la commande suivante:

npm run start

Maintenant, si vous accédez àhttp://localhost:3000 depuis votre navigateur préféré, vous verrez votre application en cours d'exécution.

Alt Welcome page of the fresh installation of Nest.js application

Vous avez généré le projet avec succès en exploitant la disponibilité de la commande Nest CLI. Ensuite, vous avez exécuté l'application et y avez accédé sur le port par défaut3000 sur votre machine locale. Dans la section suivante, vous allez pousser l’application plus loin en configurant la configuration de la connexion à la base de données.

[[step-2 -—- configuration-and-connection-with-the-database]] == Étape 2 - Configuration et connexion avec la base de données

Dans cette étape, vous allez configurer et intégrer MongoDB à votre application Nest.js. Vous utiliserez MongoDB pour stocker des données pour votre application. MongoDB stocke ses données dansdocuments sous forme de pairesfield : value. Pour accéder à cette structure de données, vous utiliserezMongoose, qui est une modélisation de document objet (ODM) qui vous permet de définir des schémas représentant les types de données stockées par une base de données MongoDB.

Pour démarrer MongoDB, ouvrez une fenêtre de terminal séparée afin que l'application puisse continuer à s'exécuter, puis exécutez la commande suivante:

sudo mongod

Cela démarrera le service MongoDB et exécutera la base de données en arrière-plan de votre ordinateur.

Ouvrez le projetblog-backend dans votre éditeur de texte et accédez à./src/app.module.ts. Vous pouvez configurer une connexion à la base de données en incluant lesMongooseModule installés dans lesApplicationModule racine. Pour ce faire, mettez à jour le contenu enapp.module.ts avec les lignes en surbrillance suivantes:

~/blog-backend/src/app.module.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [
    MongooseModule.forRoot('mongodb://localhost/nest-blog', { useNewUrlParser: true }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule { }

Dans ce fichier, vous utilisez la méthodeforRoot() pour fournir la connexion à la base de données. Enregistrez et fermez le fichier une fois l’édition terminée.

Avec cela en place, vous avez configuré la connexion à la base de données en utilisant le module Mongoose pour MongoDB. Dans la section suivante, vous allez créer un schéma de base de données à l'aide de la bibliothèque Mongoose, d'une interface TypeScript et d'un schéma d'objet de transfert de données (DTO).

[[step-3 -—- creation-a-database-schema-interfaces-and-dto]] == Étape 3 - Création d'un schéma de base de données, d'interfaces et d'un DTO

Dans cette étape, vous allez créer unschema,interface et undata transfer object pour votre base de données en utilisant Mongoose. Mongoose aide à gérer les relations entre les données et fournit une validation de schéma pour les types de données. Pour vous aider à définir la structure et le type de données des données dans la base de données de votre application, vous créerez des fichiers qui détermineront les éléments suivants:

  • database schema: il s'agit d'une organisation des données sous forme de modèle pour définir la structure et les types de données que la base de données doit stocker.

  • interfaces: les interfaces TypeScript sont utilisées pour la vérification de type. Il peut être utilisé pour définir les types de données à transmettre pour une application.

  • data transfer object: il s'agit d'un objet qui définit la manière dont les données seront envoyées sur le réseau et transportent les données entre les processus.

Pour commencer, retournez sur votre terminal où l'application est en cours d'exécution et arrêtez le processus avecCTRL + C, puis accédez au dossier./src/:

cd ./src/

Ensuite, créez un répertoire nomméblog, et un dossierschemas dans celui-ci:

mkdir -p blog/schemas

Dans le dossierschemas, créez un nouveau fichier appeléblog.schema.ts et ouvrez-le à l'aide de votre éditeur de texte. Ajoutez ensuite le contenu suivant:

~/blog-backend/src/blog/schemas/blog.schema.ts

import * as mongoose from 'mongoose';

export const BlogSchema = new mongoose.Schema({
    title: String,
    description: String,
    body: String,
    author: String,
    date_posted: String
})

Ici, vous avez utilisé Mongoose pour définir le type de données que vous allez stocker dans la base de données. Vous avez indiqué que tous les champs seront stockés et n'accepteront que des valeurs de chaîne. Enregistrez et fermez le fichier une fois l’édition terminée.

Maintenant, avec le schéma de base de données déterminé, vous pouvez passer à la création des interfaces.

Pour commencer, revenez dans le dossierblog:

cd ~/blog-backend/src/blog/

Créez un nouveau dossier nomméinterfaces et accédez-y:

mkdir interfaces

Dans le dossierinterfaces, créez un nouveau fichier appelépost.interface.ts et ouvrez-le à l'aide de votre éditeur de texte. Ajoutez le contenu suivant pour définir les types de données pour unPost:

~/blog-backend/src/blog/interfaces/post.interface.ts

import { Document } from 'mongoose';

export interface Post extends Document {
    readonly title: string;
    readonly description: string;
    readonly body: string;
    readonly author: string;
    readonly date_posted: string
}

Dans ce fichier, vous avez correctement défini les types de données pour un typePost en tant que valeurs de chaîne. Enregistrez et quittez le fichier.

Etant donné que votre application exécutera la fonctionnalité d’enregistrement de données dans la base de données, vous créerez un objet de transfert de données qui définira le mode d’envoi des données sur le réseau.

Pour ce faire, créez un dossierdto dans le dossier./src/blog. Dans le dossier nouvellement créé, créez un autre fichier nommécreate-post.dto.ts

Revenez dans le dossierblog:

cd ~/blog-backend/src/blog/

Créez ensuite un dossier nommédto et déplacez-vous dedans:

mkdir dto

Dans le dossierdto, créez un nouveau fichier appelécreate-post.dto.ts et ouvrez-le à l'aide de votre éditeur de texte pour ajouter le contenu suivant:

~/blog-backend/src/blog/dto/create-post.dto.ts

export class CreatePostDTO {
    readonly title: string;
    readonly description: string;
    readonly body: string;
    readonly author: string;
    readonly date_posted: string
}

Vous avez marqué chacune des propriétés individuelles de la classeCreatePostDTO comme ayant le type de donnéesstring et commereadonly pour éviter une mutation inutile. Enregistrez et quittez le fichier une fois l’édition terminée.

Au cours de cette étape, vous avez créé un schéma de base de données pour la base de données, une interface et un objet de transfert de données pour les données que votre base de données stockera. Ensuite, vous allez générer un module, un contrôleur et un service pour votre blog.

[[step-4 -—- creation-the-module-controller-and-service-for-the-blog]] == Étape 4 - Création du module, du contrôleur et du service pour le blog

Dans cette étape, vous allez améliorer la structure existante de l’application en créant un module pour votre blog. Ce module organisera la structure de fichier de votre application. Ensuite, vous allez créer un contrôleur pour gérer les itinéraires et traiter les demandes HTTP du client. Pour conclure, vous allez configurer un service qui traitera toute la logique métier trop complexe pour que le contrôleur de l’application puisse la traiter.

Générer un module

À l'instar du framework Web frontal angulaire, Nest.js utilise une syntaxe modulaire. Nest.js applications have a modular design; it comes installed with a single root module, which is often sufficient for a small application. Cependant, lorsqu'une application commence à se développer, Nest.js recommande une organisation à plusieurs modules, scindant le code en fonctionnalités connexes.

Unmodule dans Nest.js est identifié par le décorateur@Module() et prend un objet avec des propriétés telles quecontrollers etproviders. Chacune de ces propriétés prend un tableau decontrollers etproviders respectivement.

Vous allez générer un nouveau module pour cette application de blog afin de mieux organiser la structure. Pour commencer, toujours dans le dossier~/blog-backend, exécutez la commande suivante:

nest generate module blog

Vous verrez une sortie semblable à celle-ci:

OutputCREATE /src/blog/blog.module.ts

UPDATE /src/app.module.ts

La commande a généré un nouveau module nomméblog.module.ts pour l'application et a importé le module nouvellement créé dans le module racine de l'application. Cela permettra à Nest.js de connaître un autre module en plus du module racine.

Dans ce fichier, vous verrez le code suivant:

~/blog-backend/src/blog/blog.module.ts

import { Module } from '@nestjs/common';

@Module({})
export class BlogModule {}

Vous mettrez à jour ceBlogModule avec les propriétés requises plus tard dans le didacticiel. Enregistrez et quittez le fichier.

Générer un service

Unservice, qui peut également être appelé un fournisseur dans Nest.js, a été conçu pour supprimer la logique des contrôleurs, qui sont destinés à traiter uniquement les requêtes HTTP et à rediriger les tâches plus complexes vers les services. Les services sont des classes JavaScript simples avec un décorateur@Injectable() au dessus. Pour générer un nouveau service, exécutez la commande suivante à partir du terminal tant que vous vous trouvez dans le répertoire du projet:

nest generate service blog

Vous verrez une sortie semblable à celle-ci:

Output  CREATE /src/blog/blog.service.spec.ts (445 bytes)

CREATE /src/blog/blog.service.ts (88 bytes)

UPDATE /src/blog/blog.module.ts (529 bytes)

La commandenest utilisée ici a créé un fichierblog.service.spec.ts, que vous pouvez utiliser pour les tests. Il a également créé un nouveau fichierblog.service.ts, qui contiendra toute la logique de cette application et gérera l'ajout et la récupération de documents dans la base de données MongoDB. En outre, il a automatiquement importé le service nouvellement créé et ajouté à blog.module.ts.

Le service gère toute la logique de l'application, est responsable de l'interaction avec la base de données et renvoie les réponses appropriées au contrôleur. Pour ce faire, ouvrez le fichierblog.service.ts dans votre éditeur de texte et remplacez le contenu par ce qui suit:

~/blog-backend/src/blog/blog.service.ts

import { Injectable } from '@nestjs/common';
import { Model } from 'mongoose';
import { InjectModel } from '@nestjs/mongoose';
import { Post } from './interfaces/post.interface';
import { CreatePostDTO } from './dto/create-post.dto';

@Injectable()
export class BlogService {

    constructor(@InjectModel('Post') private readonly postModel: Model) { }

    async getPosts(): Promise {
        const posts = await this.postModel.find().exec();
        return posts;
    }

    async getPost(postID): Promise {
        const post = await this.postModel
            .findById(postID)
            .exec();
        return post;
    }

    async addPost(createPostDTO: CreatePostDTO): Promise {
        const newPost = await this.postModel(createPostDTO);
        return newPost.save();
    }

    async editPost(postID, createPostDTO: CreatePostDTO): Promise {
        const editedPost = await this.postModel
            .findByIdAndUpdate(postID, createPostDTO, { new: true });
        return editedPost;
    }

    async deletePost(postID): Promise {
        const deletedPost = await this.postModel
            .findByIdAndRemove(postID);
        return deletedPost;
    }

}

Dans ce fichier, vous avez d'abord importé le module requis depuis@nestjs/common,mongoose et@nestjs/mongoose. Vous avez également importé une interface nomméePost et un objet de transfert de donnéesCreatePostDTO.

Dans lesconstructor, vous avez ajouté@InjectModel('Post'), qui injectera le modèlePost dans cette classeBlogService. Vous pourrez désormais utiliser ce modèle injecté pour extraire toutes les publications, extraire une publication unique et effectuer d'autres activités liées à la base de données.

Ensuite, vous avez créé les méthodes suivantes:

  • getPosts(): pour récupérer toutes les publications de la base de données.

  • getPost(): pour récupérer un seul article de la base de données.

  • addPost(): pour ajouter un nouveau message.

  • editPost(): pour mettre à jour un seul post.

  • deletePost(): pour supprimer un article particulier.

Enregistrez et quittez le fichier lorsque vous avez terminé.

Vous avez terminé la configuration et la création de plusieurs méthodes qui gèrent l’interaction correcte avec la base de données MongoDB à partir de l’API d’arrière-plan. Vous allez maintenant créer les itinéraires requis pour gérer les appels HTTP à partir d'un client frontal.

Générer un contrôleur

Au nid. js,controllers sont responsables du traitement de toutes les demandes entrantes du côté client d'une application et du renvoi de la réponse appropriée. Comme pour la plupart des autres infrastructures Web, il est important que l'application écoute une demande et y réponde.

Pour répondre à toutes les requêtes HTTP de votre application de blog, vous utiliserez la commandenest pour générer un nouveau fichier contrôleur. Assurez-vous que vous êtes toujours dans le répertoire du projet,blog-backend, et exécutez la commande suivante:

nest generate controller blog

Vous verrez une sortie similaire à:

OutputCREATE /src/blog/blog.controller.spec.ts (474 bytes)

CREATE /src/blog/blog.controller.ts (97 bytes)

UPDATE /src/blog/blog.module.ts (483 bytes)

La sortie indique que cette commande a créé deux nouveaux fichiers dans le répertoiresrc/blog. Ce sontblog.controller.spec.ts etblog.controller.ts. Le premier est un fichier que vous pouvez utiliser pour écrire des tests automatisés pour le contrôleur nouvellement créé. Ce dernier est le fichier du contrôleur lui-même. Les contrôleurs de Nest.js sont des fichiers TypeScript décorés avec les métadonnées@Controller. La commande a également importé le contrôleur nouvellement créé et ajouté au module de blog.

Ensuite, ouvrez le fichierblog.controller.ts avec votre éditeur de texte et mettez-le à jour avec le contenu suivant:

~/blog-backend/src/blog/blog.controller.ts

import { Controller, Get, Res, HttpStatus, Param, NotFoundException, Post, Body, Query, Put, Delete } from '@nestjs/common';
import { BlogService } from './blog.service';
import { CreatePostDTO } from './dto/create-post.dto';
import { ValidateObjectId } from '../shared/pipes/validate-object-id.pipes';


@Controller('blog')
export class BlogController {

    constructor(private blogService: BlogService) { }

    @Get('posts')
    async getPosts(@Res() res) {
        const posts = await this.blogService.getPosts();
        return res.status(HttpStatus.OK).json(posts);
    }

    @Get('post/:postID')
    async getPost(@Res() res, @Param('postID', new ValidateObjectId()) postID) {
        const post = await this.blogService.getPost(postID);
        if (!post) throw new NotFoundException('Post does not exist!');
        return res.status(HttpStatus.OK).json(post);

    }

    @Post('/post')
    async addPost(@Res() res, @Body() createPostDTO: CreatePostDTO) {
        const newPost = await this.blogService.addPost(createPostDTO);
        return res.status(HttpStatus.OK).json({
            message: "Post has been submitted successfully!",
            post: newPost
        })
    }
}

Dans ce fichier, vous avez d'abord importé les modules nécessaires pour gérer les requêtes HTTP du module@nestjs/common. Ensuite, vous avez importé trois nouveaux modules qui sont:BlogService,CreatePostDTO etValidateObjectId. Après cela, vous avez injecté lesBlogService dans le contrôleur via un constructeur afin d'obtenir l'accès et d'utiliser les fonctions déjà définies dans le fichierBlogService. Il s'agit d'un modèle considéré commedependency injection utilisé dans Nest.js pour augmenter l'efficacité et améliorer la modularité de l'application.

Enfin, vous avez créé les méthodes asynchrones suivantes:

  • getPosts(): Cette méthode exécutera la fonctionnalité de réception d'une requête HTTP GET du client pour récupérer toutes les publications de la base de données, puis retournera la réponse appropriée. Il est décoré d'un@Get('posts').

  • getPost(): Cela prend unpostID comme paramètre et récupère un seul article de la base de données. En plus du paramètrepostID passé à cette méthode, vous avez réalisé l'ajout d'une méthode supplémentaire nomméeValidateObjectId(). Cette méthode implémente l'interfacePipeTransform de Nest.js. Son but est de valider et de s'assurer que le paramètrepostID peut être trouvé dans la base de données. Vous allez définir cette méthode dans la section suivante.

  • addPost(): Cette méthode gérera une requête HTTP POST pour ajouter une nouvelle publication à la base de données.

Pour pouvoir modifier et supprimer un article en particulier, vous devrez ajouter deux méthodes supplémentaires au fichierblog.controller.ts. Pour ce faire, incluez les méthodeseditPost() etdeletePost() suivantes directement après la méthodeaddPost() que vous avez précédemment ajoutée àblog.controller.ts:

~/blog-backend/src/blog/blog.controller.ts

...
@Controller('blog')
export class BlogController {
    ...
    @Put('/edit')
    async editPost(
        @Res() res,
        @Query('postID', new ValidateObjectId()) postID,
        @Body() createPostDTO: CreatePostDTO
    ) {
        const editedPost = await this.blogService.editPost(postID, createPostDTO);
        if (!editedPost) throw new NotFoundException('Post does not exist!');
        return res.status(HttpStatus.OK).json({
            message: 'Post has been successfully updated',
            post: editedPost
        })
    }


    @Delete('/delete')
    async deletePost(@Res() res, @Query('postID', new ValidateObjectId()) postID) {
        const deletedPost = await this.blogService.deletePost(postID);
        if (!deletedPost) throw new NotFoundException('Post does not exist!');
        return res.status(HttpStatus.OK).json({
            message: 'Post has been deleted!',
            post: deletedPost
        })
    }
}

Ici vous avez ajouté:

  • editPost(): Cette méthode accepte un paramètre de requête depostID et effectuera la fonctionnalité de mise à jour d'un seul post. Il a également utilisé la méthodeValidateObjectId pour fournir une validation appropriée pour le message que vous devez modifier.

  • deletePost(): Cette méthode acceptera un paramètre de requête depostID et supprimera une publication particulière de la base de données.

Comme pour lesBlogController, chacune des méthodes asynchrones que vous avez définies ici a un décorateur de métadonnées et prend un préfixe que Nest.js utilise comme mécanisme de routage. Il contrôle quel contrôleur reçoit quelles requêtes et pointe vers les méthodes qui doivent traiter la requête et renvoyer une réponse, respectivement.

Par exemple, leBlogController que vous avez créé dans cette section a un préfixe deblog et une méthode nomméegetPosts() qui prend un préfixe deposts. Cela signifie que toute requête GET envoyée à un point final deblog/posts (http:localhost:3000/blog/posts) sera traitée par la méthode `getPosts ()`. Cet exemple est similaire à celui utilisé par d'autres méthodes pour gérer les demandes HTTP.

Enregistrez et quittez le fichier.

Pour obtenir le fichierblog.controller.ts complet, visitez lesDO Community repository de cette application.

Dans cette section, vous avez créé un module pour que l'application soit mieux organisée. Vous avez également créé un service pour gérer la logique applicative de l'application en interagissant avec la base de données et en renvoyant la réponse appropriée. Enfin, vous avez généré un contrôleur et créé les méthodes requises pour gérer les requêtes HTTP telles queGET,POST,PUT etDELETE côté client. Dans l’étape suivante, vous allez terminer la configuration de votre back-end.

[[step-5 -—- creation-an-extra-validation-for-mongoose]] == Étape 5 - Création d'une validation supplémentaire pour Mongoose

Vous pouvez identifier chaque article de votre application de blog par un identifiant unique, également appeléPostID. Cela signifie que pour aller chercher un article, vous devrez passer cet ID en tant que paramètre de requête. Pour valider ce paramètrepostID et vous assurer que la publication est disponible dans la base de données, vous devez créer une fonction réutilisable qui peut être initialisée à partir de n'importe quelle méthode dans lesBlogController.

Pour configurer cela, accédez au dossier./src/blog:

cd ./src/blog/

Ensuite, créez un nouveau dossier nomméshared:

mkdir -p shared/pipes

Dans le dossierpipes, à l'aide de votre éditeur de texte, créez un nouveau fichier appelévalidate-object-id.pipes.ts et ouvrez-le. Ajoutez le contenu suivant pour définir les donnéespostID acceptées:

~/blog-backend/src/blog/shared/pipes/validate-object-id.pipes.ts

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';
import * as mongoose from 'mongoose';

@Injectable()
export class ValidateObjectId implements PipeTransform {
    async transform(value: string, metadata: ArgumentMetadata) {
        const isValid = mongoose.Types.ObjectId.isValid(value);
        if (!isValid) throw new BadRequestException('Invalid ID!');
        return value;
    }
}

La classeValidateObjectId() implémente la méthodePipeTransform du module@nestjs/common. Il a une seule méthode nomméetransform() qui prend en valeur comme paramètre -postID dans ce cas. Avec la méthode ci-dessus, toute requête HTTP du frontend de cette application avec unpostID qui ne peut pas être trouvé dans la base de données sera considérée comme invalide. Enregistrez et fermez le fichier.

Après avoir créé à la fois le service et le contrôleur, vous devez configurer le modèlePost basé sur lesBlogSchema. Cette configuration peut être configurée dans la racineApplicationModule, mais dans ce cas, la construction du modèle dansBlogModule maintiendra l'organisation de votre application. Ouvrez le./src/blog/blog.module.ts et mettez-le à jour avec les lignes en surbrillance suivantes:

~/blog-backend/src/blog/blog.module.ts

import { Module } from '@nestjs/common';
import { BlogController } from './blog.controller';
import { BlogService } from './blog.service';
import { MongooseModule } from '@nestjs/mongoose';
import { BlogSchema } from './schemas/blog.schema';

@Module({
  imports: [
    MongooseModule.forFeature([{ name: 'Post', schema: BlogSchema }])
 ],
  controllers: [BlogController],
  providers: [BlogService]
})
export class BlogModule { }

Ce module utilise la méthodeMongooseModule.forFeature() pour définir les modèles à enregistrer dans le module. Sans cela, injecter lesPostModel dans lesBlogService à l'aide du décorateur@injectModel() ne fonctionnerait pas. Enregistrez et fermez le fichier lorsque vous avez fini d'ajouter le contenu.

Au cours de cette étape, vous avez créé l’API d’arrière-plan complète RESTful avec Nest.js et l’avez intégrée à MongoDB. Dans la section suivante, vous allez configurer le serveur pour autoriser les requêtes HTTP provenant d’un autre serveur, car votre application frontale s’exécutera sur un autre port.

[[step-6 -—- enabled-cors]] == Étape 6 - Activation de CORS

Une demande HTTP d'un domaine à un autre est souvent bloquée par défaut, sauf si le serveur le permet. Pour que votre application frontale fasse une demande au serveur principal, vous devez activerCross-origin resource sharing (CORS), qui est une technique qui autorise les demandes de ressources restreintes sur une page Web.

Dans Nest.js pour activer CORS, vous devez ajouter une seule méthode à votre fichiermain.ts. Ouvrez ce fichier dans votre éditeur de texte, situé à./src/main.ts, et mettez-le à jour avec le contenu en surbrillance suivant:

~/blog-backend/src/main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.enableCors();
  await app.listen(3000);
}
bootstrap();

Enregistrez et quittez le fichier.

Maintenant que vous avez terminé la configuration du back-end, vous allez vous focaliser sur le front-end et utilisez Vue.js pour utiliser les API construites jusqu'à présent.

[[step-7 -—- creation-the-vue-js-frontend]] == Étape 7 - Création du frontend Vue.js

Dans cette section, vous allez créer votre application frontale avec Vue.js. Vue CLI est un outil standard qui vous permet de générer et d'installer rapidement un nouveau projet Vue.js sans trop de tracas.

Pour commencer, vous devez d'abord installer Vue CLI globalement sur votre ordinateur. Ouvrez un autre terminal et au lieu de travailler à partir du dossierblog-backend, accédez au dossier de développement de votre projet local et exécutez:

npm install -g @vue/cli

Une fois le processus d'installation terminé, vous utiliserez la commandevue pour créer un nouveau projet Vue.js:

vue create blog-frontend

Une courte invite apparaît après que vous avez entré cette commande. Choisissez l'optionmanually select features, puis sélectionnez les fonctionnalités dont vous aurez besoin pour ce projet en appuyant surSPACE sur votre ordinateur pour mettre en évidence plusieurs fonctionnalités. Vous sélectionnerezBabel,Router etLinter / Formatter.

Alt Vue project CLI set up

Pour les instructions suivantes, tapezy pour utiliser le mode historique pour un routeur; cela garantira que le mode historique est activé dans le fichier du routeur, qui sera automatiquement généré pour ce projet. De plus, sélectionnezESLint with error prevention only pour choisir une configuration linter / formatter. Ensuite, sélectionnezLint on save pour des fonctionnalités supplémentaires Lint. Ensuite, sélectionnez pour enregistrer votre configuration dans undedicated config file pour de futurs projets. Tapez un nom pour votre préréglage, commevueconfig.

Alt Vue.js final CLI set up

Vue.js will then start creating the application and all its required dependencies in a directory named blog-frontend.

Une fois le processus d'installation terminé, naviguez dans l'application Vue.js:

cd blog-frontend

Ensuite, démarrez le serveur de développement avec:

npm run serve

Votre application fonctionnera surhttp://localhost:8080.

Alt Vue.js home view

Étant donné que vous exécuterez des requêtes HTTP dans cette application, vous devrez installer Axios, un client HTTP basé sur des promesses pour le navigateur. Ici, vous utiliserez Axios pour exécuter des requêtes HTTP à partir des différents composants de l’application. Arrêtez l'application frontale en appuyant surCTRL + C depuis le terminal de votre ordinateur, puis exécutez la commande suivante:

npm install axios --save

Votre application frontale effectuera un appel d'API à l'API back-end sur un domaine particulier à partir de différents composants de l'application. Afin de garantir une structure appropriée pour cette application, vous pouvez créer un fichierhelper et définir le serveurbaseURL.

Pour commencer, depuis votre terminal toujours à l'intérieur deblog-frontend, naviguez jusqu'au dossier./src/:

cd ./src/

Créez un autre dossier nomméutils:

mkdir utils

Dans le dossierutils, à l'aide de votre éditeur de texte, créez un nouveau fichier appeléhelper.js et ouvrez-le. Ajoutez le contenu suivant pour définir lesbaseURL pour le projet principal Nest.js:

~blog-frontend/src/utils/helper.js

export const server = {

baseURL: 'http://localhost:3000'

}

En définissant unbaseURL, vous pourrez l'appeler de n'importe où dans vos fichiers de composants Vue.js. Si vous devez modifier l'URL, il sera plus facile de mettre à jour lesbaseURL dans ce fichier plutôt que dans votre application.

Dans cette section, vous avez installé Vue CLI, un outil permettant de créer une nouvelle application Vue.js. Vous avez utilisé cet outil pour créer l'applicationblog-frontend. De plus, vous avez exécuté l'application et installé une bibliothèque appelée Axios, que vous utiliserez chaque fois qu'il y a un appel HTTP dans l'application. Ensuite, vous allez créer des composants pour l'application.

[[step-8 -—- creating-reusable-components]] == Étape 8 - Création de composants réutilisables

Vous allez maintenant créer des composants réutilisables pour votre application, qui constituent la structure standard des applications Vue.js. Le système de composants de Vue.js permet aux développeurs de créer une seule unité indépendante d'une interface pouvant avoir son propre état, son propre marquage et son propre style. Cela rend approprié que les composants de Vue.js soient réutilisables.

Chaque composant Vue.js contient trois sections différentes:

  • <template>: contient le contenu HTML

  • <script>: contient toute la logique frontale de base et définit les fonctions

  • <style>: la feuille de style pour chaque composant séparé

Tout d’abord, vous allez commencer par créer un composant pour créer une nouvelle publication. Pour ce faire, créez un nouveau dossier nommépost dans le dossier./src/components, qui hébergera les composants réutilisables nécessaires pour les publications. Puis en utilisant votre éditeur de texte, dans le dossierpost nouvellement créé, créez un autre fichier et nommez-leCreate.vue. Ouvrez le nouveau fichier et ajoutez le code suivant, qui contient les champs de saisie nécessaires pour soumettre un message:

~blog-frontend/src/components/post/Create.vue

Il s'agit de la section<template> du composantCreatePost. Il contient les éléments d’entrée HTML nécessaires à la création d’une nouvelle publication. Chacun des champs d'entrée a une directivev-model comme attribut d'entrée. Cela permet d’assurer des liaisons de données bidirectionnelles sur chaque entrée de formulaire afin de permettre à Vue.js d’obtenir la saisie de l’utilisateur.

Ensuite, ajoutez la section<script> au même fichier directement après le contenu précédent:

~blog-frontend/src/components/post/Create.vue

...

Ici, vous avez ajouté une méthode nomméecreatePost() pour créer une nouvelle publication et la soumettre au serveur à l'aide d'Axios. Une fois qu'un utilisateur crée un nouveau message, l'application sera redirigée vers la page d'accueil où les utilisateurs peuvent afficher la liste des messages créés.

Vous allez configurer vue-router pour implémenter la redirection ultérieurement dans ce tutoriel.

Enregistrez et fermez le fichier une fois l’édition terminée. Pour obtenir le fichierCreate.vue complet, visitez lesDO Community repository de cette application.

Maintenant, vous devez créer un autre composant pour éditer un article particulier. Accédez au dossier./src/components/post et créez un autre fichier et nommez-leEdit.vue. Ajoutez-y le code suivant qui contient la section<template>:

~blog-frontend/src/components/post/Edit.vue

Cette section de modèle contient un contenu similaire à celui du composantCreatePost(); la seule différence est qu'il contient les détails de l'article particulier qui doit être modifié.

Ensuite, ajoutez la section`

Ici, vous avez obtenu le paramètre d'itinéraireid pour identifier une publication particulière. Vous avez ensuite créé une méthode nomméegetPost() pour récupérer les détails de cette publication à partir de la base de données et mis à jour la page avec elle. Enfin, vous avez créé une méthodeeditPost() pour renvoyer la publication modifiée au serveur principal avec une requête HTTP PUT.

Enregistrez et quittez le fichier. Pour obtenir le fichierEdit.vue complet, visitez lesDO Community repository de cette application.

Maintenant, vous allez créer un nouveau composant dans le dossier./src/components/post et le nommerPost.vue. Cela vous permettra d'afficher les détails d'une publication particulière à partir de la page d'accueil. Ajoutez le contenu suivant àPost.vue:

~blog-frontend/src/components/post/Post.vue

Ce code rend les détails d'une publication qui comprend,title,author et la publicationbody.

Maintenant, juste après</template>, ajoutez le code suivant au fichier:

~blog-frontend/src/components/post/Post.vue

...

Semblable à la section<script> du composant d'édition de publication, vous avez obtenu le paramètre d'itinéraireid et l'avez utilisé pour récupérer les détails d'une publication particulière.

Enregistrez et fermez le fichier lorsque vous avez terminé d'ajouter le contenu. Pour obtenir le fichierPost.vue complet, visitez lesDO Community repository de cette application.

Ensuite, pour afficher toutes les publications créées pour les utilisateurs, vous allez créer un nouveau composant. Si vous accédez au dossierviews danssrc/views, vous verrez un composantHome.vue - si ce fichier n'est pas présent, utilisez votre éditeur de texte pour le créer, ajoutez le code suivant:

~blog-frontend/src/views/Home.vue

Ici, dans la section<template>, vous avez utilisé les<router-link> pour créer un lien pour l'édition ainsi que pour afficher un message en passant lespost._id comme paramètre de requête. Vous avez également utilisé la directivev-if pour rendre conditionnellement le message aux utilisateurs. S'il n'y a pas de publication de la base de données, un utilisateur ne verra que ce texte:No post found at the moment.

Enregistrez et quittez le fichier. Pour obtenir le fichierHome.vue complet, visitez lesDO Community repository de cette application.

Maintenant, juste après la section</template> dansHome.vue, ajoutez la section</script> suivante:

~blog-frontend/src/views/Home.vue

...

Dans la section<script> de ce fichier, vous avez créé une méthode nomméefetchPosts() pour récupérer toutes les publications de la base de données et vous avez mis à jour la page avec les données renvoyées par le serveur.

Vous allez maintenant mettre à jour le composantApp de l’application frontale afin de créer des liens vers les composantsHome etCreate. Ouvrezsrc/App.vue et mettez-le à jour avec les éléments suivants:

~blog-frontend/src/App.vue



En plus d'inclure les liens vers les composantsHome etCreate, vous avez également inclus la section<Style>, qui est la feuille de style de ce composant et contient la définition des styles pour certains des éléments sur la page. Enregistrez et quittez le fichier.

Vous avez créé tous les composants requis pour votre application à cette étape. Ensuite, vous allez configurer le fichier du routeur.

[[step-9 -—- setting-up-routing]] == Étape 9 - Configuration du routage

Après avoir créé tous les composants réutilisables nécessaires, vous pouvez maintenant configurer correctement le fichier du routeur en mettant à jour son contenu avec des liens vers tous les composants que vous avez créés. Cela garantira que tous les points de terminaison de l'application frontale sont mappés sur un composant particulier pour une action appropriée. Accédez à./src/router.js et remplacez son contenu par ce qui suit:

~blog-frontend/src/router.js

import Vue from 'vue'
import Router from 'vue-router'
import HomeComponent from '@/views/Home';
import EditComponent from '@/components/post/Edit';
import CreateComponent from '@/components/post/Create';
import PostComponent from '@/components/post/Post';

Vue.use(Router)

export default new Router({
  mode: 'history',
  routes: [
    { path: '/', redirect: { name: 'home' } },
    { path: '/home', name: 'home', component: HomeComponent },
    { path: '/create', name: 'Create', component: CreateComponent },
    { path: '/edit/:id', name: 'Edit', component: EditComponent },
    { path: '/post/:id', name: 'Post', component: PostComponent }
  ]
});

Vous avez importéRouter du modulevue-router et l'instancié en passant les paramètresmode etroutes. Le mode par défaut pourvue-router est un mode de hachage, qui utilise le hachage d'URL pour simuler une URL complète afin que la page ne soit pas rechargée lorsque l'URL change. Afin de rendre le hachage inutile, vous avez utilisé le mode historique pour effectuer une navigation URL sans rechargement de page. Enfin, dans l'optionroutes, vous avez spécifié le chemin du noeud final - un nom pour la route et le composant qui doit être rendu lorsque la route est appelée dans l'application. Enregistrez et quittez le fichier.

Maintenant que vous avez configuré le routage vers l'application, vous devez inclure le fichier Bootstrap pour vous aider à créer un style prédéfini pour l'interface utilisateur de l'application. Pour ce faire, ouvrez le fichier./public/index.html dans votre éditeur de texte et incluez le fichier CDN pour Bootstrap en ajoutant le contenu suivant au fichier:

~blog-frontend/public/index.html




  ...
  
  blog-frontend


   ...

Enregistrez et quittez le fichier, puis redémarrez l'application avecnpm run serve pour vosblog-frontend, si elle n'est pas en cours d'exécution.

[.note] #Note: Assurez-vous que le serveur principal et l'instance MongoDB sont également en cours d'exécution. Sinon, accédez auxblog-backend depuis un autre terminal et exécuteznpm run start. Démarrez également le service MongoDB en exécutantsudo mongod à partir d'un nouveau terminal.
#

Accédez à votre application à l'adresse:http://localhost:8080. Vous pouvez maintenant tester votre blog en créant et en modifiant des messages.

Alt Create a new post

Cliquez surCreate sur votre application pour voir l'écranCreate Post, qui se rapporte au fichierCreateComponent et le rend. Entrez les valeurs dans les champs de saisie et cliquez sur le boutonCreate Post pour soumettre un message. Une fois que vous avez terminé, l'application vous redirigera vers la page d'accueil.

La page d'accueil de l'application rend lesHomeComponent. Ce composant a une méthode qui envoie un appel HTTP pour extraire toutes les publications de la base de données et les affiche aux utilisateurs.

Alt View all posts from the database

En cliquant sur le boutonEdit Post pour un article particulier, vous serez redirigé vers une page d'édition où vous pourrez incorporer les modifications et enregistrer votre article.

Alt Edit a new post

Dans cette section, vous avez configuré et configuré le routage pour l'application. Avec cela en place, votre application de blog est prête.

Conclusion

Dans ce tutoriel, vous avez exploré une nouvelle façon de structurer une application Node.js à l'aide de Nest.js. Vous avez créé une application de blog simple à l'aide de Nest.js pour créer l'API RESTful principale et avez utilisé Vue.js pour gérer toute la logique frontale. De plus, vous avez également intégré MongoDB en tant que base de données pour votre application Nest.js.

Pour en savoir plus sur l'ajout de l'authentification à votre application, vous pouvez utiliserPassport.js, une bibliothèque d'authentification Node.js populaire. Vous pouvez en savoir plus sur l'intégration de Passport.js dans lesNest.js documentation.

Vous pouvez trouver le code source complet de ce projethere on GitHub. Pour plus d'informations sur Nest.js, vous pouvez visiter le siteofficial documentation.