比nestjs更優雅的ts控制反轉策略-依賴查詢

濮水大叔發表於2024-04-06

一、Cabloy5.0內測預告

Cabloy5.0採用TS對整個全棧框架進行了脫胎換骨般的大重構,並且提供了更加優雅的ts控制反轉策略,讓我們的業務開發更加快捷順暢

1. 新舊技術棧對比:

後端 前端
舊版 js、egg2.0、mysql js、vue2、framework7
新版 ts、egg3.0、多資料庫相容(支援mysql、postgresql) ts、vue3、quasar

2. 框架開發兩大趨勢

  1. TS化:這是顯而易見的趨勢,不必贅言

  2. ESM化:從目前趨勢看,前端框架已經全鏈路ESM化了,但是,大多數後端框架仍然是Commonjs。即便是egg3.0也仍然是Commonjs。由於egg的定位仍然是元框架,CabloyJS5.0在egg基礎上仍然開發出了全量ESM化的業務模組化系統(在Commonjs之上進行ESM化的具體機制是什麼,另有文章闡述)

二、比nestjs更優雅的ts控制反轉策略

基於TS的後端框架一般都會提供依賴容器,實現控制反轉。控制反轉有兩種策略:依賴注入依賴查詢。CabloyJS5.0同時支援依賴注入依賴查詢,並且透過模組範圍的輔助,讓依賴查詢的程式碼更加簡潔高效,下面挑幾個特性舉例說明:

  1. Service服務
  2. Config配置
  3. 多語言
  4. 錯誤異常

三、Service服務

1. 建立一個Service

在CabloyJS中,local bean相當於nestjs中service的概念,下面建立一個local bean

import { BeanBase, Local } from '@cabloy/core';
import { ScopeModule } from '../resource/this.js';

@Local()
export class LocalHome extends BeanBase<ScopeModule> {
  async echo({ user: _user }) {
    return `Hello World!`;
  }
}
  1. 透過@Local宣告LocalHome是一個local bean

  2. LocalHome繼承自基類BeanBase

2. Service的依賴注入

接下來,在Controller中採用依賴注入的方式來使用LocalHome

import { BeanBase, Controller, Use } from '@cabloy/core';
import { ScopeModule } from '../resource/this.js';
import { LocalHome } from '../local/home.js';

@Controller()
export class ControllerHome extends BeanBase<ScopeModule> {
  @Use()
  home: LocalHome;

  async echo() {
    const res = await this.home.echo({
      user: this.ctx.state.user.op,
    });
    this.ctx.success(res);
  }
}
  1. 使用@Use注入LocalHome

3. Service的依賴查詢

接下來,在Controller中採用依賴查詢的方式來使用LocalHome

import { BeanBase, Controller } from '@cabloy/core';
import { ScopeModule } from '../resource/this.js';

@Controller()
export class ControllerHome extends BeanBase<ScopeModule> {
  async echo() {
    const res = await this.scope.local.home.echo({
      user: this.ctx.state.user.op,
    });
    this.ctx.success(res);
  }
}
  1. 不需要匯入LocalHome,直接在程式碼中使用this.scope.local來訪問容器中的local bean例項

看一下動畫演示,提供了完整的型別智慧提示:

四、Config配置

1. 定義Config

可以為業務模組單獨定義一些Config配置,如下:

import { CabloyApplication } from '@cabloy/core';

export const config = (_app: CabloyApplication) => {
  return {
+   prompt: 'hello world',
  };
};

2. 使用Config

可以在LocalHome中直接使用剛才定義的config

import { BeanBase, Local } from '@cabloy/core';
import { ScopeModule } from '../resource/this.js';

@Local()
export class LocalHome extends BeanBase<ScopeModule> {
  async echo({ user: _user }) {
+   return this.scope.config.prompt;
-   return `Hello World!`;
  }
}
  1. 不需要匯入任何型別,直接在程式碼中使用this.scope.config來訪問當前業務模組中的config配置

看一下動畫演示,提供了完整的型別智慧提示:

五、多語言

1. 定義語言資源

可以為業務模組定義語言資源,比如,這裡分別定義英文和中文兩種語言資源

英文

export default {
  HelloWorld: 'Hello World',
};

中文

export default {
  HelloWorld: '您好世界',
};

2. 使用語言資源

可以在LocalHome中直接使用剛才定義的語言資源

import { BeanBase, Local } from '@cabloy/core';
import { ScopeModule } from '../resource/this.js';

@Local()
export class LocalHome extends BeanBase<ScopeModule> {
  async action({ user: _user }) {
+   // 自動判斷當前語言
+   const message = this.scope.locale.HelloWorld();
+   // 強制使用英文資源
+   const message1 = this.scope.locale.HelloWorld.locale('en-us');
+   // 強制使用中文資源
+   const message2 = this.scope.locale.HelloWorld.locale('zh-cn');
+   return `${message}:${message1}:${message2}`;
-   return this.scope.config.prompt;
  }
}
  1. 不需要匯入任何型別,直接在程式碼中使用this.scope.locale來訪問當前業務模組中的語言資源

看一下動畫演示,提供了完整的型別智慧提示:

六、錯誤異常

1. 定義錯誤碼

可以為業務模組定義錯誤碼

export enum Errors {
+ Error001 = 1001,
}
  1. 這裡定義了一個錯誤列舉型別Error001,對應的錯誤碼是1001

2. 定義錯誤碼對應的語言資源

可以為錯誤碼定義語言資源,比如,這裡分別定義英文和中文兩種語言資源

英文

export default {
+ Error001: 'This is a test',
  HelloWorld: 'Hello World',
};

中文

export default {
+ Error001: '這是一個錯誤',
  HelloWorld: 'Hello World',
};

3. 丟擲錯誤異常

可以在LocalHome中直接使用剛才定義的錯誤列舉值,並丟擲異常

import { ScopeModule } from '../resource/this.js';

@Local()
export class LocalHome extends BeanBase<ScopeModule> {
  async action({ user: _user }) {
+   // 直接丟擲異常
+   this.scope.error.Error001.throw();
-   return this.scope.config.prompt;
  }
}
  1. 不需要匯入任何型別,直接在程式碼中使用this.scope.error來訪問當前業務模組中的錯誤列舉值

看一下動畫演示,提供了完整的型別智慧提示:

六、後記

Cabloy4.0中就已經提供了大量業務能力,比如:工作流引擎、表單引擎、許可權引擎、欄位許可權、多級快取、模組化體系、分散式架構、多租戶引擎,等等。隨著Cabloy5.0 Typescript的賦能,這些業務能力也隨之有了全新的表現

欲瞭解更多,請關注每晚8點B站直播:濮水程式碼

相關文章