Help us understand the problem. What is going on with this article?

NestJS Response ヘッダー 変え方

この記事は NestJS Advent Calendar 2019 11日目の記事です。前日は @euxn23 さんによる「NestJS 循環参照」の予定でしたが、都合により遅れるとのことです。かくいう私も担当の日付を勘違いしていて、1日遅れの投稿となってしまったことをお詫び申し上げます。
本日は NestJS においてレスポンスのヘッダーを変える方法について紹介します。

Content-Type を変更する

特定のエンドポイントだけ返すコンテンツの種類が異なり、特定の Content-Type を設定したいなどのシチュエーションは往々にしてあると思います。
今回は例として、NewsController というコントローラ以下の feed という関数の担当するエンドポイントに対して、RSS フィードの Content-Type である application/rss+xml; charset=UTF-8 を設定する方法を例に解説したいと思います。
これの要件に対し、NestJS では2通りの解決方法があります。

@Header デコレータを用いる方法

NestJS では、コントローラ内のエンドポイントに対して @Get, @Post と同様に @Header というデコレータを用いることによってヘッダーの特定プロパティの返り値を上書きすることができます。
以下の例ではエンドポイントが返すレスポンスのヘッダーが常に application/rss+xml; charset=UTF-8 になります。

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

@Controller('news')
export class NewsController {
  @Get('/feed')
  @Header('content-type', 'application/rss+xml; charset=UTF-8')
  feed(): string {
    return feedContent;
  }
}

ただしこの方法を用いると、関数内でエラーが発生しエラーレスポンスが json で返されたときも指定した Content-Type で上書きされてしまいます。

Response オブジェクトに設定する方法

こちらは関数の引数として Response オブジェクトを受け取り、それに直接 Content-Type を設定する方法です。Express などを既に使ったことがある方にはおなじみの方法ではないでしょうか。
以下の例ではエンドポイントが返すレスポンスのヘッダーが生成処理の成功時のみ application/rss+xml; charset=UTF-8 になります。

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

@Controller('news')
export class NewsController {
  @Get('/feed')
  async feed(@Res() res: Response) {
    try {
      // RSS フィードを生成する関数が存在すると仮定
      const generatedFeed = await feedGenerator.generate();
      res.set({
        'content-type': 'application/rss+xml; charset=UTF-8',
      });
      res.send(generatedFeed);
    } catch (error) {
      throw new HttpException(
        'Internal server error',
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }
}

ただ、上記コードを見てもらえばわかるように、NestJS では引数として受け取った部分をハンドリングしてやる必要があります。
今回は Response オブジェクトをヘッダーの設定のために呼び出しているので、そのオブジェクトに対してレスポンスを設定する部分まで面倒を見る必要があります
デコレータで設定したときのように return でレスポンス内容を返してもタイムアウトしてしまう点に注意が必要です。

おわりに

本日の記事では、NestJS においてレスポンスヘッダーを書き換える方法を、設定したシチュエーションに合わせて2通りの手法で紹介しました。

明日の担当は @euxn23 さんです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした