4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

frourio+fastifyでAPI経由のバイナリファイルダウンロード

Posted at

frourioでAPIにリクエストしたときにバイナリファイルを送信する場合、APIのレスポンスの型を定義しておかないとNext.js側で処理できずに詰まった時の事をまとめます。

Next.js側での実装

ファイルのダウンロードの方法は色々あるかと思いますが、Blobを使ってみることにしました。
zipファイルをダウンロードすることにします。

サンプルなので雰囲気ですがこんな感じになると思います

const apiClient = api(aspida());
const res = await apiClient.file.$get();
const blob = new Blob([res], { type: 'application/zip' });
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = `file.zip`;
link.click();
link.remove();

こんなわけでBlobオブジェクトを作らないといけないわけですが、コンストラクタに渡すデータはBufferにします。
というわけでAPI側の定義はBufferを返すようにします。

API側の実装

定義したまま値を返す

index.tsではBufferを返すように定義します。

// index.ts
export type Methods = {
  get: {
    resBody: Buffer;
  };
};

でそうするとcontroller.ts側ではBufferを返さないといけないのですが、

// controller.ts
export default defineController(() => ({
  get: async () => {
    const buffer = await getBuffer();
    return { status: 200, body: buffer };
  },
}));

getBufferからBufferを返してもレスポンスがファイルのバイナリと一致しないのでファイルを開くのが失敗してしまいます。

定義とは別にBufferを返す

一方、fastifyでバイナリファイルを送信するサンプルはいくらでもあるので、それが使えないかやってみました。
controller.tsの実装を以下のように変えます。

// controller.ts
export type AdditionalRequest = {
  reply: FastifyReply;
};

export default defineController(() => ({
  get: async ({ reply }) => {
    await getBuffer(reply);
    return { status: 200, body: Buffer.from([])}; // Buffer.fromはダミー
  },
}));

getBufferにFastifyReplyを渡したいので、まずAdditionalRequestでFastifyReplyをリクエストに追加するように定義します。
getメソッドでそれを受け取れるのでgetBufferに渡します。
getBuffer内ではFastifyReply.sendを使ってバイナリファイルを送信するようにします。

で、controllerのgetメソッド側ではbodyにBufferを返してあげないと型エラーになってしまうので空のBufferを返します。
実際にはFastifyReply.sendでレスポンスが返されているのでここで返している値は影響しません。

まとめ

こうすると型定義としてNext.js側ではBufferを受け取ることになり、バイナリファイルがダウンロードできます。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?