<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 應用上下文 Nest提供了一些應用類來簡化在不同應用上下文之間編寫應用(例如Nest HTTP應用,微服務和WebSockets應用)。這些應用可以用于創建通用的守衛,過濾器和攔截器,可以工作在控制器,方法和應用上下文中。 本章包括`ArgumentsHost`和`ExecutionContext`兩個類. ## `ArgumentsHost`類 `ArgumentsHost`類提供了獲取傳遞給處理程序的參數。它允許選擇合適的上下文(例如HTTP,RPC(微服務)或者Websockets)來從框架中獲取參數。框架提供了`ArgumentsHost`的實例,作為`host`參數提供給需要獲取的地方。例如,在異常過濾器中傳入`ArgumentsHost`參數來調用`catch()`方法。 `ArgumentsHost`簡單地抽象為處理程序參數。例如,在HTTP應用中(使用`@nestjs/platform-express`時),host對象封裝了Express的`[request, response, next] `數組,`reuest`是一個`request`對象,`response`是一個`response`對象,`next`是控制應用的請求響應循環的函數。此外,在GraphQL應用中,host包含`[root, args, context, info]`數組。 ## 當前應用上下文 當構建通用的守衛,過濾器和攔截器時,意味著要跨應用上下文運行,我們需要一種方法來確定我們的方法當前正在運行的應用程序類型。可以使用 `ArgumentsHost`的`getType()`方法。 ```typescript if (host.getType() === 'http') { // do something that is only important in the context of regular HTTP requests (REST) } else if (host.getType() === 'rpc') { // do something that is only important in the context of Microservice requests } else if (host.getType<GqlContextType>() === 'graphql') { // do something that is only important in the context of GraphQL requests } ``` > `GqlContextType`從中`@nestjs/graphql`導入。 有了可用的應用程序類型,我們可以編寫更多的通用組件,如下所示。 ### `Host`處理程序參數 要獲取傳遞給處理程序的參數數組,使用host對象的`getArgs()`方法。 ```typescript const [req, res, next] = host.getArgs(); ``` 可以使用`getArgByIndex()`根據索引獲取指定參數: ```typescript const request = host.getArgByIndex(0); const response = host.getArgByIndex(1); ``` 在這些例子中我們通過索引來獲取請求響應對象,這并不推薦,因為它將應用和特定上下文耦合。為了使代碼魯棒性更好,更可復用,你可以在程序中使用host對象的應用方法來切換合適的應用上下文,如下所示: ```typescript /** * Switch context to RPC. */ switchToRpc(): RpcArgumentsHost; /** * Switch context to HTTP. */ switchToHttp(): HttpArgumentsHost; /** * Switch context to WebSockets. */ switchToWs(): WsArgumentsHost; ``` 使用 `switchToHttp`() 方法重寫前面的例子, `host.switchToHttp()`幫助方法調用一個HTTP應用的`HttpArgumentsHost`對象. `HttpArgumentsHost`對象有兩個有用的方法,我們可以用來提取期望的對象。我們也可以使用Express類型的斷言來返回原生的Express類型對象: ```typescript const ctx = host.switchToHttp(); const request = ctx.getRequest<Request>(); const response = ctx.getResponse<Response>(); ``` 類似地,`WsArgumentsHost`和`RpcArgumentsHost`有返回微服務和WebSockets上下文的方法,以下是`WsArgumentsHost`的方法: ```typescript export interface WsArgumentsHost { /** * Returns the data object. */ getData<T>(): T; /** * Returns the client object. */ getClient<T>(): T; } ``` 以下是`RpcArgumentsHost`的方法: ```typescript export interface RpcArgumentsHost { /** * Returns the data object. */ getData<T>(): T; /** * Returns the context object. */ getContext<T>(): T; } ``` ### 執行上下文類 `ExecutionContext`擴展了`ArgumentsHost`,提供有關當前執行過程的其他詳細信息。和`ArgumentsHost`類似,Nest在需要的時候提供了一個`ExecutionContext`的實例, 例如守衛的`canActivate()`方法和攔截器的`intercept()`方法,它提供以下方法: ```typescript export interface ExecutionContext extends ArgumentsHost { /** * Returns the type of the controller class which the current handler belongs to. */ getClass<T>(): Type<T>; /** * Returns a reference to the handler (method) that will be invoked next in the * request pipeline. */ getHandler(): Function; } ``` `getHandler()`方法返回要調用的處理程序的引用。`getClass()`方法返回一個特定處理程序所屬的控制器類。例如,一個HTTP上下文,如果當前處理的是一個POST請求,在`CatsController`中綁定`create()`方法。`getHandler()`返回`create()`方法和`getClass()`方法所在的`CatsController`類的引用(不是實例)。 ```typescript const methodKey = ctx.getHandler().name; // "create" const className = ctx.getClass().name; // "CatsController" ``` 訪問對當前類和處理程序方法的引用的能力提供了極大的靈活性。最重要的是,它讓我們有機會通過`@SetMetadata()`裝飾器從守衛或攔截器中訪問元數據集。我們將在下面介紹這個用例。 ### 反射和元數據 Nest提供了通過`@SetMetadata()`裝飾器將自定義元數據附加在路徑處理程序的能力。我們可以在類中獲取這些元數據來執行特定決策。 >cats.controller.ts ```typescript @Post() @SetMetadata('roles', ['admin']) async create(@Body() createCatDto: CreateCatDto) { this.catsService.create(createCatDto); } ``` > `@SetMetadata()`裝飾器從`@nestjs/common`導入。 基于上述結構,我們將`roles`元數據(`roles`是一個元數據,并且`['admin']` 是對應的值)關聯到`create()`方法。在這種情況下,不推薦直接在路徑中使用`@SetMetadata()`,而是應該如下創建自己的裝飾器: >roles.decorator.ts ```typescript import { SetMetadata } from '@nestjs/common'; export const Roles = (...roles: string[]) => SetMetadata('roles', roles); ``` 這種方法更干凈、更易讀,并且是強類型的。我們現在可以使用自定義的`@Roles()`裝飾器,并將其應用在`create()`方法中。 >cats.controller.ts ```typescript @Post() @Roles('admin') async create(@Body() createCatDto: CreateCatDto) { this.catsService.create(createCatDto); } ``` 要訪問`roles`路徑 (自定義元數據),我們將使用`Reflector`輔助類,它由框架提供,開箱即用,從`@nestjs/core`包導入。`Reflector`可以通過常規方式注入到類: >roles.guard.ts ```typescript @Injectable() export class RolesGuard { constructor(private reflector: Reflector) {} } ``` > `Reflector`類從`@nestjs/core`導入。 使用`get()`方法讀取處理程序的元數據。 ```typescript const roles = this.reflector.get<string[]>('roles', context.getHandler()); ``` `Reflector#get`方法允許通過傳遞兩個參數簡單獲取元數據:一個元數據key和一個context(裝飾器對象)來獲取元數據。在本例中,指定的key是`roles`(向上指回`roles.decorator.ts`以及在此處調用的`SetMetadata()`方法)。context 由`context.getHandler()`提供,用于從當前路徑處理程序中獲取元數據,`getHandler()`給了我們一個到路徑處理函數的引用。 我們也可以組織我們的控制器,來從控制器層獲取元數據,以在控制器所有路徑中應用。 >cats.controller.ts ```typescript @Roles('admin') @Controller('cats') export class CatsController {} ``` 在本例中,要獲取控制器元數據,將`context.getClass()`作為第二個參數(將控制器類作為上下文提供以獲取元數據)來替代`context.getHandler()`: >roles.guard.ts ```typescript const roles = this.reflector.get<string[]>('roles', context.getClass()); ``` 要具備在多層提供元數據的能力,需要從多個上下文獲取與合并元數據。`Reflector`類提供兩個應用方法來幫助實現該功能。這些方法同時獲取控制器和方法元數據,并通過不同方法來合并他們。 考慮以下場景,在兩個水平應用`roles`都提供了元數據: >cats.controller.ts ```typescript @Roles('user') @Controller('cats') export class CatsController { @Post() @Roles('admin') async create(@Body() createCatDto: CreateCatDto) { this.catsService.create(createCatDto); } } ``` 如果你想將`user`指定為默認角色,并且出于特定目的有選擇地進行覆蓋,可以使用 `getAllAndOverride()`方法。 ```typescript const roles = this.reflector.getAllAndOverride<string[]>('roles', [ context.getHandler(), context.getClass(), ]); ``` 使用該代碼編寫守衛,在上下文中應用`create()`方法,采用上述元數據,將生成包含 `['admin']`的`roles`。 要獲取與合并元數據(該方法合并數組和對象),使用`getAllAndMerge()`方法: ```typescript const roles = this.reflector.getAllAndMerge<string[]>('roles', [ context.getHandler(), context.getClass(), ]); ``` 這會生成包含['user', 'admin']的`roles`。 對于這兩種合并方法,傳輸元數據作為第一個參數,數組或者元數據對象上下文(例如,調用`getHandler()`和/或`getClass()`)作為第二個參數。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看