Cách tạo blog bằng Nest.js, MongoDB và Vue.js
Nest.js là một khung JavaScript phía server , có thể mở rộng được xây dựng bằng TypeScript vẫn duy trì khả năng tương thích với JavaScript, làm cho nó trở thành một công cụ hiệu quả để xây dựng các ứng dụng back-end hiệu quả và tin cậy . Nó có kiến trúc module cung cấp một mẫu thiết kế cấu trúc, trưởng thành cho thế giới phát triển Node.js.Vue.js là một khung JavaScript front-end để xây dựng giao diện user . Nó có một API đơn giản nhưng rất mạnh mẽ cùng với hiệu suất tuyệt vời. Vue.js có khả năng cấp nguồn cho lớp front-end và logic của bất kỳ ứng dụng web nào dù kích thước. Việc dễ dàng tích hợp nó với các thư viện khác hoặc các dự án hiện có làm cho nó trở thành một lựa chọn hoàn hảo cho hầu hết các ứng dụng web hiện đại.
Trong hướng dẫn này, bạn sẽ xây dựng ứng dụng Nest.js để làm quen với các khối xây dựng của nó cũng như các nguyên tắc cơ bản của việc xây dựng các ứng dụng web hiện đại. Bạn sẽ tiếp cận dự án này bằng cách tách ứng dụng thành hai phần khác nhau: giao diện user và phần backend . Đầu tiên, bạn sẽ tập trung vào API back-end RESTful được xây dựng bằng Nest.js. Sau đó, bạn sẽ tập trung vào giao diện user mà bạn sẽ xây dựng với Vue.js. Cả hai ứng dụng sẽ chạy trên các cổng khác nhau và sẽ hoạt động như các domain riêng biệt.
Bạn sẽ xây dựng một ứng dụng blog để user có thể tạo và lưu một bài đăng mới, xem các bài đăng đã lưu trên trang chủ và thực hiện các quy trình khác như chỉnh sửa và xóa bài đăng. Hơn nữa, bạn sẽ kết nối ứng dụng của bạn và duy trì dữ liệu của nó với MongoDB , đây là một database NoSQL không có schemas có thể nhận và lưu trữ các tài liệu JSON. Hướng dẫn này tập trung vào việc xây dựng ứng dụng của bạn trong môi trường phát triển. Đối với môi trường production , bạn cũng nên xem xét xác thực user cho ứng dụng của bạn .
Yêu cầu
Để hoàn thành hướng dẫn này, bạn cần :
- Một cài đặt local của Node.js (ít nhất là v6) và npm (ít nhất là v5.2). Node.js là một môi trường thời gian chạy JavaScript cho phép bạn chạy mã của bạn bên ngoài trình duyệt. Nó đi kèm với một trình quản lý gói được cài đặt sẵn có tên là
npm
, cho phép bạn cài đặt và cập nhật các gói. Để cài đặt chúng trên macOS hoặc Ubuntu 18.04, hãy làm theo các bước trong Cách cài đặt Node.js và Tạo môi trường phát triển local trên macOS hoặc phần “Cài đặt bằng PPA” của Cách cài đặt Node.js trên Ubuntu 18.04 . - MongoDB được cài đặt trên máy của bạn. Làm theo hướng dẫn tại đây để download và cài đặt nó cho sự lựa chọn của hệ điều hành. Để cài đặt thành công MongoDB, bạn có thể cài đặt nó bằng Homebrew trên Mac hoặc bằng cách download từ trang web MongoDB.
- Hiểu biết cơ bản về TypeScript và JavaScript .
- Đã cài đặt một editor , chẳng hạn như Visual Studio Code , Atom hoặc Sublime Text .
Lưu ý: Hướng dẫn này sử dụng máy macOS để phát triển. Nếu bạn đang sử dụng hệ điều hành khác, bạn có thể cần sử dụng sudo
cho các lệnh npm
trong suốt hướng dẫn.
Bước 1 - Cài đặt Nest.js và các phần phụ thuộc khác
Trong phần này, bạn sẽ bắt đầu với Nest.js bằng cách cài đặt ứng dụng và các phụ thuộc của nó trên máy local của bạn.Bạn có thể dễ dàng cài đặt Nest.js bằng cách sử dụng CLI mà Nest.js cung cấp hoặc bằng cách cài đặt dự án khởi động từ GitHub. Với mục đích của hướng dẫn này, bạn sẽ sử dụng CLI để cài đặt ứng dụng. Để bắt đầu, hãy chạy lệnh sau từ terminal để cài đặt nó trên phạm vi global trên máy của bạn:
- npm i -g @nestjs/cli
Bạn sẽ thấy kết quả tương tự như sau:
Output@nestjs/cli@5.8.0 added 220 packages from 163 contributors in 49.104s
Để xác nhận cài đặt Nest CLI, hãy chạy lệnh này từ terminal của bạn:
- nest --version
Bạn sẽ thấy kết quả hiển thị version hiện tại được cài đặt trên máy của bạn:
Output5.8.0
Bạn sẽ sử dụng lệnh nest
để quản lý dự án của bạn và sử dụng nó để tạo các file có liên quan - như bộ điều khiển, module và trình cung cấp.
Để bắt đầu dự án cho hướng dẫn này, hãy sử dụng lệnh nest
để tạo một dự án Nest.js mới có tên blog-backend
bằng cách chạy lệnh sau từ terminal của bạn:
- nest new blog-backend
Ngay sau khi chạy lệnh, nest
sẽ nhắc bạn cung cấp một số thông tin cơ bản như description
, version
và author
. Hãy tiếp tục và cung cấp các chi tiết thích hợp. Nhấn ENTER
trên máy tính của bạn để tiếp tục sau khi trả lời từng dấu nhắc .
Tiếp theo, bạn sẽ chọn một trình quản lý gói. Với mục đích của hướng dẫn này, hãy chọn npm
và nhấn ENTER
để bắt đầu cài đặt Nest.js.
Điều này sẽ tạo một dự án Nest.js mới trong folder blog-backend
trong folder phát triển local của bạn.
Tiếp theo, chuyển đến folder của dự án mới từ terminal của bạn:
- cd blog-backend
Chạy lệnh sau để cài đặt các phụ thuộc server khác:
- npm install --save @nestjs/mongoose mongoose
Bạn đã cài đặt @nestjs/mongoose
, là một gói dành riêng cho Nest.js dành cho công cụ mô hình hóa đối tượng cho MongoDB và mongoose
, là một gói dành cho Mongoose.
Đến đây bạn sẽ khởi động ứng dụng bằng lệnh sau:
- npm run start
Bây giờ, nếu bạn chuyển đến http://localhost:3000
từ trình duyệt yêu thích của bạn , bạn sẽ thấy ứng dụng của bạn đang chạy.
Bạn đã tạo dự án thành công bằng cách tận dụng tính khả dụng của lệnh Nest CLI. Sau đó, bạn tiến hành chạy ứng dụng và truy cập nó trên cổng mặc định 3000
trên máy local của bạn. Trong phần tiếp theo, bạn sẽ đưa ứng dụng đi xa hơn bằng cách cài đặt cấu hình cho kết nối database .
Bước 2 - Cấu hình và kết nối với database
Trong bước này, bạn sẽ cấu hình và tích hợp MongoDB vào ứng dụng Nest.js của bạn . Bạn sẽ sử dụng MongoDB để lưu trữ dữ liệu cho ứng dụng của bạn . MongoDB lưu trữ dữ liệu của nó trong các tài liệu dưới dạng các cặp trường: giá trị . Để truy cập cấu trúc dữ liệu này, bạn sẽ sử dụng Mongoose , là một mô hình hóa tài liệu đối tượng (ODM) cho phép bạn xác định các schemas đại diện cho các loại dữ liệu mà database MongoDB lưu trữ.
Để khởi động MongoDB, hãy mở một cửa sổ terminal riêng biệt để ứng dụng có thể tiếp tục chạy, sau đó thực hiện lệnh sau:
- sudo mongod
Thao tác này sẽ khởi động dịch vụ MongoDB và chạy database trong nền máy của bạn.
Mở blog-backend
của dự án trong editor của bạn và chuyển đến ./src/app.module.ts
. Bạn có thể cài đặt kết nối với database bằng cách bao gồm MongooseModule
đã cài đặt trong ApplicationModule
root . Để làm điều này, hãy cập nhật nội dung trong app.module.ts
với các dòng được đánh dấu sau:
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 { }
Trong file này, bạn sử dụng phương thức forRoot()
để cung cấp kết nối đến database . Lưu file khi bạn hoàn tất chỉnh sửa.
Với điều này, bạn đã cài đặt kết nối database bằng cách sử dụng module Mongoose cho MongoDB. Trong phần tiếp theo, bạn sẽ tạo một schemas database bằng cách sử dụng thư viện Mongoose, giao diện TypeScript và schemas đối tượng truyền dữ liệu (DTO).
Bước 3 - Tạo schemas database , giao diện và DTO
Trong bước này, bạn sẽ tạo một lược đồ , giao diện và đối tượng truyền dữ liệu cho database của bạn bằng Mongoose. Mongoose giúp quản lý mối quan hệ giữa các dữ liệu và cung cấp xác nhận schemas cho các kiểu dữ liệu. Để giúp xác định cấu trúc và kiểu dữ liệu của dữ liệu trong database của ứng dụng, bạn sẽ tạo các file xác định những điều sau:
lược đồ database : Đây là một tổ chức dữ liệu như một bản thiết kế để xác định cấu trúc và các loại dữ liệu mà database cần lưu trữ.
giao diện : Giao diện TypeScript được sử dụng để kiểm tra kiểu. Nó được dùng để xác định các loại dữ liệu sẽ được chuyển cho một ứng dụng.
đối tượng truyền dữ liệu : Đây là đối tượng xác định cách thức dữ liệu sẽ được gửi qua mạng và mang dữ liệu giữa các tiến trình.
Để bắt đầu, hãy quay lại terminal của bạn nơi ứng dụng hiện đang chạy và dừng quá trình bằng CTRL + C
, sau đó chuyển đến folder ./src/
:
- cd ./src/
Sau đó, tạo một folder có tên blog
và một folder schemas
trong đó:
- mkdir -p blog/schemas
Trong folder schemas
, hãy tạo một file mới có tên blog.schema.ts
và mở nó bằng editor của bạn. Sau đó, thêm nội dung sau:
import * as mongoose from 'mongoose'; export const BlogSchema = new mongoose.Schema({ title: String, description: String, body: String, author: String, date_posted: String })
Ở đây, bạn đã sử dụng Mongoose để xác định loại dữ liệu mà bạn sẽ lưu trữ trong database . Bạn đã chỉ định rằng tất cả các trường sẽ lưu trữ và chỉ chấp nhận các giá trị chuỗi. Lưu file khi bạn hoàn tất chỉnh sửa.
Bây giờ, với schemas database được xác định, bạn có thể chuyển sang tạo giao diện.
Để bắt đầu, hãy chuyển trở lại folder blog
:
- cd ~/blog-backend/src/blog/
Tạo một folder mới có tên là interfaces
và chuyển vào đó:
- mkdir interfaces
Trong folder interfaces
, hãy tạo một file mới có tên post.interface.ts
và mở file đó bằng editor của bạn. Thêm nội dung sau để xác định các loại dữ liệu cho một Post
:
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 }
Trong file này, bạn đã xác định thành công các loại dữ liệu cho một loại Post
dưới dạng giá trị chuỗi. Lưu và thoát khỏi file .
Vì ứng dụng của bạn sẽ thực hiện chức năng đăng dữ liệu lên database , bạn sẽ tạo một đối tượng truyền dữ liệu sẽ xác định cách dữ liệu sẽ được gửi qua mạng.
Để làm điều này, hãy tạo một folder dto
bên trong folder ./src/blog
. Trong folder mới tạo, hãy tạo một file khác có tên là create-post.dto.ts
Điều hướng trở lại folder blog
:
- cd ~/blog-backend/src/blog/
Sau đó, tạo một folder có tên dto
và chuyển vào đó:
- mkdir dto
Trong folder dto
, hãy tạo một file mới có tên là create-post.dto.ts
và mở file đó bằng editor văn bản của bạn để thêm nội dung sau:
export class CreatePostDTO { readonly title: string; readonly description: string; readonly body: string; readonly author: string; readonly date_posted: string }
Bạn đã đánh dấu từng thuộc tính riêng lẻ trong lớp CreatePostDTO
để có kiểu dữ liệu là string
và ở dạng readonly
để tránh đột biến không cần thiết. Lưu và thoát khỏi file khi bạn hoàn tất chỉnh sửa.
Trong bước này, bạn đã tạo một schemas database cho database , một giao diện và một đối tượng truyền dữ liệu cho dữ liệu mà database của bạn sẽ lưu trữ. Tiếp theo, bạn sẽ tạo một module , bộ điều khiển và dịch vụ cho blog của bạn .
Bước 4 - Tạo Mô-đun, Bộ điều khiển và Dịch vụ cho Blog
Trong bước này, bạn sẽ cải thiện cấu trúc hiện có của ứng dụng bằng cách tạo một module cho blog của bạn . Mô-đun này sẽ tổ chức cấu trúc file của ứng dụng của bạn. Tiếp theo, bạn sẽ tạo một bộ điều khiển để xử lý các tuyến và xử lý các yêu cầu HTTP từ client . Để kết thúc mọi thứ, bạn sẽ cài đặt một dịch vụ để xử lý tất cả logic nghiệp vụ quá phức tạp để bộ điều khiển của ứng dụng xử lý.
Tạo module
Tương tự như khuôn khổ web front-end Angular, Nest.js sử dụng cú pháp module . Các ứng dụng Nest.js có thiết kế module ; nó được cài đặt với một module root duy nhất, thường đủ cho một ứng dụng nhỏ. Nhưng khi một ứng dụng bắt đầu phát triển, Nest.js đề xuất tổ chức nhiều module , tách mã thành các tính năng liên quan.
Mô-đun trong Nest.js được nhận dạng bởi trình trang trí @Module()
và đưa vào một đối tượng có các thuộc tính như controllers
và trình providers
. Mỗi thuộc tính này có một loạt các controllers
và trình providers
tương ứng.
Bạn sẽ tạo một module mới cho ứng dụng blog này để giữ cho cấu trúc có tổ chức hơn. Để bắt đầu, vẫn trong folder ~/ blog-backend
, hãy thực hiện lệnh sau:
- nest generate module blog
Bạn sẽ thấy kết quả tương tự như sau:
OutputCREATE /src/blog/blog.module.ts UPDATE /src/app.module.ts
Lệnh này đã tạo một module mới có tên blog.module.ts
cho ứng dụng và nhập module mới được tạo vào module root cho ứng dụng. Điều này sẽ cho phép Nest.js nhận biết được một module khác ngoài module root .
Trong file này, bạn sẽ thấy mã sau:
import { Module } from '@nestjs/common'; @Module({}) export class BlogModule {}
Bạn sẽ cập nhật BlogModule
này với các thuộc tính cần thiết ở phần sau của hướng dẫn. Lưu và thoát khỏi file .
Tạo một dịch vụ
Một dịch vụ , còn có thể được gọi là nhà cung cấp trong Nest.js, được thiết kế để loại bỏ logic khỏi bộ điều khiển, nghĩa là chỉ xử lý các yêu cầu HTTP và chuyển hướng các việc phức tạp hơn đến các dịch vụ. Dịch vụ là các lớp JavaScript thuần túy với trình trang trí @Injectable()
ở trên cùng. Để tạo một dịch vụ mới, hãy chạy lệnh sau từ terminal khi bạn vẫn ở trong folder dự án:
- nest generate service blog
Bạn sẽ thấy kết quả tương tự như sau:
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)
Lệnh nest
được sử dụng ở đây đã tạo file blog.service.spec.ts
, bạn có thể sử dụng file này để thử nghiệm. Nó cũng đã tạo một file blog.service.ts
mới, file này sẽ giữ tất cả logic cho ứng dụng này và xử lý việc thêm và truy xuất tài liệu vào database MongoDB. Ngoài ra, nó tự động nhập dịch vụ mới được tạo và thêm vào blog.module.ts.
Dịch vụ xử lý tất cả logic bên trong ứng dụng, chịu trách nhiệm tương tác với database và trả về các phản hồi thích hợp cho bộ điều khiển. Để thực hiện việc này, hãy mở file blog.service.ts
trong editor của bạn và thay thế nội dung bằng những thứ sau:
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; } }
Trong file này, trước tiên bạn đã nhập module bắt buộc từ @nestjs/common
, mongoose
và @nestjs/mongoose
. Bạn cũng đã nhập một giao diện có tên Post
và một đối tượng truyền dữ liệu CreatePostDTO
.
Trong hàm constructor
, bạn đã thêm @InjectModel(
'
Post
'
)
, sẽ đưa mô hình Post
vào lớp BlogService
này. Như vậy, bạn có thể sử dụng mô hình được chèn này để truy xuất tất cả các bài đăng, tìm nạp một bài đăng và thực hiện các hoạt động khác liên quan đến database .
Tiếp theo, bạn đã tạo các phương thức sau:
-
getPosts()
: để tìm nạp tất cả các bài đăng từ database . -
getPost()
: để lấy một bài đăng từ database . -
addPost()
: để thêm bài viết mới. -
editPost()
: để cập nhật một bài đăng. -
deletePost()
: để xóa một bài đăng cụ thể.
Lưu và thoát khỏi file khi bạn hoàn tất.
Bạn đã hoàn tất việc cài đặt và tạo một số phương thức sẽ xử lý tương tác thích hợp với database MongoDB từ API back-end. Bây giờ, bạn sẽ tạo các tuyến cần thiết sẽ xử lý các cuộc gọi HTTP từ client front-end.
Tạo bộ điều khiển
Trong Nest. js, bộ điều khiển chịu trách nhiệm xử lý bất kỳ yêu cầu nào đến từ phía client của một ứng dụng và trả lại phản hồi thích hợp. Tương tự như hầu hết các khuôn khổ web khác, điều quan trọng là ứng dụng phải lắng nghe yêu cầu và phản hồi yêu cầu đó.
Để đáp ứng tất cả các yêu cầu HTTP cho ứng dụng blog của bạn, bạn sẽ sử dụng lệnh nest
để tạo một file bộ điều khiển mới. Đảm bảo rằng bạn vẫn ở trong folder dự án, blog-backend
và chạy lệnh sau:
- nest generate controller blog
Bạn sẽ thấy kết quả tương tự như:
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)
Đầu ra cho biết lệnh này đã tạo hai file mới trong folder src/blog
. Chúng là blog.controller.spec.ts
và blog.controller.ts
. Trước đây là một file mà bạn có thể sử dụng để viết kiểm thử tự động cho bộ điều khiển mới được tạo. Sau đó là file điều khiển chính nó. Bộ điều khiển trong Nest.js là các file TypeScript được trang trí bằng metadata @Controller
. Lệnh này cũng đã nhập bộ điều khiển mới được tạo và thêm vào module blog.
Tiếp theo, mở file blog.controller.ts
bằng editor văn bản của bạn và cập nhật file với nội dung sau:
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 }) } }
Trong file này, trước tiên bạn đã nhập các module cần thiết để xử lý các yêu cầu HTTP từ @nestjs/common
module @nestjs/common
. Sau đó, bạn đã nhập ba module mới là: BlogService
, CreatePostDTO
và ValidateObjectId
. Sau đó, bạn đã đưa BlogService
vào bộ điều khiển thông qua một hàm tạo để có quyền truy cập và sử dụng các chức năng đã được xác định trong file BlogService
. Đây là một mẫu được coi là phụ thuộc được sử dụng trong Nest.js để tăng hiệu quả và nâng cao tính module của ứng dụng.
Cuối cùng, bạn đã tạo các phương thức không đồng bộ sau:
getPosts()
: Phương thức này sẽ thực hiện chức năng nhận yêu cầu HTTP GET từ client để tìm nạp tất cả các bài đăng từ database và sau đó trả lại phản hồi thích hợp. Nó được trang trí bằng@Get(
'
posts
'
)
.getPost()
: Điều này nhậnpostID
làm tham số và tìm nạp một bài đăng từ database . Ngoài tham sốpostID
được truyền cho phương thức này, bạn nhận ra việc bổ sung một phương thức bổ sung có tên làValidateObjectId()
. Phương pháp này thực hiện cácPipeTransform
giao diện từ Nest.js. Mục đích của nó là xác thực và đảm bảo tham sốpostID
có thể được tìm thấy trong database . Bạn sẽ định nghĩa phương pháp này trong phần tiếp theo.addPost()
: Phương thức này sẽ xử lý một yêu cầu POST HTTP để thêm một bài đăng mới vào database .
Để có thể chỉnh sửa và xóa một bài đăng cụ thể, bạn cần thêm hai phương pháp nữa vào file blog.controller.ts
. Để làm điều đó, hãy bao gồm các phương thức editPost()
và deletePost()
sau ngay sau phương thức addPost()
mà trước đó bạn đã thêm vào 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 }) } }
Ở đây bạn đã thêm:
editPost()
: Phương thức này chấp nhận một tham số truy vấn củapostID
và sẽ thực hiện chức năng cập nhật một bài đăng. Nó cũng sử dụng phương thứcValidateObjectId
để cung cấp xác thực thích hợp cho bài đăng mà bạn cần chỉnh sửa.deletePost()
: Phương thức này sẽ chấp nhận một tham số truy vấn củapostID
và sẽ xóa một bài đăng cụ thể khỏi database .
Tương tự với BlogController
, mỗi phương thức không đồng bộ mà bạn đã xác định ở đây đều có trình trang trí metadata và nhận tiền tố mà Nest.js sử dụng làm cơ chế định tuyến. Nó kiểm soát bộ điều khiển nào nhận được yêu cầu nào và trỏ đến các phương thức sẽ xử lý yêu cầu và trả về phản hồi tương ứng.
Ví dụ: BlogController
mà bạn đã tạo trong phần này có tiền tố là blog
và một phương thức có tên getPosts()
nhận tiền tố của posts
. Điều này nghĩa là bất kỳ yêu cầu GET nào được gửi đến điểm cuối của blog/posts
( http:localhost:3000/blog/posts
) sẽ được xử lý bởi phương thức getPosts()
. Ví dụ này tương tự như cách các phương thức khác sẽ xử lý các yêu cầu HTTP.
Lưu và thoát khỏi file .
Để có file blog.controller.ts
hoàn chỉnh, hãy truy cập kho lưu trữ Cộng đồng DO cho ứng dụng này.
Trong phần này, bạn đã tạo một module để giữ cho ứng dụng có tổ chức hơn. Bạn cũng đã tạo một dịch vụ để xử lý logic nghiệp vụ cho ứng dụng bằng cách tương tác với database và trả về phản hồi thích hợp. Cuối cùng, bạn đã tạo bộ điều khiển và tạo các phương thức cần thiết để xử lý các yêu cầu HTTP như GET
, POST
, PUT
và DELETE
từ phía client . Trong bước tiếp theo, bạn sẽ hoàn thành cài đặt back-end của bạn .
Bước 5 - Tạo thêm xác thực cho Mongoose
Bạn có thể xác định từng bài đăng trong ứng dụng blog của bạn bằng một ID duy nhất, còn gọi là PostID
. Điều này nghĩa là việc tìm nạp một bài đăng sẽ yêu cầu bạn chuyển ID này làm tham số truy vấn. Để xác thực tham số postID
này và đảm bảo bài đăng có sẵn trong database , bạn cần tạo một hàm có thể sử dụng lại có thể được khởi tạo từ bất kỳ phương thức nào trong BlogController
.
Để cấu hình điều này, hãy chuyển đến folder ./src/blog
:
- cd ./src/blog/
Sau đó, tạo một folder mới có tên là shared
:
- mkdir -p shared/pipes
Trong folder pipes
, bằng cách sử dụng editor của bạn, hãy tạo một file mới có tên là validate-object-id.pipes.ts
và mở nó. Thêm nội dung sau để xác định dữ liệu postID
được chấp nhận:
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; } }
Lớp ValidateObjectId()
triển khai phương thức PipeTransform
từ @nestjs/common
module @nestjs/common
. Nó có một phương thức duy nhất có tên là transform()
nhận giá trị làm tham số - trong trường hợp này là postID
. Với phương pháp trên, bất kỳ yêu cầu HTTP nào từ giao diện user của ứng dụng này có postID
không thể tìm thấy trong database sẽ được coi là không hợp lệ. Lưu và đóng file .
Sau khi tạo cả dịch vụ và bộ điều khiển, bạn cần cài đặt mô hình Post
dựa trên BlogSchema
. Cấu hình này có thể được cài đặt trong ApplicationModule
root , nhưng trong trường hợp này, việc xây dựng mô hình trong BlogModule
sẽ duy trì tổ chức ứng dụng của bạn. Mở ./src/blog/blog.module.ts
và cập nhật nó với các dòng được đánh dấu sau:
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 { }
Mô-đun này sử dụng phương thức MongooseModule.forFeature()
để xác định mô hình nào nên được đăng ký trong module . Nếu không có này, chích PostModel
trong BlogService
sử dụng @injectModel()
trang trí sẽ không làm việc. Lưu file khi bạn đã hoàn tất việc thêm nội dung.
Trong bước này, bạn đã tạo API RESTful backend hoàn chỉnh với Nest.js và tích hợp nó với MongoDB. Trong phần tiếp theo, bạn sẽ cấu hình server để cho phép các yêu cầu HTTP từ một server khác, vì ứng dụng giao diện user của bạn sẽ chạy trên một cổng khác.
Bước 6 - Bật CORS
Yêu cầu HTTP từ domain này sang domain khác thường bị chặn theo mặc định, ngoại trừ khi được server chỉ định để cho phép. Để ứng dụng front-end của bạn thực hiện yêu cầu tới server back-end, bạn phải bật Chia sẻ tài nguyên nguồn root chéo (CORS), đây là một kỹ thuật cho phép yêu cầu các tài nguyên bị hạn chế trên một trang web.
Trong Nest.js để bật CORS, bạn cần thêm một phương thức duy nhất vào file main.ts
của bạn . Mở file này trong editor của bạn, có tại ./src/main.ts
và cập nhật file với nội dung được đánh dấu sau:
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();
Lưu và thoát khỏi file .
Đến đây bạn đã hoàn thành cài đặt back-end, bạn sẽ chuyển trọng tâm của bạn sang frontend và sử dụng Vue.js để sử dụng các API được xây dựng cho đến nay.
Bước 7 - Tạo giao diện user Vue.js
Trong phần này, bạn sẽ tạo ứng dụng giao diện user của bạn với Vue.js. Vue CLI là một công cụ tiêu chuẩn cho phép bạn nhanh chóng tạo và cài đặt một dự án Vue.js mới mà không gặp nhiều rắc rối.
Để bắt đầu, trước tiên bạn cần cài đặt Vue CLI global trên máy của bạn . Mở một terminal khác và thay vì làm việc từ folder blog-backend
, hãy chuyển đến folder phát triển dự án local của bạn và chạy:
- npm install -g @vue/cli
Khi quá trình cài đặt hoàn tất, bạn sẽ sử dụng lệnh vue
để tạo một dự án Vue.js mới:
- vue create blog-frontend
Bạn sẽ thấy một dấu nhắc ngắn sau khi nhập lệnh này. Chọn manually select features
tùy chọn, và sau đó chọn tính năng mà bạn cần cho dự án này bằng cách nhấn SPACE
trên máy tính của bạn để làm nổi bật nhiều tính năng. Bạn sẽ chọn Babel
, Router
và Linter / Formatter
.
Đối với các hướng dẫn tiếp theo, hãy nhập y
để sử dụng chế độ lịch sử cho bộ định tuyến; điều này sẽ đảm bảo chế độ lịch sử được bật trong file bộ định tuyến, chế độ này sẽ tự động tạo cho dự án này. Ngoài ra, chọn ESLint with error prevention only
để chọn cấu hình linter / formatter. Tiếp theo, chọn Lint on save
cho các tính năng bổ sung của Lint. Sau đó, chọn lưu cấu hình của bạn trong một dedicated config file
cho các dự án trong tương lai. vueconfig
tên cho cài đặt trước của bạn, như vueconfig
.
Sau đó, Vue.js sẽ bắt đầu tạo ứng dụng và tất cả các phụ thuộc của nó trong một folder có tên blog-frontend
.
Khi quá trình cài đặt hoàn tất, hãy chuyển bên trong ứng dụng Vue.js:
- cd blog-frontend
Sau đó, khởi động server phát triển với:
- npm run serve
Ứng dụng của bạn sẽ chạy trên http://localhost:8080
.
Vì bạn sẽ thực hiện các yêu cầu HTTP trong ứng dụng này, bạn cần cài đặt Axios, là một ứng dụng HTTP dựa trên lời hứa cho trình duyệt. Bạn sẽ sử dụng Axios tại đây để thực hiện các yêu cầu HTTP từ các thành phần khác nhau trong ứng dụng. Dừng ứng dụng giao diện user bằng cách nhấn CTRL + C
từ terminal trên máy tính của bạn, sau đó chạy lệnh sau:
- npm install axios --save
Ứng dụng front-end của bạn sẽ thực hiện lệnh gọi API tới API back-end trên một domain cụ thể từ các thành phần khác nhau trong ứng dụng. Để đảm bảo cấu trúc phù hợp cho ứng dụng này, bạn có thể tạo file helper
và xác định baseURL
server .
Để bắt đầu, từ terminal của bạn vẫn nằm trong blog-frontend
, hãy chuyển đến folder ./src/
:
- cd ./src/
Tạo một folder khác có tên utils
:
- mkdir utils
Trong folder utils
, sử dụng editor của bạn, hãy tạo một file mới có tên helper.js
và mở nó. Thêm nội dung sau để xác định baseURL
cho dự án Nest.js back-end:
export const server = { baseURL: 'http://localhost:3000' }
Bằng cách xác định baseURL
, bạn có thể gọi nó từ bất kỳ đâu trong các file thành phần Vue.js của bạn. Trong trường hợp bạn cần thay đổi URL, quá trình cập nhật baseURL
trong file này sẽ dễ dàng hơn thay vì trên ứng dụng của bạn.
Trong phần này, bạn đã cài đặt Vue CLI, một công cụ để tạo ứng dụng Vue.js mới. Bạn đã sử dụng công cụ này để tạo ứng dụng blog-frontend
. Ngoài ra, bạn đã chạy ứng dụng và cài đặt một thư viện có tên Axios, bạn sẽ sử dụng thư viện này khi nào có cuộc gọi HTTP trong ứng dụng. Tiếp theo, bạn sẽ tạo các thành phần cho ứng dụng.
Bước 8 - Tạo các thành phần có thể tái sử dụng
Đến đây bạn sẽ tạo các thành phần có thể sử dụng lại cho ứng dụng của bạn , đây là cấu trúc tiêu chuẩn cho các ứng dụng Vue.js. Hệ thống thành phần trong Vue.js giúp các nhà phát triển có thể xây dựng một đơn vị duy nhất, độc lập của một giao diện có thể có trạng thái, đánh dấu và phong cách riêng. Điều này làm cho các thành phần trong Vue.js có thể sử dụng lại được.
Mỗi thành phần Vue.js chứa ba phần khác nhau:
<template>
: chứa nội dung HTML<script>
: chứa tất cả logic giao diện user cơ bản và xác định các chức năng<style>
: biểu định kiểu cho từng thành phần riêng biệt
Đầu tiên, bạn sẽ bắt đầu bằng cách tạo một thành phần để tạo một bài đăng mới. Để làm điều đó, hãy tạo một folder mới có tên post
trong folder ./src/components
, folder này sẽ chứa các thành phần có thể tái sử dụng cần thiết cho các bài đăng. Sau đó, sử dụng editor của bạn, bên trong folder post
mới được tạo, tạo một file khác và đặt tên là Create.vue
. Mở file mới và thêm mã sau, mã này chứa các trường đầu vào cần thiết để gửi bài đăng:
<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>
Đây là phần <template>
của thành phần CreatePost
. Nó chứa các yếu tố đầu vào HTML cần thiết để tạo một bài đăng mới. Mỗi trường đầu vào có một chỉ thị v-model
như một thuộc tính đầu vào. Điều này nhằm đảm bảo ràng buộc dữ liệu hai chiều trên mỗi đầu vào biểu mẫu để giúp Vue.js dễ dàng lấy được đầu vào của user .
Tiếp theo, thêm phần <script>
vào cùng một file ngay sau nội dung trước:
... <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>
Ở đây, bạn đã thêm một phương thức có tên createPost()
để tạo một bài đăng mới và gửi nó đến server bằng Axios. Sau khi user tạo một bài đăng mới, ứng dụng sẽ chuyển hướng trở lại trang chủ, nơi user có thể xem danh sách các bài viết đã tạo.
Bạn sẽ cấu hình vue-router để thực hiện chuyển hướng sau trong hướng dẫn này.
Lưu file khi bạn hoàn tất chỉnh sửa. Để có file Create.vue
hoàn chỉnh, hãy truy cập kho lưu trữ Cộng đồng DO cho ứng dụng này.
Bây giờ, bạn cần tạo một thành phần khác để chỉnh sửa một bài đăng cụ thể. Điều hướng đến folder ./src/components/post
và tạo một file khác và đặt tên là Edit.vue
. Thêm mã sau có chứa phần <template>
vào nó:
<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>
Phần mẫu này chứa nội dung tương tự như thành phần CreatePost()
; sự khác biệt duy nhất là nó chứa các chi tiết của bài đăng cụ thể cần được chỉnh sửa.
Tiếp theo, thêm phần <script>
ngay sau phần </template>
trong 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>
Tại đây, bạn đã có được id
tham số tuyến đường để xác định một bài đăng cụ thể. Sau đó, bạn tạo một phương thức có tên getPost()
để lấy chi tiết của bài đăng này từ database và cập nhật trang với nó. Cuối cùng, bạn đã tạo một phương thức editPost()
để gửi bài đã chỉnh sửa trở lại server back-end với một yêu cầu PUT HTTP.
Lưu và thoát khỏi file . Để có file Edit.vue
hoàn chỉnh, hãy truy cập kho lưu trữ Cộng đồng DO cho ứng dụng này.
Bây giờ, bạn sẽ tạo một thành phần mới trong folder ./src/components/post
và đặt tên là Post.vue
. Điều này sẽ cho phép bạn xem chi tiết của một bài đăng cụ thể từ trang chủ. Thêm nội dung sau vào 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>
Mã này làm cho các chi tiết của một bài đăng trong đó bao gồm, title
, author
, và bài body
.
Bây giờ, ngay sau </template>
, hãy thêm mã sau vào file :
... <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>
Tương tự như phần <script>
của thành phần bài đăng chỉnh sửa, bạn có được id
tham số tuyến đường và sử dụng nó để truy xuất chi tiết của một bài đăng cụ thể.
Lưu file khi bạn hoàn tất việc thêm nội dung. Để có file Post.vue
hoàn chỉnh, hãy truy cập kho lưu trữ Cộng đồng DO cho ứng dụng này.
Tiếp theo, để hiển thị tất cả các bài viết đã tạo cho user , bạn sẽ tạo một thành phần mới. Nếu bạn chuyển đến folder views
trong src/views
, bạn sẽ thấy một thành phần Home.vue
- nếu file này không có mặt, hãy sử dụng editor của bạn để tạo nó, thêm mã sau:
<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>
Tại đây, trong phần <template>
, bạn đã sử dụng <router-link>
để tạo liên kết để chỉnh sửa cũng như xem bài đăng bằng cách chuyển post._id
làm tham số truy vấn. Bạn cũng đã sử dụng lệnh v-if
để hiển thị có điều kiện bài đăng cho user . Nếu không có bài đăng nào từ database , user sẽ chỉ thấy dòng chữ này: Không tìm thấy bài đăng nào vào lúc này .
Lưu và thoát khỏi file . Để có file Home.vue
hoàn chỉnh, hãy truy cập kho lưu trữ Cộng đồng DO cho ứng dụng này.
Bây giờ, ngay sau phần </template>
trong Home.vue
, thêm phần </script>
sau:
... <script> // @ is an alias to /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>
Trong phần <script>
của file này, bạn đã tạo một phương thức có tên fetchPosts()
để tìm nạp tất cả các bài đăng từ database và bạn đã cập nhật trang với dữ liệu được trả về từ server .
Bây giờ, bạn sẽ cập nhật thành phần App
giao diện user để tạo liên kết đến Home
và thành phần Create
. Mở src/App.vue
và cập nhật nó như sau:
<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>
Ngoài việc bao gồm các liên kết đến cả Thành phần Home
và Create
, bạn cũng bao gồm phần <Style>
, là biểu định kiểu cho thành phần này và giữ định nghĩa về kiểu cho một số phần tử trên trang. Lưu và thoát khỏi file .
Bạn đã tạo tất cả các thành phần cần thiết cho ứng dụng của bạn trong bước này. Tiếp theo, bạn sẽ cấu hình file bộ định tuyến.
Bước 9 - Cài đặt định tuyến
Sau khi tạo tất cả các thành phần có thể sử dụng lại cần thiết, bây giờ bạn có thể cấu hình đúng cách file bộ định tuyến bằng cách cập nhật nội dung của nó bằng các liên kết đến tất cả các thành phần bạn đã tạo. Điều này sẽ đảm bảo tất cả các điểm cuối trong ứng dụng front-end đều được ánh xạ tới một thành phần cụ thể để có hành động thích hợp. Điều hướng đến ./src/router.js
và thay thế nội dung của nó bằng nội dung sau:
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 } ] });
Bạn đã nhập Router
từ module vue-router
và khởi tạo nó bằng cách chuyển các tham số mode
và định routes
. Chế độ mặc định cho vue-router
là chế độ băm, sử dụng băm URL để mô phỏng một URL đầy đủ để trang không bị reload khi URL thay đổi. Để làm cho hàm băm không cần thiết, bạn đã sử dụng chế độ lịch sử ở đây để chuyển URL mà không cần reload trang. Cuối cùng, trong tùy chọn routes
, bạn đã chỉ định đường dẫn cho điểm cuối - tên cho tuyến đường và thành phần sẽ được hiển thị khi tuyến đường được gọi trong ứng dụng. Lưu và thoát khỏi file .
Đến đây bạn đã cài đặt định tuyến đến ứng dụng, bạn cần bao gồm file Bootstrap để giúp tạo kiểu được tạo sẵn cho giao diện user của ứng dụng. Để đạt được điều đó, hãy mở file ./public/index.html
trong editor của bạn và bao gồm file CDN cho Bootstrap bằng cách thêm nội dung sau vào file :
<!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>
Lưu và thoát khỏi file , sau đó khởi động lại ứng dụng với npm run serve
cho blog-frontend
của bạn, nếu nó hiện không chạy.
Lưu ý: Đảm bảo rằng cả server back-end và version MongoDB cũng đang chạy. Nếu không, hãy chuyển đến phần blog-backend
từ một terminal khác và chạy npm run start
. Ngoài ra, hãy bắt đầu dịch vụ MongoDB bằng cách chạy sudo mongod
từ một terminal mới.
Điều hướng đến ứng dụng của bạn tại: http://localhost:8080
. Đến đây bạn có thể kiểm tra blog của bạn bằng cách tạo và chỉnh sửa các bài đăng.
Nhấp vào Tạo trên ứng dụng của bạn để xem màn hình Tạo bài đăng , liên quan đến và hiển thị file CreateComponent
. Nhập giá trị vào các trường đầu vào và nhấp vào nút Tạo bài đăng để gửi bài đăng. Sau khi bạn hoàn tất, ứng dụng sẽ chuyển hướng bạn trở lại trang chủ.
Trang chủ của ứng dụng hiển thị HomeComponent
. Thành phần này có một phương thức gửi lệnh gọi HTTP để tìm nạp tất cả các bài đăng từ database và hiển thị chúng cho user .
Nhấp vào nút Chỉnh sửa bài đăng cho một bài đăng cụ thể sẽ đưa bạn đến trang chỉnh sửa nơi bạn có thể kết hợp bất kỳ thay đổi nào và lưu bài đăng của bạn .
Trong phần này, bạn đã cấu hình và cài đặt định tuyến cho ứng dụng. Với điều này tại chỗ, ứng dụng blog của bạn đã sẵn sàng.
Kết luận
Trong hướng dẫn này, bạn đã khám phá một cách mới để cấu trúc ứng dụng Node.js bằng cách sử dụng Nest.js. Bạn đã tạo một ứng dụng blog đơn giản bằng Nest.js để xây dựng API RESTful mặt sau và sử dụng Vue.js để xử lý tất cả logic giao diện user . Hơn nữa, bạn cũng đã tích hợp MongoDB làm database cho ứng dụng Nest.js của bạn .
Để tìm hiểu thêm về cách thêm xác thực vào ứng dụng của bạn, bạn có thể sử dụng Passport.js , một thư viện xác thực Node.js phổ biến. Bạn có thể tìm hiểu về tích hợp Passport.js trong tài liệu Nest.js.
Bạn có thể tìm thấy mã nguồn hoàn chỉnh cho dự án này tại đây trên GitHub . Để biết thêm thông tin về Nest.js, bạn có thể truy cập tài liệu chính thức .
Các tin liên quan