Microsoft developer platformのurl.parse非推奨対応|typed-rest-client変更点と確認ポイント

Microsoft developer platform documentation updateとして確認したい「Remove Deprecated use of url.parse」は、Node.jsの旧URL APIであるurl.parse()を、より標準的なWHATWG URL APIのnew URL()へ置き換える変更です。結論から言うと、typed-rest-clientを直接または間接的に使ってREST APIを呼び出しているNode.js/TypeScript開発チームは、依存関係の更新状況だけでなく、URL生成、リダイレクト、プロキシ、認証情報付きURLの動作確認まで行うべきです。Node.jsのDEP0169では、url.parse()は標準化されておらず、セキュリティ上の誤りにつながりやすいとしてWHATWG URL APIの利用が推奨されています。(Node.js)

目次

Microsoft developer platform documentation update: Remove Deprecated use of url.parseの概要

今回の更新は、Microsoftのtyped-rest-clientリポジトリにあるPR「Remove Deprecated use of url.parse」に関するものです。PR本文では、Node 24のDeprecationに対応し、url.parseの利用をより安全なnew URL()へ更新すること、さらにrest-clientでリクエストオブジェクトが形成される方法に影響することが明記されています。(GitHub)

typed-rest-clientは、TypeScriptでREST/HTTP通信を扱うための軽量クライアントです。Azure DevOps関連のNode.jsアプリや、Microsoft系APIを呼び出す自動化ツール、社内CLI、CI/CDタスクなどで直接・間接的に使われている可能性があります。

ただし、ここで重要なのは「PRが出ている=すぐ本番環境に反映済み」とは限らない点です。PRページでは2026年5月5日に「minor changes and version update」やAzure Pipelinesの実行が確認できますが、確認時点ではPRはOpenで、レビュー待ちの表示も残っています。(GitHub) また、PR内ではpackage.jsonのバージョンが2.3.1から2.3.2へ変更されていますが、公開済みnpmパッケージの最新版とはタイミングがずれる場合があります。(GitHub)

なぜurl.parse()からnew URL()へ移行する必要があるのか

Node.jsのDEP0169では、url.parse()について「挙動が標準化されておらず、セキュリティ上の影響がある誤りを招きやすい」と説明されています。Node 24ではアプリケーションコード向けの非推奨扱いになっており、url.format(urlString)やurl.resolve()も内部的にurl.parse()を呼び出すため、同じ非推奨の対象に含まれます。(Node.js)

実務上のポイントは、単に警告が出るかどうかではありません。url.parse()とnew URL()では、不正なURL、相対URL、ポート番号、認証情報、パスの正規化に対する扱いが異なります。そのため、機械的に置き換えるだけでは、HTTPリクエストの送信先やプロキシ設定が意図せず変わる可能性があります。

たとえば、以下のようなコードは見た目には単純です。

// 旧: legacy URL API
import * as url from "url";

const parsed = url.parse(requestUrl);
const isHttps = parsed.protocol === "https:";

移行後は、基本的に次のように書きます。

// 新: WHATWG URL API
const parsed = new URL(requestUrl);
const isHttps = parsed.protocol === "https:";

ただし、new URL()は絶対URLを前提にするため、相対パスを扱う場合はベースURLを渡す必要があります。

const baseUrl = "https://dev.azure.com/example-org/";
const resource = "_apis/projects";

const requestUrl = new URL(resource, baseUrl).href;
// https://dev.azure.com/example-org/_apis/projects

相対パスの先頭に/を付けると、ベースURLのパス部分を上書きする場合があります。

const baseUrl = "https://dev.azure.com/example-org/";
const resource = "/_apis/projects";

const requestUrl = new URL(resource, baseUrl).href;
// https://dev.azure.com/_apis/projects

この違いは、Azure DevOpsのようにURLパス内に組織名やプロジェクト名を含めるAPIで特に見落としやすいポイントです。

PRで確認できる主な変更点

PRの差分では、lib/HttpClient.ts、lib/Interfaces.ts、lib/Util.ts、テスト、package.jsonなどが変更されています。特に重要なのは、IRequestInfo.parsedUrlの型がurl.UrlからURLへ変わっている点です。これにより、内部的なリクエスト形成だけでなく、型を参照している利用側コードにも影響する可能性があります。(GitHub)

