NestJS 搭建博客系统(二)— 编写静态文章CURD
前言
根据上一篇NestJS 搭建博客系统(一)— 搭建框架我们已经准备好了NestJS的基本框架,并且也熟悉了一些基本的概念,那么现在就开始填充我们的第一个功能吧。
简介
本篇将通过一个简单的例子来熟悉 NestJS 里 Controller 和 Service 的基本用法。
编写代码
创建模块
使用 Nest CLI 可以快速帮助我们新建相应的文件
在终端输入 nest -h
name | alias | description |
---|---|---|
application | application | Generate a new application workspace |
class | cl | Generate a new class |
configuration | config | Generate a CLI configuration file |
controller | co | Generate a controller declaration |
decorator | d | Generate a custom decorator |
filter | f | Generate a filter declaration |
gateway | ga | Generate a gateway declaration |
guard | gu | Generate a guard declaration |
interceptor | in | Generate an interceptor declaration |
interface | interface | Generate an interface |
middleware | mi | Generate a middleware declaration |
module | mo | Generate a module declaration |
pipe | pi | Generate a pipe declaration |
provider | pr | Generate a provider declaration |
resolver | r | Generate a GraphQL resolver declaration |
service | s | Generate a service declaration |
library | lib | Generate a new library within a monorepo |
sub-app | app | Generate a new application within a monorepo |
resource | res | Generate a new CRUD resource |
新建一个 article 模块,依次在命令行输入
nest g mo modules/article # 创建模块
nest g s modules/article # 创建服务
nest g co modules/article # 创建控制器
复制代码
此时我们的代码结构为
.
├── README.md
├── nest-cli.json
├── package.json
├── src
│ ├── app.controller.spec.ts
│ ├── app.controller.ts
│ ├── app.module.ts
│ ├── app.service.ts
│ ├── filters
│ ├── main.ts
│ └── modules # 新增
│ └── article
│ ├── article.controller.spec.ts
│ ├── article.controller.ts
│ ├── article.module.ts
│ ├── article.service.spec.ts
│ └── article.service.ts
├── test
│ ├── app.e2e-spec.ts
│ └── jest-e2e.json
├── tsconfig.build.json
├── tsconfig.json
└── yarn.lock
复制代码
Nest CLI 会帮我们自动在 article.module 引入 article.controller 和 article.service,并在 app.module 引入 article.module
看起来就像这样
main: {
app.module: {
app.controller
app.service
article.module: {
article.controller
article.service
}
}
}
复制代码
编写路由
在 article.controller 中编写路由
// src/modules/article/article.controller.ts
import { Body, Controller, Get, Post, Query } from '@nestjs/common';
import { ArticleService } from './article.service';
import { Article } from './interface/article.interace';
@Controller('article')
export class ArticleController {
constructor(
private articleService: ArticleService
) {}
@Get('list')
getMore() {
return '文章列表'
}
@Get('info')
getOne(
@Query() id:string
) {
return '文章详情'
}
@Post('create')
create(
@Body() article: Article
) {
return '创建文章'
}
@Post('edit')
update(
@Body() article: Article
) {
return '编辑文章'
}
@Post('remove')
delete(
@Body() id: number
) {
return '删除文章'
}
}
复制代码
当然,NestJS 提供标准 Http 方法的装饰器,你也可以这样子
// src/modules/article/article.controller.ts
import { Body, Controller, Get, Post, Query } from '@nestjs/common';
import { ArticleService } from './article.service';
import { Article } from './interface/article.interace';
@Controller('article')
export class ArticleController {
constructor(
private articleService: ArticleService
) {}
@Get()
getMore() {
return '文章列表'
}
@Get(':id')
getOne(
@Query() id:string
) {
return '文章详情'
}
@Post(':id')
create(
@Body() article: Article
) {
return '创建文章'
}
@Put(':id')
update(
@Body() article: Article
) {
return '编辑文章'
}
@Delete(':id')
delete() {
return '删除文章'
}
}
复制代码
Nest 提供相当丰富的装饰器可供使用,详细可以看考控制器
我这里为了简单,只选择了 Get、Post 两种请求方式
编写服务
现在我们只有路由,请求 localhost:3000/article/list
只会返回简单的文章列表几个字符串。所以我们需要编写服务,也就是这样
控制器(路由) -> 提供者(服务)
在编写服务前,我们先定义一下文章的字段结构,这里采用
创建 src/modules/article/interface/article.interface.ts
export interface Article {
id?: '', // id
title: '', // 标题
description: '', // 描述
content: '', // content
createTime?: '', // 创建时间
updateTime?: '', // 更新时间
isDelete?: '', // 是否删除
}
复制代码
定义完文章的字段结构就可以开始编写服务了
// src/modules/article/article.service.ts
import { Injectable } from '@nestjs/common';
import { Article } from './interface/article.interace';
@Injectable()
export class ArticleService {
list: any[]; // 存放临时数据
constructor() {
this.list = []
}
// 获取列表
getMore() {
return this.list.filter(item => !item.isDelete)
}
// 获取单条
getOne({ id }) {
const item = this.list.filter(item => {
return item.id === id
})[0]
if (item) {
return item
}
return '找不到文章'
}
// 创建文章
create(
article: Article
) {
const id = this.list.length
const item = {
id,
...article
}
this.list.push(item)
}
// 更新文章
update(
article: Article
) {
let idx = 0
const item = this.list.filter((item, i) => {
if (item.id === article.id) {
idx = i
}
return item.id === article.id
})
if (!item) {
return '找不到文章'
}
const nItem = {
...item,
...article,
}
this.list.splice(idx, 1, nItem)
}
// 删除文章
delete({ id }) {
let idx = 0
const item = this.list.filter((item, i) => {
if (item.id === id) {
idx = i
}
return item.id === id
})
if (!item) {
return '找不到文章'
}
const nItem = {
...item,
isDelete: true,
}
this.list.splice(idx, 1, nItem)
}
}
复制代码
改写一下我们的控制器, 把路由和服务对应起来
import { Body, Controller, Get, Post, Query } from '@nestjs/common';
import { ArticleService } from './article.service';
import { Article } from './interface/article.interace';
@Controller('article')
export class ArticleController {
constructor(
private articleService: ArticleService
) {}
@Get('list')
getMore() {
return this.articleService.getMore()
}
@Get('info')
getOne(
@Query() id:string
) {
return this.articleService.getOne({ id })
}
@Post('create')
create(
@Body() article: Article
) {
return this.articleService.create(article)
}
@Post('edit')
update(
@Body() article: Article
) {
return this.articleService.update(article)
}
@Post('remove')
delete(
@Body() id: number
) {
return this.articleService.delete({ id })
}
}
复制代码
这时我们就可以对文章进行增删改查操作了。
到这里,我们了解到了 nest 的基本的请求,但是数据是存放在变量list 里面的,也就是说,当我们重新启动服务后,数据将会丢失。
下一节,我们使用 TypeORM 和 mysql 实现数据持久化