Node.jsのfetchで画像をダウンロードしてローカルディレクトリへ保存するエンドポイントの作成

TypeScriptNode.jsexpress
Node.jsのfetchで画像をダウンロードしてローカルディレクトリへ保存するエンドポイントの作成
Memo

経緯

SNS認証がでログインを実施するアプリを構築していてその際にログインしたユーザーのアカウント画像を保存する必要があり
その際の設計でエンドポイントを叩いて画像をダウンロードできるようにしたかったため
画像をダウンロードできるエンドポイントを作成しました。

環境

  • node 14.15.3
  • express 4.17.1

ファイル操作で利用するUnixコマンドについて

基本的なディレクトリ作成やファイル操作はUnixコマンドを利用します。
Unixコマンドについて詳しくはこちらの記事を参考にしてください。

構築手順

fetchはisomorphic-fetchを利用し、エンドポイントはexpressで作成しています。

必要パッケージのダウンロード

isomorphic-fetchとexpressのインストール

isomorphic-fetchexpressをyarnコマンドでインストールします。
npmで実施する方は必要に応じて適宜変更してください。

terminal
$ yarn add isomorphic-fetch express

ダウンロードの実装

main.jsへ実装処理を記述していきます。
また記述言語についてはTypeScriptを利用します。
それぞれ必要に応じて適宜変更してください。

必要パッケージのインポート

インストールしたパッケージをインポートしていきます。

main.ts
import express from 'express'; import fetch from 'isomorphic-fetch';

合わせてファイル保存を利用するfsモジュールもインポートします。

import fs from 'fs'

expressの初期化

main.ts
const app = express();

エンドポイントの作成

/api/downloadを叩いでダウンロードできるようにします。

main.ts
app.get('/api/download', async ( req: express.Request, res: express.Response ): Promise<void> => { } )

引数の取得

リクエストするURLと保存するパスとをクエリパラメータから取得できるようにします。

request_url

取得する画像のURL

filename

保存する画像のファイル名

main.ts
const { request_url, filename } = req.query;

画像を保存するディレクトリ

画像を保存するディレクトリを定義します。

main.ts
const downloadDir = 'download'

画像を保存

fetchで画像を取得し画像を保存します。

main.ts
try { const response = await fetch(request_url); const savePath = `${downloadDir}/${filename}`; response.body.pipe(fs.createWriteStream(savePath)); res.send("画像を保存しました。") } catch (error) { console.error(error); res.send("エラーが発生しました。") }

コード全体

画像を保存する処理の全体コードになります。

import express from 'express';
import fetch from 'isomorphic-fetch';
import fs from 'fs'

app.get('/api/download',
  async (
    req: express.Request,
    res: express.Response
  ): Promise<void> => {
    const { request_url, filename } = req.query;
    const downloadDir = 'download'
    try {
      const response = await fetch(request_url);
      const savePath = `${downloadDir}/${filename}`;
      response.body.pipe(fs.createWriteStream(savePath));
      res.send("画像を保存しました。")
    } catch (error) {
      console.error(error);
      res.send("エラーが発生しました。")
    }
  }
)

app.listen(8000, () => {
  console.log(`listening on *:${8000}`);
});

リクエストして確認

アプリケーション起動

作成したmain.tsからアプリケーションを立ち上げます。
TypeScriptで記述しているためts-nodeで起動しています。

terminal
$ ts-node main.ts

URLへアクセス

起動したアプリケーションへアクセスします。 http://localhost:8000/api/download?request_url=https://placehold.jp/150x150.png&filename=sample.png

データを確認

download配下に取得したファイルが作成されていれば成功です。

└── download
    └── sample.png

終わりに

最後までご覧いただきありがとうございます。
この記事ではNode.jsのfetchで画像をダウンロードしてローカルディレクトリへ保存するエンドポイントの作成について紹介させていただきました。

これからも皆様の開発に役立つ情報を提供していきたいと考えています。
今後ともよろしくお願いいたします。