Nest.js クエリパラメータ 使い方
Nest.jsにおけるクエリパラメータの使い方
Nest.jsでは、HTTPリクエストのクエリパラメータを簡単に取得し、アプリケーションロジックに組み込むことができます。以下に、その方法を説明します。
クエリパラメータの型定義
クエリパラメータの型を定義します。これは、TypeScriptの型システムを活用して、より安全なコードを書くために重要です。
import { QueryParam } from '@nestjs/common';
class MyQuery {
@QueryParam('param1')
param1: string;
@QueryParam('param2')
param2: number;
}
コントローラクラスのメソッドで、@QueryParam()
デコレータを使用してクエリパラメータを取得します。
import { Controller, Get } from '@nestjs/common';
import { MyQuery } from './my-query';
@Controller('my-controller')
export class MyController {
@Get()
getWithQuery(@Query() query: MyQuery) {
console.log(query.param1, query.param2);
}
}
取得したクエリパラメータをアプリケーションロジックで使用します。
@Get()
getWithQuery(@Query() query: MyQuery) {
// クエリパラメータを使用して何か処理を行う
const result = doSomethingWithQuery(query.param1, query.param2);
return result;
}
オプションのクエリパラメータ
クエリパラメータがオプションの場合は、@Optional()
デコレータを使用します。
import { Controller, Get, Optional } from '@nestjs/common';
@Controller('my-controller')
export class MyController {
@Get()
getWithOptionalQuery(@Optional() @QueryParam('param1') param1?: string) {
if (param1) {
// param1が存在する場合の処理
} else {
// param1が存在しない場合の処理
}
}
}
配列としてのクエリパラメータ
複数の値を持つクエリパラメータは配列として取得できます。
@QueryParam('arrayParam')
arrayParam: string[];
オブジェクトとしてのクエリパラメータ
ネストされたクエリパラメータはオブジェクトとして取得できます。
@QueryParam('nestedParam')
nestedParam: {
property1: string;
property2: number;
};
import { Controller, Get, Query } from '@nestjs/common';
@Controller('products')
export class ProductsController {
@Get()
findAll(@Query('category') category: string) {
// categoryに基づいて商品を検索するロジック
return this.productsService.findAll({ category });
}
}
- findAll()
category
に基づいて商品を検索するメソッドを呼び出します。 - @Query('category')
クエリパラメータのcategory
を取得し、category
変数に代入します。 - @Get()
GETメソッドに対応するエンドポイントを定義します。 - @Controller('products')
ProductsControllerというコントローラを定義します。
この例では、http://localhost:3000/products?category=electronics
のようなリクエストに対して、category
パラメータの値がelectronics
としてfindAll
メソッドに渡されます。
import { Controller, Get, Query } from '@nestjs/common';
@Controller('products')
export class ProductsController {
@Get()
findAll(@Query('category') category: string, @Query('price') price: number) {
// categoryとpriceに基づいて商品を検索するロジック
return this.productsService.findAll({ category, price });
}
}
複数のクエリパラメータを取得する場合は、@Query()
デコレータを複数回使用します。
import { Controller, Get, Query } from '@nestjs/common';
class ProductQueryDto {
category: string;
price?: number;
}
@Controller('products')
export class ProductsController {
@Get()
findAll(@Query() query: ProductQueryDto) {
// queryオブジェクトを使って商品を検索する
return this.productsService.findAll(query);
}
}
TypeScriptのクラスを使用して、クエリパラメータの型を定義することで、より安全なコードを書くことができます。
import { Controller, Get, Query, Optional } from '@nestjs/common';
@Controller('products')
export class ProductsController {
@Get()
findAll(@Optional() @Query('category') category?: string) {
// categoryが存在する場合のみ検索
if (category) {
return this.productsService.findAll({ category });
}
// 全ての商品を返す
return this.productsService.findAll();
}
}
@Optional()
デコレータを使用することで、クエリパラメータが省略された場合でもエラーにならないようにします。
import { Controller, Get, Query } from '@nestjs/common';
@Controller('products')
export class ProductsController {
@Get()
findAll(@Query('ids') ids: string[]) {
// idsの配列に基づいて商品を検索
return this.productsService.findByIds(ids);
}
}
複数のIDをカンマで区切って渡す場合、string[]
型で受け取ることができます。
import { Controller, Get, Query } from '@nestjs/common';
class FilterDto {
category: string;
price: number;
}
@Controller('products')
export class ProductsController {
@Get()
findAll(@Query() filter: FilterDto) {
return this.productsService.findAll(filter);
}
}
ネストされたオブジェクトをクエリパラメータとして渡すことも可能です。
Nest.jsでは、@Query()
デコレータを使用して、HTTPリクエストのクエリパラメータを簡単に取得し、アプリケーションロジックに組み込むことができます。TypeScriptの型システムを活用することで、より安全で保守性の高いコードを書くことができます。
ポイント
- 配列やオブジェクトとしてパラメータを受け取る
@Optional()
デコレータでオプションのパラメータを扱う- TypeScriptで型を定義することで、より安全なコードを書く
@Query()
デコレータでクエリパラメータを取得する
Requestオブジェクトの直接操作
- デメリット
- 手間がかかる
- エラーが発生しやすい
- 型安全性が低い
- メリット
- より柔軟な処理が可能
- Nest.jsの機能に依存しない
import { Controller, Get, Request } from '@nestjs/common';
@Controller('products')
export class ProductsController {
@Get()
findAll(@Request() req) {
const category = req.query.category;
// ...
}
}
- 解説
@Request()
デコレータでリクエストオブジェクト全体を取得し、req.query
プロパティからクエリパラメータにアクセスします。- Nest.jsの機能に依存しないため、高度なカスタマイズが必要な場合に有効です。
カスタムデコレータの作成
- デメリット
- 開発コストがかかる
- メリット
- 再利用性が高い
- 型安全性を保てる
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
export const MyQueryParam = createParamDecorator(
(data: string, ctx: ExecutionContext): string => {
const request = ctx.switchToHttp().getRequest();
return request.query[data];
},
);
@Controller('products')
export class ProductsController {
@Get()
findAll(@MyQueryParam('category') category: string) {
// ...
}
}
- 解説
createParamDecorator
を使ってカスタムデコレータを作成します。ExecutionContext
を使ってリクエストコンテキストにアクセスし、クエリパラメータを取得します。- 再利用可能なカスタムデコレータを作成することで、コードの重複を減らせます。
サードパーティライブラリの利用
-
例
- class-validator: 入力バリデーション
- class-transformer: オブジェクト変換
-
デメリット
- 依存関係が増える
-
- 特定の機能に特化している
- 開発時間の短縮
パイプラインの使用
- デメリット
- 複雑な処理になる場合がある
- メリット
- リクエスト処理のパイプライン化
- 複数の処理を連結可能
import { ParseIntPipe } from '@nestjs/common';
@Get()
findAll(@Query('id', ParseIntPipe) id: number) {
// ...
}
- 解説
ParseIntPipe
パイプラインを使用して、文字列のクエリパラメータを数値に変換します。- パイプラインを使用することで、入力値の検証や変換を統一的に行えます。
どの方法を選ぶべきか?
- 入力バリデーションや変換が必要な場合
サードパーティライブラリやパイプラインが有効です。 - 高度なカスタマイズが必要な場合
Requestオブジェクトの直接操作やカスタムデコレータが適しています。 - シンプルで一般的なケース
@Query()
デコレータが最も簡単で、多くの場合で十分です。
選択のポイント
- 柔軟性
さまざまなケースに対応できるか - パフォーマンス
処理速度が十分であるか - 保守性
将来的に修正や拡張がしやすいコードであるか - コードの可読性
他の開発者が理解しやすいコードであるか
Nest.jsにおけるクエリパラメータの取得方法は、@Query()
デコレータ以外にも様々な選択肢があります。それぞれの方法にはメリットとデメリットがあるため、プロジェクトの要件や開発者のスキルに合わせて適切な方法を選択することが重要です。
- ヘッダー
@Headers()
デコレータを用いてリクエストヘッダーを取得します。 - リクエストボディ
@Body()
デコレータを用いてリクエストボディを取得します。 - パスパラメータ
@Param()
デコレータを用いてパスパラメータを取得します。
javascript node.js typescript