Node 使用 Egg 框架 之 上TS 的教程(一)
阿新 • • 發佈:2019-12-31
Node + Egg + TS + Mongodb + Resetful
-
作為一個從優美的、面向物件的、專業的:C、C++、C#、JAVA一路過來的程式設計師,開始讓我寫JS,我是拒絕的。這哪裡是在寫程式碼,明明是在寫 console.log() 啊!!! 連少個引數、引數型別不對都不告訴我,我太難了。
-
我那祖傳的:面向物件 和 23種設計模式,在這JS的程式碼中失去了靈魂。
-
順便說句: async 和 await 真香。
-
網上的教程都是egg少部分的結合,沒有真正的做到俺們這篇的強。廢話不多說,開始!
老規矩,本地教程的地址為:github.com/liangwei010…
執行環境: Node ,Yarn/NPM,MongoDB
egg為node.js的一個框架,用起來還是挺簡單的,大夥看看就會了。
Node + egg + ts + Mongodb 示例
目錄結構
egg-demo
├── app
│ ├── controller (前端的請求會到這裡來!)
│ │ └── home.ts
│ ├── model(資料庫表結構抽象出來的模型)
│ │ └── User.ts
│ ├── service(controller 層不建議承載過多的業務,業務重時放在service層)
│ │ └── user.ts
│ └── router.ts (Url的相關對映)
├── config (框架的配置檔案)
│ ├── config.default.ts
│ ├── config.local.ts
│ ├── config.prod.ts
│ └── plugin.ts
├── test (測試資料夾)
│ └── **/*.test.ts
├── typings (目錄用於放置 d.ts 檔案)
│ └── **/*.d.ts
├── README.md
├── package.json
├── tsconfig.json
└── tslint.json
複製程式碼
配置
demo配置了兩處地方:
- 資料庫
config.mongoose = {
url: process.env.EGG_MONGODB_URL || 'mongodb://127.0.0.1/egg-demo',options: {},};
複製程式碼
- csrf(先關閉,要不然post報錯)
config.security = {
csrf: {
enable : false,},};
複製程式碼
router
對於resetful風格的介面來說,用http的關鍵字來標識動作,用名詞來標識資源。已user為例子: 對於請求 '/user'的請求,在下方程式碼的指定對映到對應的函式中。
router.get('/user',controller.home.getUser);
router.post('/user',controller.home.addUser);
router.put('/user',controller.home.updateUser);
router.delete('/user',controller.home.deleteUser);
複製程式碼
controller
這裡是請求對應的函式的類。
// 這裡是get('/user')的處理函式
public async getUser() {
const ctx = this;
// 這裡就是隨你怎麼來。可以資料庫查,或者別的。
const user = { ... };
// 返回的值
ctx.body = user;
}
// 下面類似,不再解釋了啊
public async addUser() {
const ctx = this;
// 模擬前端傳遞過來的資料(方便測試)
const user = new UserModel();
user.userName = 'add user';
user.userNo = 99;
const res = await ctx.model.User.create(user);
ctx.body = res;
}
public async deleteUser() {
const ctx = this;
const user = new UserModel();
user.userNo = 99;
const res = await UserModel.findOneAndRemove({ userNo: user.userNo });
ctx.body = res;
}
複製程式碼
service層
這裡沒有啥講的,就是一些業務性的東西放這裡,讓被controller或者其他service呼叫。
/**
* sayHi to you
* @param name - your name
*/
public async sayHi(name: string) {
return `hi,${name}`;
}
複製程式碼
Model (畫重點,用mongodb的注意啦)
- 首先我們建立一個Schema
/**
* 定義一個User的Schema
*/
const UserSchema: Schema = new Schema({
userNo: {
type: Number,index: true,userName: String,{
timestamps: true,);
複製程式碼
- 索引
// userNo 為索引
UserSchema.index({ userNo: 1,});
複製程式碼
- 例項方法和靜態方法
// UserSchema的例項方法
UserSchema.methods.userInstanceTestMethods = function () {
const user: IUser = new UserModel();
user.userName = '我是例項化方法測試';
user.userNo = 9527;
return user;
};
// UserSchema的例項方法
UserSchema.statics.userStaticTestMethods = function () {
const user: IUser = new UserModel();
user.userName = '我是靜態方法測試';
user.userNo = 9528;
return user;
};
複製程式碼
- 建立User介面欄位
/**
* 使用者欄位介面
*/
export interface IUser {
userNo: number;
userName: string;
}
複製程式碼
- 例項方法和靜態方法介面的定義,注意:這裡的介面要和Schema中定義的函式的名稱和返回值一致。
export interface IUserDocument extends IUser,Document {
/**
* 例項方法介面(名稱需要和Schema的方法名一樣)
*/
userInstanceTestMethods: () => IUser;
}
/**
* 靜態方法介面
*/
export interface IUserModel extends Model<IUserDocument> {
/**
* 靜態方法
*/
userStaticTestMethods: () => IUser;
}
複製程式碼
- 匯出model即可。
export const UserModel = model<IUserDocument,IUserModel>('User',UserSchema);
複製程式碼
- 為了怕有需求使用到ctx.model.User,我們需要將UserSchema掛載到ctx中
// egg-mongoose注入
export default (app: Application) => {
const mongoose = app.mongoose;
// 這裡為了掛載到ctx中,讓正常ctx.model.User也能使用
mongoose.model<IUserDocument,UserSchema);
};
複製程式碼
使用Model
使用mode能使用IUser欄位介面,例項方法,靜態方法。
// 這裡的user是: IUser的型別。然後就能盡情的點點點啦!
const user = await UserModel.findOne();
// 等價於
const users = await this.ctx.model.User.find();
// 例項方法
const newUser = new UserModel();
newUser.userInstanceTestMethods();
// 靜態方法
UserModel.userStaticTestMethods();
複製程式碼
最後,單元測試!!!
可能很多人覺得單元測試不寫就不寫,寫了浪費時間。但是等你發現你要重構的時候,沒有足夠的單元測試的時候,你會覺得,什麼鬼,不敢動啊!!!所以,我覺得還是要寫單元測試,這個東西是費點時間,但是後期好啊。
test/app/controller/home.test.ts
√ should GET / (49ms)
√ addUser (39ms)
√ getUser
√ getUsers
√ updateUser
√ deleteUser
√ testStaticMethods
√ testInstanceFunction
test/app/service/Test.test.js
√ sayHi
√ testUserInstanceServiceMethods
√ testUserInstanceServiceMethods
11 passing (4s)
複製程式碼
看見他打綠色的 √ √ 我就很開心。
今天有點晚了,後面給大家寫:定時任務,GraphQL,redis,部署等內容。