変更箇所変更内容実務で確認すべきこと
URL解析url.parse()からnew URL()へ変更不正なURLや相対URLで例外が発生しないか
型定義url.UrlからURLへ変更parsedUrl.authやparsedUrl.pathなど旧プロパティを参照していないか
リダイレクト処理new URL(redirectUrl, parsedUrl.href)で解決相対リダイレクト、外部ホストへのリダイレクト、HTTPSからHTTPへの遷移を確認
プロキシ処理プロキシURLもnew URL()で解析HTTP_PROXY、HTTPS_PROXY、認証付きプロキシURLの形式を確認
URL結合Util.getUrl()のベースURLとリソースURLの結合ロジックを更新末尾スラッシュ、先頭スラッシュ、クエリ文字列、認証情報付きURLを回帰テスト
バージョンPR上で2.3.1から2.3.2へ変更実際のnpm公開状況とlockファイルの更新を確認

url.UrlとURLではプロパティ名が完全には一致しません。移行時は、次の対応関係を意識すると安全です。

旧APIでよく使う値新APIでの確認方法注意点
protocolurlObj.protocolhttps:のように末尾のコロンを含む
hosturlObj.hostホスト名とポートを含む
hostnameurlObj.hostnameポートを含まない
porturlObj.port文字列として返る
authurlObj.username、urlObj.password認証情報は個別に扱う
pathurlObj.pathname + urlObj.searchpath相当の値は自分で組み立てる
queryurlObj.searchParamsURLSearchParamsとして扱う
hrefurlObj.hrefurl.format()の代替として使いやすい

影響を受けやすい開発チーム

この変更で特に確認が必要なのは、typed-rest-clientを使っているすべてのチームではなく、URLの組み立てやHTTP通信条件をカスタマイズしているチームです。

対象対応優先度理由
typed-rest-clientを直接importしているNode.jsアプリ高型変更やURL解析の挙動変更を直接受ける
Azure DevOps APIなどをNode.js SDK経由で呼び出すツール中〜高間接依存としてtyped-rest-clientを使っている可能性がある
プロキシ環境下で動く社内CLIやCIジョブ高プロキシURL、認証、バイパス設定の影響を受けやすい
REST APIのURLを設定ファイルや環境変数から読むアプリ高不正なURLがnew URL()で例外になる可能性がある
Node 18/20のみで動かしている既存アプリ中すぐ壊れるとは限らないが、将来のNode更新で警告や例外に備える必要がある
ブラウザだけで動くフロントエンド低Node.jsのurl.parse()を使っていなければ影響は限定的

まずは依存関係を確認します。

npm ls typed-rest-client

npm v8以降で「なぜ入っているか」を見たい場合は、次のコマンドも有効です。

npm explain typed-rest-client

pnpmやYarnを使っている場合は、同様に依存経路を確認します。

pnpm why typed-rest-client
yarn why typed-rest-client

移行時に確認すべきチェックポイント

URLが絶対URLか相対URLかを分けて確認する

url.parse()は曖昧な入力をある程度受け入れることがありました。一方、new URL()は厳格です。相対パスをそのまま渡すと例外になります。

new URL("/_apis/projects");
// TypeError: Invalid URL

相対パスを扱う場合は、必ずベースURLを渡します。

new URL("/_apis/projects", "https://dev.azure.com/example-org/");

ただし、先頭スラッシュがあるとベースURLのパス部分を引き継がない場合があります。APIの仕様として組織名、テナント名、プロジェクト名をURLパスに含める場合は、実際に生成されるhrefをテストで確認してください。

認証情報付きURLを安易に使わない

PR内のレビューでも、usernameやpasswordに特殊文字が含まれるケースが論点になっています。(GitHub)

たとえば、次のようなURLは、特殊文字のエンコードやログ出力で問題になりやすい形式です。

https://user:p@[email protected]/api

