Skip to content

Commit

Permalink
docs: update tenant component
Browse files Browse the repository at this point in the history
  • Loading branch information
czy88840616 committed May 7, 2024
1 parent 8bc2f2b commit 5b15a56
Show file tree
Hide file tree
Showing 7 changed files with 323 additions and 20 deletions.
File renamed without changes.
14 changes: 11 additions & 3 deletions site/docs/extensions/swagger.md
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,15 @@ Swagger 本身不支持泛型数据,泛型作为 Typescript 的一种类型,
为此,我们可以编写一个方法,入参是返回的 data,返回一个包裹的类。

```typescript
export function SuccessWrapper<T extends Type>(ResourceCls: T) {
import { Type } from '@midwayjs/swagger';

type Res<T> = {
code: number;
message: string;
data: T;
}

export function SuccessWrapper<T>(ResourceCls: Type<T>): Type<Res<T>> {
class Successed {
@ApiProperty({ description: '状态码' })
code: number;
Expand All @@ -660,7 +668,7 @@ export function SuccessWrapper<T extends Type>(ResourceCls: T) {
我们可以基于这个方法,来实现我们自己的返回类。

```typescript
class ViewCat extends SuccessWrapper(Cat) {}
class ViewCat extends SuccessWrapper<Cat>(Cat) {}
```

在使用的时候,可以直接指定这个类即可。
Expand All @@ -672,7 +680,7 @@ class ViewCat extends SuccessWrapper(Cat) {}
description: 'The found record',
type: ViewCat,
})
findOne(@Param('id') id: string, @Query('test') test: any): ViewCat {
async findOne(@Param('id') id: string, @Query('test') test: any): ViewCat {
// ...
}
```
Expand Down
142 changes: 142 additions & 0 deletions site/docs/extensions/tenant.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# 租户

这里介绍如何快速在 Midway 中使用租户组件。

相关信息:

| 描述 | |
| ----------------- | ---- |
| 可用于标准项目 ||
| 可用于 Serverless ||
| 可用于一体化 ||
| 包含独立主框架 ||
| 包含独立日志 ||



## 租户定义

租户管理是中后台业务开发过程中经常需要的功能。

在开发中,不同的用户需要保存在不同的数据源、命名空间或是区域中,这些不同的数据区域我们统称为 “租户”。



## 安装依赖

`@midwayjs/tenant` 是主要的功能包。

```bash
$ npm i @midwayjs/tenant@3 --save
```

或者在 `package.json` 中增加如下依赖后,重新安装。

```json
{
"dependencies": {
"@midwayjs/tenant": "^3.0.0",
// ...
}
}
```




## 引入组件


首先,引入 组件,在 `src/configuration.ts` 中导入:

```typescript
import { Configuration } from '@midwayjs/core';
import * as tenant from '@midwayjs/tenant';

@Configuration({
imports: [
// ...
tenant,
],
})
export class MainConfiguration {
}
```



## 租户信息存取

不同的租户数据相互隔离,一般来说,每个用户数据都会关联相关的租户信息,在用户认证拿到用户信息之后,获取其对应的租户数据,以便后续数据读写使用。

在 Midway 中,可以将租户数据保存在请求对象 ctx 中,后续的所有请求作用域对象可以使用。但是租户信息仅仅在请求链路中使用是不够的,需要在不同的作用域都生效,这就需要新的架构来支持。

组件提供了一个 `TenantManager` 来管理租户信息。

你需要在每个请求链路中保存租户信息,之后才能获取。

租户信息的格式可以按需求定义。

比如:

```typescript
interface TenantInfo {
id: string;
name: string;
}
```

比如,在中间件中保存。

```typescript
import { TenantManager } from '@midwayjs/tenant';
import { Middleware, Inject } from '@midwayjs/core';

@Middleware()
class TenantMiddleware {
@Inject()
tenantManager: tenant.TenantManager;

resolve() {
return async(ctx, next) => {
// 请求链路中设置租户信息
this.tenantManager.setCurrentTenant({
id: '123',
name: '我的租户'
});
}
}
}
```

在后续的单例服务中获取。

```typescript
import { TenantManager } from '@midwayjs/tenant';
import { Inject, Singleton } from '@midwayjs/core';
import { TenantInfo } from '../interface';

@Singleton()
class TenantService {
@Inject()
tenantManager: tenant.TenantManager;

async getTenantInfo() {
const tenantInfo = await this.tenantManager.getCurrentTenant<TenantInfo>();
if (tenantInfo) {
console.log(tenantInfo.name);
// output => 我的租户
}
}
}
```



:::tip

* 1、租户信息一定会关联请求,如有需求,你可以在不同的 Framework 中都加入中间件
* 2、每个请求保存的租户信息是隔离的
* 3、不管是单例还是请求作用域,你都仅能获取到当前请求对应的租户数据

:::
3 changes: 2 additions & 1 deletion site/docs/sidebars.json
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,8 @@
"extensions/static_file",
"extensions/cross_domain",
"extensions/http-proxy",
"extensions/captcha"
"extensions/captcha",
"extensions/tenant"
]
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,15 @@ For example, we need to add some common package structure to the return value.
To do this, we can write a method where the input parameter is the returned data and returns a wrapped class.

