Node 使用 Egg 框架 之 上TS 的教程(四)

Node + Egg + TS + typegoose + Resetful + schedule + type-graphql+ websocket
psc.jpg

在使用了之前教程的骨架代碼一段時候,有同學說,typegoose出新包,大改了?,F(xiàn)在寫法變化了很多。于是就有了這個 typegoose新包的骨架代碼教程。

本次教材地址:https://github.com/liangwei0101/egg-demo.git

版本:

  • node:v12.14.0
  • @typegoose/typegoose: 6.4.0

先對比下前后typegoose之前的寫法

  1. 引入的包不一樣了
// 之前是這樣寫的
import { index, prop, instanceMethod, staticMethod } from 'typegoose';

// 現(xiàn)在是這樣寫的
import { index, getModelForClass, prop } from '@typegoose/typegoose';
  1. 實例方法和之前不一樣了(簡潔了許多)
// 之前實例方法是加注解就好了
export default class User extends Typegoose {
  @instanceMethod
  public async userInstanceTestMethods(this: InstanceType<User>) {

  }
}

// 現(xiàn)在直接寫就好了不用注解
export default class User extends Typegoose {
  public async userInstanceTestMethods() {

  }
}
  1. 靜態(tài)方法和之前不一樣了(簡潔了許多)
// 之前靜態(tài)方法是加注解就好了
export default class User extends Typegoose {
  @staticMethod
  public async userStaticTestMethods(this: InstanceType<User>) {

  }
}

// 現(xiàn)在直接寫就好了不用注解
export default class User extends Typegoose {
  public static async userStaticTestMethods() {

  }
}
  1. 導出Model, 現(xiàn)在getModelForClass直接使用即可
// 之前是這樣寫的
export const UserModel = new User().getModelForClass(User);

// 現(xiàn)在是這樣寫的
export const UserModel = getModelForClass(User);
  1. buildSchema 函數(shù) (單元測試的ctx.model可能會需要)
// 從class 獲取 Schema
const TradeSchema = buildSchema(User);
// 如果需要Schema的話
export default (app: Application) => {
  const mongoose = app.mongoose;
  const UserSchema = buildSchema(Order);
  UserSchema.loadClass(OrderClass);
  return mongoose.model('Order', UserSchema);
}

type-graphql 使用JSON類型

找了很久type-graphql使用any或者json的文檔或者例子,都是只支持type-graphql的基礎(chǔ)類型,和class類型。然后,就自己定義一個JSON類型吧。

  • GraphQLScalarType 自定義(我封裝了兩個,一個查詢用的,一個新增用的)
import { GraphQLScalarType } from "graphql";
// 自定義 名稱為JSON的類型
export const JosnScalar = new GraphQLScalarType({
  name: "JSON",
  description: "驗證 JSON 類型",
  parseValue(value: any) {
    if (Object.prototype.toString.call(value) !== '[object Object]') {
      throw new Error('親,參數(shù)不是一個對象呢!');
    }
    return value;
  },
  serialize(value: any) {
    return value;
  },
});
  • 使用自定義JSON類型例子一
// 輸入?yún)?shù)
@ArgsType()
export class DefaultMutation {

  @Field(() => JosnScalar, { nullable: true })
  data: any;
}
  
@Mutation(() => User, { description: '增加用戶' })
 async addUser(@Args() { data }: DefaultMutation, @Ctx() ctx: Context) {
   // 這里的 data 指向 DefaultMutation 屬性的data也就是any類型
   const user = await ctx.service.user.createUser(data);

   return user;
}

  • 使用自定義JSON類型例子二
@ArgsType()
export class DefaultQuery {

  @Field(() => JosnScalar, { nullable: true })
  filter: any;

  @Field(() => JosnScalar, { nullable: true })
  order: any;

  @Field(() => JosnScalar, { nullable: true })
  page: any;
}

 // 使用
 @Query(() => [User], { description: '查詢用戶列表' })
 async getUser(@Args() { filter, order, page }: DefaultQuery, @Ctx() ctx: Context) {
   return await ctx.service.user.filterUser(filter, order, page);
 }

egg中 mongoose 的 transaction

  • 提取公用函數(shù),封裝到上下文ctx中
// extend/context.ts
import { Context } from 'egg';

export default {
  // 獲取session,回滾事務
  async getSession(this: Context) {
    // Start a session.
    const session = await this.app.mongoose.startSession();
    // Start a transaction
    // 這里因為獲取到的session也是要startTransaction,所以,就一并在這寫掉
    session.startTransaction();
    return session
  }
}

 /**
  * 測試事務
  */
  public async testErrorTransaction() {

    const session: any = await this.ctx.getSession();
    try {
      const user = new UserModel();
      user.userName = 'add user';
      user.userNo = 103;
      (await UserModel.create(user)).$session(session)

      // 沒有userNo將會報錯
      const user1 = new UserModel();
      (await UserModel.create(user)).$session(session)
      console.log(user1);

      // 提交事務
      await session.commitTransaction();
    } catch (err) {
      // 事務回滾
      await session.abortTransaction();
      throw err;
    } finally {
      await session.endSession();
    }
  }

這個骨架使用應該沒有啥問題啦,有啥問題歡迎大家指出。謝謝!別忘記給我點星星哦,再次謝謝啦!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容