RESTクライアントで認証する場合は、URLにユーザー名やパスワードを埋め込むより、認証ハンドラー、ヘッダー、シークレット管理機能を使う方が安全です。どうしても認証付きURLを扱う場合は、usernameとpasswordの値、エンコード後のURL、ログに出る内容を確認しましょう。

プロキシ設定を本番に近い環境でテストする

typed-rest-clientでは、プロキシURLの解析もnew URL()へ変更されています。PR差分では、プロキシURLの解析に失敗した場合にInvalid proxy URLとしてエラーを投げる処理が追加されています。(GitHub)

確認すべき環境変数は、利用環境によって異なりますが、代表的には以下です。

HTTP_PROXY=http://proxy.example.com:8080
HTTPS_PROXY=http://proxy.example.com:8080
NO_PROXY=localhost,127.0.0.1,.example.com

特に、プロキシURLに認証情報を含めている環境では、特殊文字、空白、末尾スラッシュ、ポート番号の形式を確認してください。

リダイレクト先のURLを確認する

PRでは、リダイレクトURLをnew URL(redirectUrl, parsedUrl.href)で解析する形に変更されています。(GitHub) これは相対リダイレクトを扱ううえで自然な実装ですが、従来と完全に同じ結果になるとは限りません。

次のようなケースをテストに入れると、移行後の不具合を見つけやすくなります。

テストケース確認内容
Location: /login同一ホストの絶対パスとして解決されるか
Location: ../next現在のパスから相対解決されるか
Location: https://別ホスト/...認証ヘッダーやトークンを不用意に送らないか
httpsからhttpへのリダイレクトセキュリティ設定どおり拒否されるか
不正なLocation例外時にアプリが安全に失敗するか

TypeScriptの型エラーを軽視しない

IRequestInfo.parsedUrlがurl.UrlからURLへ変わるため、型エラーは単なるコンパイル上の問題ではなく、実行時のプロパティ参照ミスを示している可能性があります。

たとえば、旧APIのpathやauthを参照している場合は、次のように置き換えを検討します。

// 旧
const path = parsedUrl.path;
const auth = parsedUrl.auth;

// 新
const path = parsedUrl.pathname + parsedUrl.search;
const username = parsedUrl.username;
const password = parsedUrl.password;

authを文字列として再構築する場合は、ログに出さないこと、必要に応じてマスクすることも忘れないでください。

すぐ実施したい確認手順

Microsoft developer platformのこの更新を受けて、実務では次の順序で確認すると効率的です。

| 手順 | 作業 | 目的 |
| -: | ————————————————— | —————— |
| 1 | npm ls typed-rest-clientで利用有無を確認 | 直接・間接依存を把握する |
| 2 | package-lock.json、pnpm-lock.yaml、yarn.lockを確認 | 実際に使われるバージョンを特定する |
| 3 | ソース内のurl.parse、url.format、url.resolveを検索 | 自社コード側の非推奨APIを見つける |
| 4 | Node 24またはdeprecation警告を有効にしたCIでテスト | 警告や例外の発生箇所を特定する |
| 5 | REST APIのURL生成テストを追加 | 送信先URLの変化を防ぐ |
| 6 | プロキシ、リダイレクト、認証情報付きURLを重点テスト | 本番で起きやすい障害を事前に潰す |
| 7 | npm公開バージョンとPRのマージ状況を確認して更新 | 未公開PRを前提にした誤更新を避ける |

ソース検索は、まず単純なgrepで十分です。

grep -R "url.parse\|url.format\|url.resolve" ./src ./lib ./test

Node.jsの警告を追跡する場合は、次のように実行すると発生箇所を特定しやすくなります。

NODE_OPTIONS="--trace-deprecation" npm test

早めに検出したい場合は、警告を例外として扱うテストも有効です。

NODE_OPTIONS="--throw-deprecation" npm test

ただし、依存パッケージ側の警告まで一律に失敗扱いにするとCIが不安定になることがあります。まずは--trace-deprecationで発生源を確認し、自社コード、直接依存、間接依存のどこで起きているかを切り分けるのが現実的です。

移行で失敗しやすいポイント

「警告を消すだけ」の置き換えをしない