```typescript
export function SuccessWrapper<T extends Type>(ResourceCls: T) {
import { Type } from '@midwayjs/swagger';

type Res<T> = {
code: number;
message: string;
data: T;
}

export function SuccessWrapper<T>(ResourceCls: Type<T>): Type<Res<T>> {
class Successed {
@ApiProperty({ description: 'Status Code'})
code: number;
Expand All @@ -660,7 +668,7 @@ export function SuccessWrapper<T extends Type>(ResourceCls: T) {
We can implement our own return class based on this method.

```typescript
class ViewCat extends SuccessWrapper(Cat) {}
class ViewCat extends SuccessWrapper<Cat>(Cat) {}
```

When using, you can directly specify this class.
Expand All @@ -672,7 +680,7 @@ When using, you can directly specify this class.
description: 'The found record',
type: ViewCat
})
findOne(@Param('id') id: string, @Query('test') test: any): ViewCat {
async findOne(@Param('id') id: string, @Query('test') test: any): ViewCat {
// ...
}
```
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# Tenant

Here's how to quickly use tenant components in Midway.

Related Information:

| Description | |
| ------------------------------- | ---- |
| Available for standard projects ||
| Available for Serverless ||
| Available for integration ||
| Contains independent main frame ||
| Contains standalone logs ||



## Tenant definition

Tenant management is a function often required in the middle and back-end business development process.

During development, different users need to be stored in different data sources, namespaces or areas. These different data areas are collectively called "tenants".



## Install dependencies

`@midwayjs/tenant` is the main function package.

```bash
$ npm i @midwayjs/tenant@3 --save
```

Or add the following dependencies in `package.json` and reinstall.

```json
{
"dependencies": {
"@midwayjs/tenant": "^3.0.0",
// ...
}
}
```




##Introduce components


First, introduce the component and import it in `src/configuration.ts`:

```typescript
import { Configuration } from '@midwayjs/core';
import * as tenant from '@midwayjs/tenant';

@Configuration({
imports: [
// ...
tenant,
],
})
export class MainConfiguration {
}
```



## Tenant information access

Different tenant data are isolated from each other. Generally speaking, each user data is associated with relevant tenant information. After the user information is obtained through user authentication, its corresponding tenant data is obtained for subsequent data reading and writing.

In Midway, tenant data can be saved in the request object ctx and can be used by all subsequent request scope objects. However, it is not enough for tenant information to be used only in the request link. It needs to be effective in different scopes, which requires a new architecture to support it.

The component provides a `TenantManager` to manage tenant information.

You need to save tenant information in each request link before retrieving it later.

The format of tenant information can be defined as required.

for example:

```typescript
interface TenantInfo {
id: string;
name: string;
}
```

For example, save in middleware.

```typescript
import { TenantManager } from '@midwayjs/tenant';
import { Middleware, Inject } from '@midwayjs/core';

@Middleware()
class TenantMiddleware {
@Inject()
tenantManager: tenant.TenantManager;

resolve() {
return async(ctx, next) => {
//Set tenant information in the request link
this.tenantManager.setCurrentTenant({
id: '123',
name: 'my tenant'
});
}
}
}
```

Obtained in subsequent singleton services.

```typescript
import { TenantManager } from '@midwayjs/tenant';
import { Inject, Singleton } from '@midwayjs/core';
import { TenantInfo } from '../interface';

@Singleton()
class TenantService {
@Inject()
tenantManager: tenant.TenantManager;

async getTenantInfo() {
const tenantInfo = await this.tenantManager.getCurrentTenant<TenantInfo>();
if (tenantInfo) {
console.log(tenantInfo.name);
// output => my tenant
}
}
}
```



:::tip

* 1. Tenant information will definitely be associated with the request. If necessary, you can add middleware to different Frameworks.
* 2. The tenant information saved in each request is isolated
* 3. Regardless of whether it is a singleton or a request scope, you can only obtain the tenant data corresponding to the current request.

:::
28 changes: 15 additions & 13 deletions site/static/resource/101010100.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
{
"city": "北京",
"cityid": "101010100",
"temp": "27.9",
"WD": "南风",
"WS": "小于3级",
"SD": "28%",
"AP": "1002hPa",
"njd": "暂无实况",
"WSE": "<3",
"time": "17:55",
"sm": "2.1",
"isRadar": "1",
"Radar": "JC_RADAR_AZ9010_JB"
"weatherinfo": {
"city": "北京",
"cityid": "101010100",
"temp": "27.9",
"WD": "南风",
"WS": "小于3级",
"SD": "28%",
"AP": "1002hPa",
"njd": "暂无实况",
"WSE": "<3",
"time": "17:55",
"sm": "2.1",
"isRadar": "1",
"Radar": "JC_RADAR_AZ9010_JB"
}
}

0 comments on commit 5b15a56

Please sign in to comment.