差點就Miss掉MongoDB,這次沿用Day21專案,基本上專案架構大同小異,Sequelize、TypeORM和MongoDB,都只是換湯不換藥的去改寫一些地方而已。這次使用很夯的Mongoose模組作為串接MongoDB的模組,我們將Day21專案換成Mongoose模組的API,並且灌好MongoDB,並啟動MongoDB,database名稱IronManNest,collection名稱:Users。
npm install --save mongoose
npm install --save-dev @types/mongoose
'use strict';
import * as mongoose from 'mongoose';
export const databaseProviders = [
{
provide: 'MongoDBConnection',
useFactory: async (): Promise<mongoose.Connection> => {
(mongoose as any).Promise = global.Promise;
return await mongoose.connect('mongodb://localhost:27017/IronManNest', {
useMongoClient: true
})
}
}
]
先使用mongoose.connect()建立一下與MongoDB的連線,這會回傳MongooseThenable,再透過global.Promise 覆寫它,避免程式發出警告,實際上這也是一個非同步的Component。
import * as mongoose from 'mongoose';
export const UsersSchema = new mongoose.Schema(
{
Name: String,
Age: Number
},
{ collection: 'Users', versionKey: false },
)
'use strict';
import { Connection, connection } from 'mongoose';
import { UsersSchema } from './schemas/users.schema';
export const UsersProvider = [
{
provide: 'UsersRepository',
useFactory: (connection: Connection) => connection.model('Users', UsersSchema),
inject: ['MongoDBConnection']
}
]
'use strict';
import { Document } from 'mongoose';
export interface IUsers extends Document {
readonly _id: number;
readonly Name: string;
readonly Age: number;
}
import { ApiModelProperty } from '@nestjs/swagger';
export class CreateUsersDTO {
@ApiModelProperty()
readonly _id: number;
@ApiModelProperty()
readonly Name: string;
@ApiModelProperty()
readonly Age: number;
}
'use strict';
import { Users } from '../users.entity';
import { IUsers } from './IUsers';
export interface IUsersService {
findAll(): Promise<Array<IUsers>>;
findById(ID: number): Promise<IUsers | null>;
findOne(options: Object): Promise<IUsers | null>;
create(users: IUsers): Promise<IUsers>;
update(ID: number, newValue: IUsers): Promise<IUsers | null>;
delete(ID: number): Promise<number>;
}
'use strict';
import { Component, Inject } from '@nestjs/common';
import { IUsers, IUsersService } from './interfaces/index';
import { Model } from 'mongoose';
import { InjectRepository } from '@nestjs/typeorm';
import { CreateUsersDTO } from './DTO/createUsers.dto';
@Component()
export class UsersServices implements IUsersService{
constructor( @Inject('UsersRepository') private readonly usersRepository: Model<IUsers>) { }
public async findAll(): Promise<Array<IUsers>> {
return await this.usersRepository.find().exec();
}
//findOne()可以加入各種option,以下示範常見的where
//注意findOne() 找到一筆就會立即return data,不會繼續往下找。
public async findOne(options: Object): Promise<IUsers | null> {
return await this.usersRepository.findOne(options).exec();
}
//restful API很常用。
public async findById(_id): Promise<IUsers | null> {
return await this.usersRepository.findById(_id).exec();
}
public async create(users: CreateUsersDTO): Promise<IUsers> {
return await this.usersRepository.create(users);
}
public async update(_id: number, newValue: IUsers): Promise<IUsers | null> {
//先找出單筆資料
let user = await this.usersRepository.findById(_id).exec();
//該筆資料不存在
if (!user._id) {
console.error("user doesn't exist");
}
//呼叫user Model的方法
await this.usersRepository.findByIdAndUpdate(_id, newValue).exec();
return await this.usersRepository.findById(_id).exec();
}
public async delete(_id: number): Promise<number> {
//成功會回傳1,失敗回傳0
await this.usersRepository.findByIdAndRemove(_id).exec();
let user = await this.usersRepository.findById(_id).exec();
if (!user) {
//刪除成功
return 1;
}
else {
//刪除失敗
return 0;
}
}
}
Sequelize、TypeORM、Mongoose的API大致都長得很像,使用起來也差不多,學一套再學另一套還蠻快的。
'use strict';
import { Module } from '@nestjs/common';
import { UsersServices } from '../users.service';
import { UsersProvider } from '../users.providers';
import { DatabaseModule } from '../../database.module';
import { UsersController } from './users.controller';
@Module({
modules: [DatabaseModule],
controllers: [UsersController],
components: [
UsersServices,
...UsersProvider
]
})
export class UsersModule { }
似乎一定要用擴展運算符把UsersProvider這陣列展開才不會噴錯。
查詢全部資料
對http://localhost:3000/users 做GET請求。
查詢單筆資料
對http://localhost:3000/users/5a4115c23fb3a94ff4d7d614 做GET請求。
修改單筆資料
對http://localhost:3000/users/5a4115c23fb3a94ff4d7d614 做PATCH請求。
刪除單筆資料
對http://localhost:3000/users/5a4115c23fb3a94ff4d7d614 做DELETE請求。
對MongoDB的CRUD都正常運作了!
程式碼都在github