url.parse()をnew URL()へ置き換える目的は、警告を消すことだけではありません。URL解析の安全性と一貫性を高めることが目的です。

次のような置き換えは危険です。

// よくない例: 相対URLを考慮していない
const parsed = new URL(inputUrl);

設定ファイルやAPI呼び出しごとに相対URLが入り得るなら、ベースURLを明示します。

const parsed = new URL(inputUrl, baseUrl);

不正なURLを握りつぶさない

new URL()は不正な入力で例外を投げます。これを空文字やデフォルトURLに置き換えると、誤った送信先へリクエストするリスクがあります。

function parseRequestUrl(input: string): URL {
  try {
    return new URL(input);
  } catch (err) {
    const message = err instanceof Error ? err.message : String(err);
    throw new Error(`Invalid request URL: ${message}`);
  }
}

ログにURL全体を出す場合は、トークン、ユーザー名、パスワード、署名付きURLのクエリ文字列が含まれないように注意してください。PR内にも、エラーメッセージにURLそのものを含めない方向の変更が見られます。(GitHub)

npm公開前のPR内容だけで本番更新しない

PR上でバージョン更新が見えていても、パッケージレジストリに公開されるタイミングは別です。PRがマージ済みか、タグやリリースノートが出ているか、npmに該当バージョンが公開されているかを確認してからlockファイルを更新してください。

本番環境では、次のような段階的な更新が安全です。

npm update typed-rest-client
npm test
npm run build

更新後はlockファイルの差分を確認します。

git diff package-lock.json

間接依存として入っている場合は、上位パッケージの更新が必要になることもあります。無理にoverridesやresolutionsで固定すると、上位パッケージの想定外の組み合わせになる場合があるため、まずは公式の更新経路を確認しましょう。

自社コードでもurl.parse()を使っている場合の移行例

typed-rest-clientの更新を待つだけでなく、自社コードでもurl.parse()を使っているなら、この機会に移行しておくと将来のNode更新に強くなります。

絶対URLを解析する

const requestUrl = "https://example.com:8443/api/items?limit=10";

const parsed = new URL(requestUrl);

console.log(parsed.protocol); // https:
console.log(parsed.hostname); // example.com
console.log(parsed.port);     // 8443
console.log(parsed.pathname); // /api/items
console.log(parsed.search);   // ?limit=10

クエリ文字列を安全に扱う

const url = new URL("https://example.com/api/items");

url.searchParams.set("limit", "10");
url.searchParams.set("keyword", "A&B");

console.log(url.href);
// https://example.com/api/items?limit=10&keyword=A%26B

文字列連結でクエリを作るより、searchParamsを使う方がエンコード漏れを防ぎやすくなります。

相対URLをベースURLと結合する

const baseUrl = "https://example.com/api/";
const resource = "items/123";

const url = new URL(resource, baseUrl);

console.log(url.href);
// https://example.com/api/items/123

ベースURLの末尾スラッシュとリソースの先頭スラッシュは、生成結果に影響します。APIクライアントのテストでは、hrefまで比較するのがおすすめです。

今回の更新で読者が次に取るべき行動

今回のMicrosoft developer platform documentation update: Remove Deprecated use of url.parseは、単なるドキュメント上の表記修正ではなく、Node.jsの非推奨APIに合わせてRESTクライアントのURL解析方法を見直す変更です。特にtyped-rest-clientを使っている場合、new URL()への移行によってリクエストURL、プロキシURL、リダイレクトURL、型定義の扱いが変わる可能性があります。

まずは自分のプロジェクトでtyped-rest-clientが使われているかを確認し、次にurl.parse()、url.format()、url.resolve()の利用箇所を洗い出してください。そのうえで、Node 24相当の環境またはdeprecation警告を有効にしたCIでテストし、URL生成の回帰テストを追加するのが最短の対応です。

特に本番でMicrosoft系APIやAzure DevOps APIを呼び出しているチームは、依存関係の更新だけで終わらせず、「最終的にどのURLへ、どのヘッダーで、どのプロキシ経由でリクエストしているか」まで確認してください。これが、今回のurl.parse()非推奨対応で最も重要な実務ポイントです。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次