iT邦幫忙

2024 iThome 鐵人賽

DAY 5
1

nestjs 核心元件 Controller

目標

  1. 介紹 nestjs Controller 作用
  2. Controller 範例

概念

在 nestjs 框架中, Controller 是用來處理 client 的 HTTP 請求,並且給予回應邏輯的元件。

語法

使用 @Controller 裝飾的類別,就是 Controller。而在 @Controller 中帶入的字串就是該 Controller 的 prefix 路徑。

以下是 blogController 的範例

import { Controller, Get, Post} from '@nestjs/common';

@Controller('blog')
export class BlogController {
	
	@Get(':id')
	GetArticle() {
	   // get article logic...	
	}
	
	@Post()
	@HttpCode(201)
	CreateArticle() {
	  // create article logic...
	}
	
}

在 nestjs 中,一些常見處理 request 的物件都可以在 @nestjs/common 找到,大致上都遵循著 expressjs 的規範, nestjs 預設的 http server 是 expressjs ,以下是 nestjs 與 expressjs 物件的對應表:

nestjs 物件 expressjs 物件
@Request(), @Req() req
@Response(), @Res() * res
@Next() next
@Session() req.session
@Param(key?: string) req.params / req.params[key]
@Body(key?: string) req.body / req.body[key]
@Query(key?: string) req.query / req.query[key]
@Headers(name?: string) req.headers / req.headers[name]
@Ip() req.ip
@HostParam() req.hosts

回傳值格式

nestjs Controller 類別內每個路由處理函式的回傳值具有預設的格式,假設回傳值是 javascript 中的 primitive type 比如 string, number, boolean。則值結回傳不做序列化處理。而如果回傳值是 non-primitive type ,比如 javascript 的 object 或是 array ,則會自動地被 nestjs 序列化為 JSON 格式。

回應 http code

預設不指定的話,一般 handler 直接 return value 沒有 exception 之後的 http code 會是 200。而 POST 的成功預設 http code 回應值是 201。

如果想要自行定義成功回應 http code 可以使用 @HttpCode 裝飾子放在處理的 method 之前,如下

@Post()
@HttpCode(204)
create() {
  return 'This action adds a new cat';
}

handler 支援 async 或是 Observable 的語法

  1. async
@Get()
async findAll(): Promise<Article[]> {
  return new Array<Article>();
}
  1. Observable
@Get()
findAll(): Observable<Article[]> {
  return of(new Array<Article>());
}

使用 expressjs 方式來回應

nestjs 提供彈性,能夠使用 expressjs 的回應處理方法,如下:

import { Controller, Get, Post, Res, HttpStatus } from '@nestjs/common';
import { Response } from 'express';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Res() res: Response) {
    res.status(HttpStatus.CREATED).send();
  }

  @Get()
  findAll(@Res() res: Response) {
     res.status(HttpStatus.OK).json([]);
  }
}

但如果這樣做,就會無法讓 request 搭配原本 nestjs 內建 request lifecycle ,也就是使用相對應 event 處理邏輯,比如 Interceptor 等等來做回應處理。

想要使用 expressjs 回應方式,又想能夠搭配原本 nestjs 的 request lifecycle 就必須要在 @Res 物件搭入一個參數 passthrough: true ,舉例如下


@Get()
findAll(@Res({ passthrough: true }) res: Response) {
  res.status(HttpStatus.OK);
  return [];
}

這樣就可以在使用 expressjs 回應函數,且能套用原本 nestjs 的 request lifecycle 去處理。

結論

nestjs 透過 Controller 元件來處理 http 的請求與回應,不論是在輸入解析與輸出回應的邏輯都會被包在這個元件之內。

後續更重要的處理 http 請求的整個 lifecycle 則會在之後的五個章節依序介紹。Module, Provider 與 Controller 是 nestjs 的基礎核心。透過這三個元件就能開發需多簡易的後端 api server 功能。

後續五個章節,將會介紹 nestjs 從分層架構的概念,延伸出更細緻的分工。讓整個開發職責能夠更區分明細,簡化處理流程。


上一篇
nestjs 核心元件 Provider
下一篇
nestjs 分層元件 Middleware
系列文
透過 nestjs 框架,讓 nodejs 系統維護度增加31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言