0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Node.js axios】params利用時のURLクエリ文字列に意図しない「+」が混入?原因と解決策

Posted at

Node.js環境で axios ライブラリを使い、外部APIに対してリクエストを行う際、クエリパラメータを params オブジェクトで指定したところ、生成されるURLに意図しない + 文字が混入し、APIが期待通りに動作しないという問題に直面しました。
この記事では、その原因と具体的な解決策を、特定のAPIサービス名を伏せた形で共有します。

生じた事象:生成されたURLに予期せぬ「+」記号

特定のIDに基づいて情報を検索する外部APIのエンドポイントに対し、処理を実装していました。axiosの設定は以下の通りです。


// 問題発生時のコード一部抜粋
import axios from 'axios';
import config from '../config.js'; // 設定ファイル

// ... (中略) ...

const apiClientConfig = {
    method: 'GET',
    url: `${config.apiSettings.baseUrl}/search-endpoint`, // APIのベースURLと検索用エンドポイント
    headers: {
        'Authorization': `Basic ${Buffer.from(/* ... */).toString('base64')}`, // 認証ヘッダー
    },
    params: {
        query: `searchId: ${config.apiSettings.targetId}` // ← 問題の箇所 (targetIdは検索対象のID)
    },
};

axios(apiClientConfig)
    .then(response => {
        console.log(response.data);
    })
    .catch(error => {
        console.error(error);
    });

このコードでAPIリクエストを実行した際、APIサーバーから期待する検索結果が得られませんでした。

試したこと:まずは、生成されるURLをログに出力して確認

問題の原因を特定するため、axios が実際にどのようなURLを生成してリクエストを送信しているのかを確認することにしました。axios.getUri() メソッドを使うと、設定オブジェクトから最終的なリクエストURL文字列を取得できます。

// デバッグコード
const generatedUrl = axios.getUri(apiClientConfig);
console.log('Axios generated URL:', generatedUrl);

ログに出力されたURLは、以下のような形式になっていました。

Axios generated URL: https://api.example.com/v1/search-endpoint?query=searchId:+some123id

ここで、searchId: と実際のID (some123id は仮の値) の間に、意図しない + が挿入されていることが明らかになりました。連携先のAPIはおそらく searchId:some123id という形式のクエリ文字列を期待しており、この + が原因でAPI側がクエリを正しく解釈できていなかったと推測されます。

原因の特定:テンプレートリテラル内の半角スペース

この予期せぬ + 文字が混入した原因は、params オブジェクト内の query プロパティを定義しているテンプレートリテラル (``) 内の半角スペースでした。

params: {
    query: `searchId: ${config.apiSettings.targetId}` // "searchId:" の直後に半角スペースが存在した
},

URLのクエリパラメータでは、半角スペースは一般的に + または %20 にURLエンコードされます。axios は、このテンプレートリテラル内の半角スペースを + としてエンコードし、最終的なリクエストURLを生成していたのです。

解決策:テンプレートリテラル内の不要なスペースを削除

この問題の解決策は非常にシンプルで、テンプレートリテラル内の不要な半角スペースを削除することでした。

// 修正後のコード
const apiClientConfig = {
    method: 'GET',
    url: `${config.apiSettings.baseUrl}/search-endpoint`,
    headers: {
        'Authorization': `Basic ${Buffer.from(/* ... */).toString('base64')}`,
    },
    params: {
        query: `searchId:${config.apiSettings.targetId}` // "searchId:" と ${...} の間のスペースを削除
    },
};

この修正を適用した結果、生成されるURLは期待通りの形式になりました。

Axios generated URL: https://api.example.com/v1/search-endpoint?query=searchId:some123id

これにより、外部APIはクエリを正しく解釈し、期待されたデータを返すようになりました。

まとめ

axiosparams オブジェクトを利用してAPIリクエストのクエリパラメータを動的に生成する際、テンプレートリテラル内の記述には注意が必要です。意図しない半角スペースがURLエンコーディングの過程で予期せぬ文字(今回のケースでは +)に変換され、APIの動作に影響を与える可能性があります。

API連携で問題が発生した場合は、まず axios.getUri() などの手段を用いて実際に送信されるリクエストURLを確認し、APIのドキュメントで期待されるURL形式と比較することが、原因究明の第一歩となります。

一見単純なスペースの見落としが、API連携においては思わぬトラブルの原因となることがあります。日頃から生成されるリクエスト内容を意識し、丁寧な実装を心がけることが重要です。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?