- Оригинальный адрес:How To Build a Blog with Nest.js, MongoDB, and Vue.js
- Оригинальный автор:Oluyemi Olususi
- Перевод с:Программа перевода самородков
- Постоянная ссылка на эту статью:GitHub.com/rare earth/gold-no…
- Переводчик:Jessica
- Корректор:vitoxli,lihaobhsfer
Как создать блог с помощью Nest.js, MongoDB и Vue.js
Обзор
Nest.js— это расширяемый серверный JavaScript-фреймворк. Он построен с использованием TypeScript, поэтому он по-прежнему совместим с JavaScript, что делает его эффективным инструментом для создания эффективных и надежных серверных приложений. Он также имеет модульную структуру, которая обеспечивает зрелый структурированный шаблон проектирования для среды разработки Node.js.
Vue.js— это интерфейсный JavaScript-фреймворк для создания пользовательских интерфейсов. У него не только простой, но мощный API, но и отличная производительность. Vue.js может предоставить внешний слой и логику любого веб-приложения масштаба проекта. Он может легко интегрироваться с другими библиотеками или существующими проектами, что делает его идеальным для большинства современных веб-приложений.
В этом руководстве мы познакомимся с его строительными блоками и основными принципами создания современного веб-приложения путем создания приложения Nest.js. Мы разделим приложение на две отдельные части: интерфейс и серверную часть. Во-первых, мы будем использовать Nest.js для создания серверного API RESTful. Затем Vue.js будет использоваться для создания внешнего интерфейса. Внешние и внутренние приложения будут работать на разных портах и будут работать как отдельные домены.
Мы создадим приложение для ведения блога, которое пользователи смогут использовать для создания и сохранения новых статей, просмотра сохраненных статей на домашней странице и других действий, таких как редактирование и удаление статей. Кроме того, мы подключаем приложение и сохраняем данные приложения вMongoDBMongoDB — это база данных NoSQL без схемы, которая может получать и хранить файлы JSON. Основное внимание в этом руководстве уделяется тому, как создать приложение в среде разработки. Если это в производственной среде, мы также должны учитывать аутентификацию пользователя приложения.
помещение
Для выполнения этого урока нам понадобится:
- Установить локальноNode.js(по крайней мере версия v6) иnpm(по крайней мере версия v5.2). Node.js — это среда выполнения, которая позволяет запускать код JavaScript вне браузера. Он поставляется с
npm
Предустановленный инструмент управления пакетами, позволяющий устанавливать и обновлять пакеты. Следуйте статье, если хотите установить их на macOS или Ubuntu 18.04.Как установить Node.js на macOS и создать локальную среду разработкишаги или статьи вКак установить Node.js на Ubuntu 18.04Раздел «Установка с помощью PPA» в . - Установите базу данных MongoDB на свой компьютер. согласно сздесьинструкции по загрузке и установке версии для вашей операционной системы. Вы можете сделать это,Macиспользовать наHomebrewдля установки или изВеб-сайт MongoDBскачать.
- для TypeScript иJavaScriptИметь базовое понимание.
- Установите текстовый редактор, напримерVisual Studio Code,AtomилиSublime Text.
Уведомление:В этом руководстве для разработки используется компьютер с macOS. Если вы используете другую операционную систему, вам может понадобиться использоватьsudo
выполнитьnpm
Заказ.
Шаг 1. Установите Nest.js и другие зависимости
В этом разделе мы сначала устанавливаем Nest.js и его необходимые зависимости локально. Вы можете использоватьCLIЛегко установите Nest.js или из стартового проекта на GitHub. В этом руководстве мы будем использовать CLI для инициализации приложения. Сначала выполните следующую команду в Терминале, чтобы установить ее глобально на свой компьютер:
npm i -g @nestjs/cli
Вы увидите вывод, подобный следующему:
Output@nestjs/cli@5.8.0
added 220 packages from 163 contributors in 49.104s
Чтобы подтвердить, что установка Nest CLI завершена, запустите эту команду на терминале:
nest --version
Вы увидите версию Nest, установленную на вашем компьютере:
Output5.8.0
мы будем использоватьnest
команды для управления проектом и использования его для создания связанных файлов, таких как контроллеры, модули и поставщики.
Чтобы запустить проект для этого руководства, в терминале используйтеnest
команда для запуска следующей командной строки для создания файла с именемblog-backend
Новый проект Nest.js для:
nest new blog-backend
После запуска этой командыnest
немедленно предоставит вам некоторую основную информацию, такую как描述(description)
,版本(version)
а также作者(author)
. Идите вперед и предоставьте соответствующие детали. После того, как вы ответили на каждое приглашение, на вашем компьютере нажмите回车
Продолжать.
Далее мы выберем менеджер пакетов. Для этого руководства выберитеnpm
и нажмите回车键
Начните установку Nest.js.
Это будет в локальной папке разработки по адресуblog-backend
В папке создается новый проект Nest.js.
Затем перейдите в новую папку проекта из терминала:
cd blog-backend
Выполните следующие команды, чтобы установить дополнительные зависимости службы:
npm install --save @nestjs/mongoose mongoose
На данный момент мы установили@nestjs/mongoose
а такжеmongoose
, первый представляет собой специфичный для Nest.js пакет инструментов объектного моделирования для MongoDB, а второй — пакет для управления Mongoose.
Теперь запустите приложение с помощью следующей команды:
npm run start
Теперь выберите предпочитаемый браузер, откройтеhttp://localhost:3000
, вы увидите, что наше приложение работает.
Теперь мы успешно создали проект с помощью команд Nest CLI. Затем продолжайте и запустите приложение с портом по умолчанию на локальном компьютере.3000
чтобы получить к нему доступ. В следующем разделе мы более подробно рассмотрим приложение, настроив конфигурацию подключения к базе данных.
Шаг 2. Настройка и подключение к базе данных
На этом этапе мы настроим и интегрируем MongoDB в приложение Nest.js и будем использовать MongoDB для хранения данных приложения. MongoDB преобразует данные вполе: значениепары хранятся в видеdocumentсередина. вы будете использоватьMongooseЧтобы получить доступ к этим структурам данных, Mongoose представляет собой объектно-документное моделирование (ODM), которое позволяет нам определять структуры схемы, которые представляют типы данных, хранящихся в базе данных MongoDB.
Чтобы запустить MongoDB, сначала откройте отдельный терминал, чтобы приложение могло продолжать работать, а затем выполните следующую команду:
sudo mongod
Это запустит службу MongoDB и запустит базу данных в фоновом режиме на вашем компьютере.
Открыть в текстовом редактореblog-backend
проект, таргетинг./src/app.module.ts
документ. Мы можем сделать это, укоренивApplicationModule
установлен вMongooseModule
установить соединение с базой данных. Необходимо добавить следующие строки кода для обновленияapp.module.ts
Содержание в:
~/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 { }
В этом файле мы используемforRoot()
метод для завершения подключения к базе данных. Когда вы закончите редактирование, сохраните и закройте файл.
С их помощью мы можем использовать соответствующий модуль MongoDB в Mongoose для установления соединения с базой данных. В следующем разделе мы создадим схему базы данных, используя библиотеку Mongoose, интерфейс TypeScript и схему объекта передачи данных (DTO).
Шаг 3 — Создайте схему базы данных, интерфейс и DTO
На этом этапе мы будем использовать Mongoose для создания базы данных.schema,интерфейса такжеобъект передачи данных. Mongoose помогает нам управлять отношениями между данными и обеспечивает проверку схемы для типов данных. Чтобы лучше определить структуры данных и типы данных в базе данных в нашем приложении, мы создадим файлы для определения следующего:
- схема базы данных: это организация данных, представляющая собой план, определяющий структуру и типы данных, которые должна хранить база данных.
- интерфейс: Интерфейс TypeScript для проверки типов. Его можно использовать для определения типа данных, передаваемых в приложении.
- объект передачи данных: этот объект определяет, как данные отправляются по сети и как они передаются между процессами.
Сначала вернитесь к терминалу, где запущено текущее приложение, и используйтеCTRL + C
остановить процесс, перейти к./src/
папка:
cd ./src/
Затем создайте файл с именемblog
каталог и создатьschemas
папка:
mkdir -p blog/schemas
существуетschemas
папку, создайте файл с именемblog.schema.ts
новый файл. Откройте его текстовым редактором. Затем добавьте следующее:
~/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
})
Здесь мы используем Mongoose для определения типа данных, которые будут храниться в базе данных. Мы указали, что все поля, которые будут сохранены и приняты, имеют только строковый тип. Сохраните и закройте файл, когда закончите редактирование.
Теперь, когда схема базы данных определена, пришло время перейти к созданию интерфейса.
Сначала вернитесь кblog
папка:
cd ~/blog-backend/src/blog/
Создатьinterfaces
, и перейдите в папку:
mkdir interfaces
существуетinterfaces
папку, создайте файл с именемpost.interface.ts
файл и откройте его текстовым редактором. Добавьте следующее, чтобы определитьPost
тип данных:
~/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
}
В этом файле мы успешно поместилиPost
Тип данных типа определяется как строковое значение. Сохраните и закройте файл.
Поскольку наше приложение будет отправлять данные в базу данных, мы создадим объект передачи данных, который будет определять, как данные будут отправляться в сеть.
Для этого, пожалуйста./src/blog
Создать папку в папкеdto
. В только что созданной папке создайте файл с именемcreate-post.dto.ts
документ
Таргетингblog
папка:
cd ~/blog-backend/src/blog/
Затем создайте файл с именемdto
папку и перейти в эту папку:
mkdir dto
существуетdto
папку, создайте файл с именемcreate-post.dto
новый файл. Откройте его текстовым редактором и добавьте следующее:
~/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
}
мы поставилиCreatePostDTO
Каждое свойство в классе помечено типом данныхstring
, и отмечен какreadonly
, чтобы избежать ненужных манипуляций с данными. Сохраните и закройте файл, когда закончите редактирование.
На этом шаге мы создали схему базы данных, интерфейс и объекты передачи данных для базы данных, в которой будут храниться данные. Далее мы создадим модули, контроллеры и сервисы для блога.
Шаг 4. Создайте модуль, контроллер и сервис для своего блога.
На этом этапе мы улучшим существующую структуру приложения, создав модуль для блога. Этот модуль организует файловую структуру в приложении. Далее мы создадим контроллер для обработки маршрутизации и HTTP-запросов от клиентов. Наконец, мы создадим сервисы для обработки сложной бизнес-логики, которую не могут обработать все контроллеры в приложении.
Создать модуль
Как и интерфейсные фреймворки, такие как Angular, Nest.js использует модульный синтаксис. Приложения Nest.js являются модульными, они поставляются с предустановленным одним корневым модулем, которого обычно достаточно для небольших приложений. Однако, когда бизнес приложений начинает расти, Nest.js рекомендует использовать несколько модулей для организации приложения, разбивая код на разные модули в соответствии со связанными функциями.
в Nest.jsмодульЗависит от@Module()
идентификатор декоратора и принимаетcontroller
а такжеprovider
объекты со свойствами, такими как . Каждое из этих свойств принимает отдельный наборcontroller
а такжеprovider
.
Мы создадим новый модуль для этого блог-приложения, чтобы сделать структуру более организованной. Во-первых, еще~/blog-backend
папке выполните следующую команду:
nest generate module blog
Вы увидите вывод, подобный следующему:
OutputCREATE /src/blog/blog.module.ts
UPDATE /src/app.module.ts
Эта команда создает файл с именемblog.module.ts
новый модуль. Импортируйте вновь созданный модуль в корневой модуль приложения. Это позволит Nest.js знать о существовании другого модуля, кроме корневого модуля.
В этом файле вы увидите следующий код:
~/blog-backend/src/blog/blog.module.ts
import { Module } from '@nestjs/common';
@Module({})
export class BlogModule {}
Позже в этом руководстве мы добавим в него нужные свойства.BlogModule
. Теперь сохраните и выйдите из файла.
Создать сервис
Служить(также называемый провайдером в Nest.js) предназначен для удаления бизнес-логики из контроллеров, которые должны обрабатывать только HTTP-запросы, и перенаправлять более сложные задачи другим классам обслуживания. Сервисы — это обычные классы JavaScript с над своим кодом@Injectable()
декоратор. Чтобы создать новую службу, выполните следующую команду в терминале в каталоге проекта:
nest generate service blog
Вы увидите вывод, подобный следующему:
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)
здесь черезnest
команда создаетblog.service.spec.ts
файл, мы можем использовать его для тестирования. Он также создает новыйblog.service.ts
файл, который будет содержать всю логику для этого приложения и обрабатывать добавление и извлечение документов в базу данных MongoDB. Кроме того, он автоматически импортирует вновь созданные сервисы и добавляет их вblog.module.ts
середина.
Служба обрабатывает всю логику в приложении и отвечает за взаимодействие с базой данных и возврат соответствующего ответа контроллеру. Для этого откройте в текстовом редактореblog.service.ts
файл и замените содержимое следующим:
~/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<Post>) { }
async getPosts(): Promise<Post[]> {
const posts = await this.postModel.find().exec();
return posts;
}
async getPost(postID): Promise<Post> {
const post = await this.postModel
.findById(postID)
.exec();
return post;
}
async addPost(createPostDTO: CreatePostDTO): Promise<Post> {
const newPost = await this.postModel(createPostDTO);
return newPost.save();
}
async editPost(postID, createPostDTO: CreatePostDTO): Promise<Post> {
const editedPost = await this.postModel
.findByIdAndUpdate(postID, createPostDTO, { new: true });
return editedPost;
}
async deletePost(postID): Promise<any> {
const deletedPost = await this.postModel
.findByIdAndRemove(postID);
return deletedPost;
}
}
В этом файле мы сначала начинаем с@nestjs/common
,mongoose
а также@nestjs/mongoose
импортировать необходимые модули. В то же время мы также импортировалиPost
интерфейс и объект передачи данныхCreatePostDTO
.
существуетconstructor
, мы использовали@InjectModel('Post')
,БудуPost
модель внедрить этоBlogService
в классе. Теперь мы можем использовать эту введенную модель для извлечения всех статей, извлечения статьи и выполнения других действий, связанных с базой данных.
Далее мы создали следующий метод:
-
getPosts()
: Получить все статьи из базы данных. -
getPost()
: извлекает статью из базы данных. -
addPost()
: добавить новую статью. -
editPost()
: обновить статью. -
deletePost()
: удалить определенную статью.
Когда закончите, сохраните и закройте файл.
Мы завершили настройку и создание нескольких методов, которые будут передавать соответствующее взаимодействие с базой данных MongoDB через backend API. Теперь мы создадим маршруты, необходимые для обработки HTTP-вызовов от внешнего клиента.
Создать контроллер
В Nest.js,контроллерОтвечает за обработку любых запросов от клиентов приложений и возврат соответствующих ответов. Как и в большинстве других веб-фреймворков, для приложения важно прослушивать запросы и отвечать на них.
Чтобы обслуживать все HTTP-запросы для приложения блога, мы будем использоватьnest
команда для создания нового файла контроллера. Сначала убедитесь, что вы все еще находитесь в каталоге проекта,blog-backend
, затем выполните следующие команды:
nest generate controller blog
Вы увидите вывод, подобный следующему:
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)
Этот вывод указывает, что команда находится вsrc/blog
В каталоге создаются два новых файла,blog.controller.spec.ts
а такжеblog.controller.ts
. Первый — это файл, который можно использовать для написания автоматических тестов для вновь созданных контроллеров. Последний является самим файлом контроллера. Контроллеры в Nest.js используют@Controller
Файлы TypeScript, украшенные метаданными. Эта команда также импортирует только что созданный контроллер и добавляет его в модуль блога.
Далее открываем текстовым редакторомblog.controller.ts
файл и обновить его с помощью:
~/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
})
}
}
В этом файле мы сначала вводим@nestjs/common
Модули модуля, необходимые для обработки HTTP-запросов. Затем мы представили три новых модуля:BlogService
,CreatePostDTO
а такжеValidateObjectId
. После этого, добавив в конструкторBlogService
Внедрить в контроллер, чтобы иметь доступ к использованиюBlogService
Функции, уже определенные в файле. В Nest.js это шаблон, который называетсявнедрение зависимости, что помогает повысить эффективность и улучшить модульность приложения.
Наконец, мы создаем эти асинхронные методы:
-
getPosts()
: этот метод будет выполнять функцию извлечения всех статей из базы данных при получении HTTP-запроса GET от клиента, а затем возвращать соответствующий ответ. оно использует@Get('posts')
Украсить. -
getPost()
: это начнется сpostID
В качестве аргумента получить статью из базы данных. В дополнение к переданному этому методуpostID
В дополнение к параметрам он также реализуетValidateObjectId()
дополнительный метод. Этот метод реализует Nest.jsPipeTransform
интерфейс. Он используется для проверки и проверки того, что его можно найти в базе данных.postID
параметр. Мы определим этот метод в следующем разделе. -
addPost()
: этот метод будет обрабатывать HTTP-запросы POST для добавления новых статей в базу данных.
Чтобы иметь возможность редактировать и удалять определенные статьи, нам нужноblog.controller.ts
Добавьте в файл более двух методов. нам нужно, прежде чем добавить вblog.controller.ts
изaddPost()
После метода непосредственно добавьтеeditPost()
а такжеdeletePost()
метод:
~/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
})
}
}
Вот объяснение того, что именно мы добавили:
-
editPost()
: этот метод принимаетpostID
Параметры запроса и выполните функцию обновления статьи. Это также используетValidateObjectId
Методы предоставляют соответствующую сертификацию для статей, которые вам необходимо отредактировать. -
deletePost()
: этот метод принимаетpostID
параметры запроса и удалить определенные статьи из базы данных.
а такжеBlogController
Точно так же каждый определенный здесь асинхронный метод имеет декоратор метаданных и включает префикс, используемый в механизме маршрутизации в Nest.js. Он контролирует, какие запросы получает каждый контроллер, и указывает на методы ответа, которые должны обрабатывать запрос и возвращать его соответственно.
Например, мы создали в этом разделеBlogController
имеютblog
префикс и имяgetPosts()
использоватьposts
Префиксный метод. Это означает отправку вblog/posts
(http:localhost:3000/blog/posts
), любой запрос GET будетgetPosts()
обработка методом. Другие методы обработки HTTP-запросов аналогичны приведенным в этом примере.
Сохраните и закройте файл.
Полное о приложенииblog.controller.ts
документы, пожалуйста, посетитеDO Community repository.
В этом разделе мы создали модули, чтобы сделать приложение более управляемым. Мы также создали службы для обработки бизнес-логики приложения, взаимодействуя с базой данных и возвращая соответствующие ответы. Наконец, мы создали контроллер и сгенерировали необходимые методы для обработки HTTP-запросов от клиентов, например.GET
,POST
,PUT
а такжеDELETE
. В следующем разделе мы завершим настройку серверной части.
Шаг 5 — Создайте дополнительный сертификат для Mongoose
Мы можем передать уникальный идентификатор (также известный какPostID
), чтобы различать каждый пост в приложении блога. Это означает, что для получения статьи нам нужно передать этот идентификатор в качестве параметра запроса. Чтобы убедиться в этомpostID
параметры и чтобы эта статья действительно была доступна в базе данных, нам нужно создать повторно используемую функцию, к которой можно получить доступ изBlogController
любой метод инициализации.
Чтобы настроить его, перейдите к./src/blog
папка:
cd ./src/blog/
Затем создайте файл с именемshared
новая папка для:
mkdir -p shared/pipes
существуетpipes
папку, с помощью текстового редактора создайте новый файл с именем validate-object-id.pipes.ts и откройте его. Добавьте следующее, чтобы определить принятыйpostID
данные:
~/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<string> {
async transform(value: string, metadata: ArgumentMetadata) {
const isValid = mongoose.Types.ObjectId.isValid(value);
if (!isValid) throw new BadRequestException('Invalid ID!');
return value;
}
}
ValidateObjectId()
класс сделан@nestjs/common
в модулеPipeTransform
метод реализован. оно имеетtransform()
метод, который принимает значение в качестве параметра - в этом случаеpostID
. Используя этот метод, любые данные сpostID
HTTP-запросы внешнего интерфейса в приложении считаются недействительными. Сохраните и закройте файл.
После создания службы и контроллера нам нужно создатьBlogSchema
изPost
Модель. Эта конфигурация может быть в корнеApplicationModule
, но в этом примере мы будемBlogModule
Модели встроены для поддержки организации приложения. Открыть./src/blog/blog.module.ts
и обновите его с помощью:
~/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 { }
Здесь мы используемMongooseModule.forFeature()
метод, чтобы определить, какие модели должны быть зарегистрированы в модуле. Если этот метод недоступен, используйте@injectModel()
декоратор вBlogService
инъекцияPostModel
не будет работать. Когда вы закончите добавлять, сохраните и закройте файл.
На этом этапе мы создали полный бэкэнд RESTful API с помощью Nest.js и интегрировали его с MongoDB. В следующем разделе мы настроим сервер для разрешения HTTP-запросов с других серверов, поскольку наше внешнее приложение и серверная часть будут работать на разных портах.
Шаг 6. Включите CORS
HTTP-запросы между источниками обычно блокируются по умолчанию, если сервер не разрешает это. Чтобы интерфейсные приложения могли выполнять запросы из разных источников на внутренние серверы, эта функция должна быть включена.Совместное использование ресурсов между источниками (CORS), метод, который позволяет запрашивать ресурсы из разных источников на веб-странице.
Чтобы включить CORS в Nest.js, нам нужноmain.ts
Добавьте метод в файл. Откройте его текстовым редактором по адресу./src/main.ts
файл и обновите его следующим образом:
~/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();
Сохраните и закройте файл.
Теперь, когда у нас есть настройка серверной части, мы переместим наше внимание на внешний интерфейс, используя Vue.js для использования созданного API.
Шаг 7 — Создайте внешний интерфейс Vue.js
В этом разделе мы создадим интерфейсное приложение с использованием Vue.js.Vue CLI— это каркас, который позволяет нам быстро и легко создавать и устанавливать новый проект Vue.js.
Во-первых, вам необходимо глобально установить Vue CLI на свой компьютер. Откройте другой терминал, обратите внимание, что путь не вblog-backend
папку, но в папку разработки вашего локального проекта, затем запустите:
npm install -g @vue/cli
После завершения процесса установки мы будем использоватьvue
Команда создает новый проект Vue.js:
vue create blog-frontend
После ввода этой команды мы увидим краткую подсказку. выберитеmanually select features
(имеется в виду ручной выбор функции), затем нажмите кнопку空格
, отображается ряд свойств, позволяющих выбрать свойства, необходимые для этого проекта. мы выберемBabel
,Router
а такжеLinter / Formatter
.
Для следующей инструкции введитеy
использовать режим истории маршрута; это включит режим истории в файле маршрутизатора, который будет автоматически сгенерирован для нашего проекта. Кроме того, выберите толькоESLint with error prevention only
Конфигурация для линтера/форматтера. Далее выберитеLint on save
Чтобы сохранить другие функции Lint. Затем выберите сохранение нашей конфигурации вdedicated config file
(частный файл конфигурации) для будущих проектов. Наконец, введите имя для наших пресетов, напримерvueconfig
.
Vue.js запустится в файле с именемblog-frontend
каталог для создания приложения и всех его необходимых зависимостей.
После завершения процесса установки найдите в приложении Vue.js:
cd blog-frontend
Затем запустите сервер с помощью следующей команды:
npm run serve
Наше приложение будет вhttp://localhost:8080
запускать на.
Поскольку в этом приложении мы будем делать HTTP-запросы, нам нужно установить axios, HTTP-клиент на основе Promise для браузера. Здесь axios будут использоваться для выполнения HTTP-запросов от разных компонентов приложения. На терминале вашего компьютера нажмитеCTRL + C
Завершите интерфейсное приложение, затем выполните следующие команды:
npm install axios --save
Наше внешнее приложение будет выполнять вызовы API к внутреннему API в определенном домене из разных компонентов приложения. Чтобы убедиться, что структура запроса маршрутизации нашего приложения верна, мы можем создать辅助
файл, в котором определен серверbaseURL
.
Во-первых, в терминале, который все еще находится в передней части блога, найдите./src/
папка:
cd ./src/
Создайте другое имяutils
папка:
mkdir utils
существуетutils
папку, с помощью текстового редактора создайте файл с именемhelper.js
новый файл и откройте его. Добавьте следующее, чтобы определить серверный проект Nest.js.baseURL
:
~blog-frontend/src/utils/helper.js
export const server = {
baseURL: 'http://localhost:3000'
}
ОпределенныйbaseURL
После этого мы можем вызвать его из любого места в файле компонента Vue.js. В случае необходимости изменения URL-адреса проще изменить базовый URL-адрес в этом файле, чем обновлять его во всем коде приложения.
В этом разделе мы установили Vue CLI, инструмент для создания новых приложений Vue.js. Мы используем этот инструмент для созданияblog-frontend
заявление. Кроме того, мы запустили приложение и установили библиотеку под названием axios, которую мы используем всякий раз, когда в приложении происходит вызов HTTP. Далее мы создадим компоненты для приложения.
Шаг 8 — Создание повторно используемых компонентов
Теперь мы собираемся создать повторно используемые компоненты для нашего приложения, которое является стандартной структурой приложения Vue.js. Система компонентов в Vue.js позволяет разработчикам создавать единую автономную единицу интерфейса с собственным состоянием, HTML и стилями. Это позволяет повторно использовать эти компоненты.
Каждый компонент Vue.js состоит из трех отдельных частей:
-
<template>
: содержит HTML-контент -
<script>
: содержит всю базовую интерфейсную логику и определяет функции -
<style>
: отдельные таблицы стилей для каждого компонента
Сначала создадим компонент для создания статей. мы должны./src/components
Создайте папку с именемpost
Новая папка для необходимых повторно используемых компонентов о статье. Затем используйте текстовый редактор во вновь созданномpost
Создайте еще один файл в папке и назовите егоCreate.vue
. Откройте этот файл и добавьте следующий код, который сообщает нам поля ввода, которые нам нужны для отправки нашей статьи:
~blog-frontend/src/components/post/Create.vue
<template>
<div>
<div class="col-md-12 form-wrapper">
<h2> Create Post </h2>
<form id="create-post-form" @submit.prevent="createPost">
<div class="form-group col-md-12">
<label for="title"> Title </label>
<input type="text" id="title" v-model="title" name="title" class="form-control" placeholder="Enter title">
</div>
<div class="form-group col-md-12">
<label for="description"> Description </label>
<input type="text" id="description" v-model="description" name="description" class="form-control" placeholder="Enter Description">
</div>
<div class="form-group col-md-12">
<label for="body"> Write Content </label>
<textarea id="body" cols="30" rows="5" v-model="body" class="form-control"></textarea>
</div>
<div class="form-group col-md-12">
<label for="author"> Author </label>
<input type="text" id="author" v-model="author" name="author" class="form-control">
</div>
<div class="form-group col-md-4 pull-right">
<button class="btn btn-success" type="submit"> Create Post </button>
</div>
</form>
</div>
</div>
</template>
ЭтоCreatePost
компонент<template>
часть. Он содержит ввод HTML-элемента, необходимый для создания новой статьи. Каждое поле ввода имеетv-model
Директивы как входные свойства. Это делается для того, чтобы включить двустороннюю привязку данных для полей ввода в каждой форме, чтобы Vue.js было проще получать ввод пользователя.
Далее будет<script>
Раздел добавляется непосредственно в предыдущий файл:
~blog-frontend/src/components/post/Create.vue
...
<script>
import axios from "axios";
import { server } from "../../utils/helper";
import router from "../../router";
export default {
data() {
return {
title: "",
description: "",
body: "",
author: "",
date_posted: ""
};
},
created() {
this.date_posted = new Date().toLocaleDateString();
},
methods: {
createPost() {
let postData = {
title: this.title,
description: this.description,
body: this.body,
author: this.author,
date_posted: this.date_posted
};
this.__submitToServer(postData);
},
__submitToServer(data) {
axios.post(`${server.baseURL}/blog/post`, data).then(data => {
router.push({ name: "home" });
});
}
}
};
</script>
Здесь мы добавляем файл с именемcreatePost()
способ создать новую статью и отправить ее на сервер с помощью axios. Как только пользователь создаст новую статью, приложение перенаправит его обратно на домашнюю страницу, где пользователь сможет просмотреть список созданных статей.
Позже в этом руководстве мы настроим vue-router для реализации перенаправления.
Сохраните и закройте файл, когда закончите редактирование. Полное о приложенииCreate.vue
документы, пожалуйста, посетитеDO Community repository.
Теперь нам нужно создать еще один компонент для редактирования конкретной статьи. Таргетинг./src/components/post
папку, создайте новую с именемEdit.vue
документ. добавить следующее<template>
Часть кода в файле:
~blog-frontend/src/components/post/Edit.vue
<template>
<div>
<h4 class="text-center mt-20">
<small>
<button class="btn btn-success" v-on:click="navigate()"> View All Posts </button>
</small>
</h4>
<div class="col-md-12 form-wrapper">
<h2> Edit Post </h2>
<form id="edit-post-form" @submit.prevent="editPost">
<div class="form-group col-md-12">
<label for="title"> Title </label>
<input type="text" id="title" v-model="post.title" name="title" class="form-control" placeholder="Enter title">
</div>
<div class="form-group col-md-12">
<label for="description"> Description </label>
<input type="text" id="description" v-model="post.description" name="description" class="form-control" placeholder="Enter Description">
</div>
<div class="form-group col-md-12">
<label for="body"> Write Content </label>
<textarea id="body" cols="30" rows="5" v-model="post.body" class="form-control"></textarea>
</div>
<div class="form-group col-md-12">
<label for="author"> Author </label>
<input type="text" id="author" v-model="post.author" name="author" class="form-control">
</div>
<div class="form-group col-md-4 pull-right">
<button class="btn btn-success" type="submit"> Edit Post </button>
</div>
</form>
</div>
</div>
</template>
Содержимое раздела шаблона здесь такое же, как иCreatePost()
Компоненты аналогичны, единственное отличие состоит в том, что он содержит конкретное содержание конкретной статьи, которую необходимо отредактировать.
Далее непосредственно вEdit.vue
середина</template>
добавить после части<script>
часть:
~blog-frontend/src/components/post/Edit.vue
...
<script>
import { server } from "../../utils/helper";
import axios from "axios";
import router from "../../router";
export default {
data() {
return {
id: 0,
post: {}
};
},
created() {
this.id = this.$route.params.id;
this.getPost();
},
methods: {
editPost() {
let postData = {
title: this.post.title,
description: this.post.description,
body: this.post.body,
author: this.post.author,
date_posted: this.post.date_posted
};
axios
.put(`${server.baseURL}/blog/edit?postID=${this.id}`, postData)
.then(data => {
router.push({ name: "home" });
});
},
getPost() {
axios
.get(`${server.baseURL}/blog/post/${this.id}`)
.then(data => (this.post = data.data));
},
navigate() {
router.go(-1);
}
}
};
</script>
Здесь мы получаем параметры маршрутаid
для обозначения конкретной статьи. Затем мы создалиgetPost()
метод для извлечения сведений об этой статье из базы данных и использования их для обновления страницы. Наконец, мы создалиeditPost()
метод для отправки отредактированной статьи обратно на внутренний сервер с помощью HTTP-запроса PUT.
Сохраните и закройте файл, когда закончите редактирование. Полное о приложенииEdit.vue
документы, пожалуйста, посетитеDO Community repository.
Теперь мы./src/components/post
Создайте папку с именемPost.vue
новые компоненты. Это позволяет нам просматривать детали конкретной статьи с главной страницы. Затем добавьте следующее вPost.vue
середина:
~blog-frontend/src/components/post/Post.vue
<template>
<div class="text-center">
<div class="col-sm-12">
<h4 style="margin-top: 30px;"><small><button class="btn btn-success" v-on:click="navigate()"> View All Posts </button></small></h4>
<hr>
<h2>{{ post.title }}</h2>
<h5><span class="glyphicon glyphicon-time"></span> Post by {{post.author}}, {{post.date_posted}}.</h5>
<p> {{ post.body }} </p>
</div>
</div>
</template>
Этот код будет отображать детали статьи, в том числе标题(titile)
,作者(author)
и статьи正文(body)
.
Теперь непосредственно в</template>
После этого добавьте следующий код:
~blog-frontend/src/components/post/Post.vue
...
<script>
import { server } from "../../utils/helper";
import axios from "axios";
import router from "../../router";
export default {
data() {
return {
id: 0,
post: {}
};
},
created() {
this.id = this.$route.params.id;
this.getPost();
},
methods: {
getPost() {
axios
.get(`${server.baseURL}/blog/post/${this.id}`)
.then(data => (this.post = data.data));
},
navigate() {
router.go(-1);
}
}
};
</script>
здесь<script>
Содержимое части аналогично компоненту специальной статьи редактора, параметры получаем из роутаid
и используйте его для получения сведений о конкретной статье.
Сохраните и закройте файл, когда закончите редактирование. Полное о приложенииPost.vue
документы, пожалуйста, посетитеDO Community repository.
Далее, вы хотите отобразить все созданные статьи пользователю, нам нужно создать новый компонент. Таргетингsrc/views
серединаviews
папка, вы увидитеHome.vue
Компонент. Если этот файл не существует, создайте его с помощью текстового редактора и добавьте следующий код:
~blog-frontend/src/views/Home.vue
<template>
<div>
<div class="text-center">
<h1>Nest Blog Tutorial</h1>
<p> This is the description of the blog built with Nest.js, Vue.js and MongoDB</p>
<div v-if="posts.length === 0">
<h2> No post found at the moment </h2>
</div>
</div>
<div class="row">
<div class="col-md-4" v-for="post in posts" :key="post._id">
<div class="card mb-4 shadow-sm">
<div class="card-body">
<h2 class="card-img-top">{{ post.title }}</h2>
<p class="card-text">{{ post.body }}</p>
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group" style="margin-bottom: 20px;">
<router-link :to="{name: 'Post', params: {id: post._id}}" class="btn btn-sm btn-outline-secondary">View Post </router-link>
<router-link :to="{name: 'Edit', params: {id: post._id}}" class="btn btn-sm btn-outline-secondary">Edit Post </router-link>
<button class="btn btn-sm btn-outline-secondary" v-on:click="deletePost(post._id)">Delete Post</button>
</div>
</div>
<div class="card-footer">
<small class="text-muted">Posted on: {{ post.date_posted}}</small><br/>
<small class="text-muted">by: {{ post.author}}</small>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
здесь, в<template>
участок, черезpost._id
параметры, мы используем<router-link>
создавать ссылки для редактирования и просмотра статей. мы также использовалиv-if
Директивы выборочно отображают статьи для пользователя. Если в базе нет статей, пользователь увидит только следующий текст:На данный момент пост не найден.
Сохраните и закройте файл, когда закончите редактирование. Полное о приложенииHome.vue
документы, пожалуйста, посетитеDO Community repository.
Теперь непосредственно вHome.vue
середина</template>
После части добавьте следующее</script>
часть:
~blog-frontend/src/views/Home.vue
...
<script>
// @ 是 /src 的别名
import { server } from "@/utils/helper";
import axios from "axios";
export default {
data() {
return {
posts: []
};
},
created() {
this.fetchPosts();
},
methods: {
fetchPosts() {
axios
.get(`${server.baseURL}/blog/posts`)
.then(data => (this.posts = data.data));
},
deletePost(id) {
axios.delete(`${server.baseURL}/blog/delete?postID=${id}`).then(data => {
console.log(data);
window.location.reload();
});
}
}
};
</script>
в этом файле<script>
раздел, мы создалиfetchPosts()
метод для получения всех статей из базы данных и обновления страницы данными, возвращенными сервером.
Теперь мы обновим внешний интерфейс приложения.App
компоненты для созданияHome
компоненты иCreate
Ссылка на компонент. Открытьsrc/App.vue
, обновите его с помощью:
~blog-frontend/src/App.vue
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/create">Create</router-link>
</div>
<router-view/>
</div>
</template>
<style>
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
}
#nav {
padding: 30px;
text-align: center;
}
#nav a {
font-weight: bold;
color: #2c3e50;
}
#nav a.router-link-exact-active {
color: #42b983;
}
</style>
В приведенном выше коде, кроме включения вHome
а такжеCreate
Помимо ссылки на компонент, он также содержит<Style>
Раздел, который является таблицей стилей для этого компонента, содержит определения стилей для некоторых элементов на странице. Сохраните и закройте файл.
В этом разделе мы создали все компоненты, необходимые приложению. Далее мы настроим файл маршрутизации.
Шаг 9 — Постройте маршрут
После создания всех необходимых повторно используемых компонентов теперь мы можем правильно настроить файл маршрутизации, обновив файл маршрута, содержащий ссылки на все компоненты. Это гарантирует, что все маршруты во внешнем приложении будут сопоставлены с определенными компонентами, чтобы можно было предпринять соответствующие действия. Таргетинг./src/router.js
, и замените его содержимое следующим:
~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 }
]
});
мы начинаем сvue-router
импортируется в модульRouter
, и, пройдяmode
а такжеroute
Параметр создает его экземпляр.vue-router
Режим по умолчанию — хеш-режим, который использует хэш URL-адреса для имитации полного URL-адреса, поэтому страница не перезагружается при изменении URL-адреса. Если хеш-режим не нужен, мы можем использовать здесь режим истории, чтобы реализовать маршрутизацию URL-адресов без перезагрузки страницы. Наконец, вroutes
В опциях указываем конкретный соответствующий компонент маршрута — компонент и имя компонента, который должен отрисовываться при вызове маршрута в приложении. Сохраните и закройте файл.
Теперь, когда мы настроили маршрутизацию приложения, нам нужно импортировать файл Bootstrap, чтобы предварительно настроить пользовательский интерфейс приложения. Нам нужно открыть в текстовом редакторе./public/index.html
файл и включите файлы CDN для Bootstrap, добавив в файл следующее:
~blog-frontend/public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
...
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<title>blog-frontend</title>
</head>
<body>
...
</body>
</html>
сохраните и выйдите из файла, затем используйтеnpm run serve
За нашихblog-frontend
Проект перезапускает приложение, если оно в данный момент не запущено.
Уведомление:Убедитесь, что и внутренний сервер, и экземпляр MongoDB запущены. Если нет, перейдите от другого нового терминала кblog-backend
под проект и запуститьnpm run start
. Опять же, запустив с нового терминалаsudo mongod
для запуска службы MongoDB.
Перейти к нашему приложению по URL-адресу:http://localhost:8080
. Теперь вы можете протестировать свой блог, создавая и редактируя статьи!
Нажмите на приложениеCreateсмотретьCreate Postвид, который аналогиченCreateComponent
Компонент связан и будет отображать этот компонент. Введите что-нибудь в поле ввода и нажмитеCreate Postкнопка отправки статьи. После этого приложение перенаправит вас обратно на домашнюю страницу.
На главной странице приложения отображаются компонентыHomeComponent
. Этот компонент вызовет один из своих методов и отправит HTTP-вызов, чтобы получить все статьи из базы данных и отобразить их пользователю.
Нажмите на конкретную статьюEdit Postи вы попадете на страницу редактирования, где сможете внести любые изменения и сохранить свою статью.
В этом разделе мы настраиваем и настраиваем маршрутизацию для приложения. На этом наше приложение для блога готово.
Суммировать
В этом руководстве вы изучили новые способы структурирования приложений Node.js с помощью Nest.js. Вы создали простое приложение для блога, построили серверный RESTful API с помощью Nest.js и обработали всю логику внешнего интерфейса с помощью Vue.js. Кроме того, вы интегрируете базу данных MongoDB в свое приложение Nest.js.
Чтобы узнать, как добавить аутентификацию в ваше приложение, вы можете использоватьPassport.js. Популярная библиотека аутентификации для Node.js. ты сможешьДокументация Nest.jsУзнайте об интеграции Passport.js в .
ты сможешьGitHub для этого проектаНайдите полный исходный код проекта на . Хотите получить больше информации о Nest. вы можете посетитьофициальная документация.
Если вы обнаружите ошибки в переводе или в других областях, требующих доработки, добро пожаловать наПрограмма перевода самородковВы также можете получить соответствующие бонусные баллы за доработку перевода и PR. начало статьиПостоянная ссылка на эту статьюЭто ссылка MarkDown этой статьи на GitHub.
Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из Интернета сНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,товар,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.