import {
DocumentBuilder,
SwaggerModule as NestSwaggerModule
} from '@nestjs/swagger'
// 建立Swagger的設定
const config = new DocumentBuilder()
.addSecurity('JWT', {
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
in: 'header'
})
.build()
// 設定Swagger的路徑
NestSwaggerModule.setup(path, app, document, {
swaggerOptions: {
// 永久儲存授權
persistAuthorization: true,
// 預設分類不展開
docExpansion: 'none',
onComplete: () => {
// 設定是否為登入請求
let isLoginRequest = false
// 取得fetch
const originalFetch = window.fetch
// 覆寫fetch
window.fetch = async function (...args) {
// 執行原本的fetch
const response = await originalFetch.apply(this, args)
try {
// 如果為SingIn Request
if (isLoginRequest) {
// clone response
const clone = response.clone()
// 取得Content-Type
const contentType =
response.headers.get('content-type')
// 如果為JSON
if (contentType?.includes('application/json')) {
// 取得JSON
const data = await clone.json()
// 檢查 token
const token = data?.data?.token
// 如果有token
if (token) {
// 設定 Token
;(window as any).ui.preauthorizeApiKey(
'JWT',
token
)
// 重置標記
isLoginRequest = false
}
}
}
} catch (error) {
console.error('Error processing response:', error)
}
return response
}
// 添加點擊事件監聽
;(window as any).document.addEventListener(
'click',
(e: any) => {
if (
e.target.matches(
'.btn.execute.opblock-control__btn'
)
) {
// 取得URL的Query
const urlQuery = window.location.hash.slice(1)
// 如果URL的Query包含 _singIn_
if (urlQuery.includes('_singIn_')) {
// 如果是登入請求
isLoginRequest = true
}
}
}
)
}
},
customSiteTitle: 'API Documentation'
})
Follow Fang!
試著突破低點,往高點邁進
2024/11/19
Auto-filling JWT Token in NestJS Swagger Documentation
2024/11/16
Implement a Current Language Decorator in NestJS
再Nestjs要取得當前Request語系可以透過Decorator去取得
import { createParamDecorator, ExecutionContext } from '@nestjs/common'
import { Request } from 'express'
/**
* 取得語系
* @param data {unknown}
* @example
* @Controller('users')
* export class UserController {
* @Get('profile')
* getProfile(@CurrentUser() userId: number) {
* return { userId };
* }
* }
*
* // 與其他guard結合使用
* @Controller('users')
* export class UserController {
* @UseGuards(JwtAuthGuard)
* @Get('profile')
* getProfile(@CurrentUser() userId: number) {
* return { userId };
* }
* }
*/
export const Lang = createParamDecorator(
/**
* Factory
* @param data {unknown}
* @param ctx {ExecutionContext}
* @return {string}
*/
(data: unknown, ctx: ExecutionContext): string => {
//取得Http上下文
const httpContext = ctx.switchToHttp()
// 取得Request
const request: Request = httpContext.getRequest()
// 回傳語系 找不到就預設台灣
return (request?.headers?.lang as string) || 'zh-TW'
}
)
NestJS Request LifeCycle
NestJS 請求生命週期:詳細解說
NestJS 是一個流行的 Node.js 框架,它專注於模組化和可維護性的伺服器端邏輯管理。理解 NestJS 如何運作的關鍵之一,就是了解請求的生命週期。在本文中,我們將逐步介紹每個階段,詳細說明一個請求從進入到結束所經歷的過程。
### 請求進入 (Incoming Request)
每個生命週期的開始都是一個 **請求進入**。這是應用程式接收到 HTTP 請求的初始點。這一步標誌著客戶端互動(通常通過瀏覽器或 API 客戶端)進入 NestJS 應用程式,並觸發整個處理過程。
### 中介軟體 (Middleware)
在請求進入系統後,它會經過 **中介軟體** 的處理。中介軟體用於執行例如日誌記錄、請求驗證,或向請求物件附加額外屬性等任務。在 NestJS 中,中介軟體可以分為兩種類型:
Implementing Global HTTP Status 200 Response in NestJS
根據不同的 HTTP 方法,NestJS 會自動設置對應的 HTTP 狀態碼,但基於特定需求,我會另作考量和調整
import {
CallHandler,
ExecutionContext,
Injectable,
NestInterceptor
} from '@nestjs/common'
import { Observable } from 'rxjs'
import { Response } from 'express'
/**
* Response Interceptor
* @class {ResponseInterceptor}
* @implements {NestInterceptor}
*/
@Injectable()
export class ResponseInterceptor implements NestInterceptor {
/**
* Intercept
* @param context {ExecutionContext} - 執行上下文
* @param next {CallHandler} - 呼叫處理程序
* @return {Observable} 返回 Observable
*/
intercept(context: ExecutionContext, next: CallHandler): Observable {
// 取得 Http 上下文
const contextHttp = context.switchToHttp()
// 取得 Response 物件
const response: Response = contextHttp.getResponse()
// 設定成Http Status 200
response.status(200)
return next.handle()
}
}
main.ts
2024/11/14
Docker Desktop - WSL distro terminated abruptly
在PowerShell使用Admin輸入命令,並重啟Docker即可
參考資料:
netsh winsock reset
參考資料:
訂閱:
文章 (Atom)