【実務・中級編】【REST API連携】MSXML2.ServerXMLHTTP を用いたJSONレスポンスの取得とスクリプト制御によるWebサービス統合 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

【REST API連携】MSXML2.ServerXMLHTTP を用いたJSONレスポンスの取得とスクリプト制御によるWebサービス統合

開発現場でふと立ち返るべき現実がある。それは、どれほどモダンなクラウドインフラが構築されようとも、社内のレガシーなWindows端末や閉域網のサーバー群では、いまだにVBScript(WSH)がインフラの接着剤として静かに、しかし強固に稼働し続けているという事実だ。

「なぜ、今さらVBScriptなのか」
そう嘲笑う者もいるだろう。だが、追加のランタイムインストールすら許されない厳格なセキュリティポリシーが敷かれた環境において、OS標準機能だけで動作するVBScriptは、業務自動化の最終防衛ラインとして圧倒的な価値を持つ。

今回は、このVBScriptを用いて外部のREST APIと通信し、JSONレスポンスを安全に取得・制御する極限のテクニックを伝授する。ネット上に散らばる「動くだけの脆いコード」を卒業し、プロダクション環境に耐えうる堅牢なWebサービス統合の設計思想を叩き込んでほしい。

1. なぜ `MSXML2.ServerXMLHTTP` なのか?

VBScriptからHTTP通信を行う際、初心者はよく `MSXML2.XMLHTTP` を使いがちだ。しかし、業務自動化エンジニアの視点から言えば、サーバーサイドやタスクスケジューラーでの無人実行において `XMLHTTP` の採用は自殺行為に等しい。

`XMLHTTP` と `ServerXMLHTTP` の決定的な違い

  • `MSXML2.XMLHTTP`

ブラウザ(Internet Explorer)のセキュリティコンテキストやキャッシュ機構を引きずる。非同期処理やUIスレッドとの連動を前提としており、無人実行(WSH)環境では予期せぬダイアログ表示によるフリーズや、セッションの固着を引き起こす。

  • `MSXML2.ServerXMLHTTP`(今回採用する真の勝者):

完全に独立したサーバーサイド向けのコンポーネント。UIとの切り離しがされており、厳密なタイムアウト制御、プロキシ認証、SSL/TLSのハンドリングにおいて圧倒的な安定性を誇る。

2. 現場で絶対に踏んではいけない「3つの地雷」

API連携スクリプトを書いていて、本番稼働後に突然システムが停止する原因のほとんどは、以下のいずれかを見落としていることにある。

1. 無限ブロック(タイムアウト未設定)
ネットワークの切断やAPIサーバーの障害時、タイムアウトを設定していないHTTPリクエストは無限にスレッドを占有し続けます。WSHスクリプトがゾンビ化し、タスクマネージャーから手動でkillするまでCPUを蝕み続ける悪夢を見たければ、タイムアウトを省略するといい。
2. 文字化け(UTF-8の罠)
VBScriptのネイティブな文字列型はBSTR(UTF-16)だが、モダンなREST APIが返すJSONはほぼ100% `UTF-8` である。`responseText` をそのまま処理すると、日本語が盛大に文字化けするか、パースエラーを引き起こす。`responseBody`(バイト配列)を正確にADODB.Streamでデコードする一手間が不可欠だ。
3. JSONパーサーの不在
VBScriptには、JavaScriptの `JSON.parse` のようなネイティブなJSONパーサーが存在しない。外部のCOMコンポーネントを入れる権限がない環境では、正規表現(RegExp)を用いた擬似パース、もしくは安全なスクリプトエンジンの評価(`Eval`)を駆使してデータを抽出しなければならない。

3. 【プロダクションコード】完全堅牢・REST API連携テンプレート

以下のコードは、タイムアウト制御、UTF-8バイナリデコード、そして安全なデータ抽出のロジックをすべて網羅した、そのまま実務に投入できる完成形のVBScriptである。

‘ ==============================================================================
‘ Script Name : RestApiIntegrationTemplate.vbs
‘ Description : MSXML2.ServerXMLHTTP を用いた堅牢なREST API連携サンプル
‘ Author : Chief Architect
‘ ==============================================================================

Option Explicit

‘ — 設定定数 —
Const API_ENDPOINT = “https://jsonplaceholder.typicode.com/todos/1” ‘ 接続先API
Const REQ_TIMEOUT_RESOLVE = 5000 名前解決タイムアウト (ms)
Const REQ_TIMEOUT_CONNECT = 5000 接続タイムアウト (ms)
Const REQ_TIMEOUT_SEND = 10000 送信タイムアウト (ms)
Const REQ_TIMEOUT_RECEIVE = 10000 受信タイムアウト (ms)

Sub Main()
Dim http, jsonText

WScript.Echo “INFO: APIリクエストを開始します -> ” & API_ENDPOINT

‘ 1. HTTPリクエストの実行とレスポンス取得
jsonText = CallRestApi(API_ENDPOINT, “GET”, “”, “”)

If jsonText = “” Then
WScript.Echo “ERROR: APIからのレスポンス取得に失敗しました。”
Exit Sub
End If

WScript.Echo “INFO: レスポンスの取得に成功しました。データを解析します。”

‘ 2. データの抽出(VBScriptにおける擬似パース)
‘ ※本番では正規表現やJScriptオブジェクトの併用で堅牢に抽出する
Dim userId, id, title, completed
userId = ExtractJsonValue(jsonText, “userId”)
id = ExtractJsonValue(jsonText, “id”)
title = ExtractJsonValue(jsonText, “title”)
completed = ExtractJsonValue(jsonText, “completed”)

‘ 3. 業務処理(ログ出力およびファイル・DB連携へのブリッジ)
WScript.Echo “————————————————–”
WScript.Echo ” User ID : ” & userId
WScript.Echo ” ID : ” & id
WScript.Echo ” Title : ” & title
WScript.Echo ” Completed : ” & completed
WScript.Echo “————————————————–”

‘ TODO: ここで取得した変数をDB(ADODB)やCSVファイル出力に渡す
End Sub

‘ ==============================================================================
‘ HTTP通信カプセル化関数(タイムアウト・UTF-8デコード完備)
‘ ==============================================================================
Function CallRestApi(url, method, requestBody, bearerToken)
Dim http
Set http = CreateObject(“MSXML2.ServerXMLHTTP.6.0”)

On Error Resume Next

‘ タイムアウトの設定 (Resolve, Connect, Send, Receive)
‘ ※ミリ秒単位。これを怠るとネットワーク障害時にスクリプトがフリーズします。
http.setOption 2, 1305 ‘ SXH_OPTION_ignore_CERT_DATE_INVALID 等が必要な場合は調整
http.setTimeouts REQ_TIMEOUT_RESOLVE, REQ_TIMEOUT_CONNECT, REQ_TIMEOUT_SEND, REQ_TIMEOUT_RECEIVE

http.Open method, url, False

‘ ヘッダーの設定
http.setRequestHeader “Content-Type”, “application/json; charset=utf-8”
http.setRequestHeader “Accept”, “application/json”

If bearerToken <> “” Then
http.setRequestHeader “Authorization”, “Bearer ” & bearerToken
End If

‘ 送信実行
If method = “POST” Or method = “PUT” Then
http.Send requestBody
Else
http.Send
End If

If Err.Number <> 0 Then
WScript.Echo “HTTP Error (Exception): ” & Err.Description
CallRestApi = “”
Exit Function
End If

On Error GoTo 0

If http.Status <> 200 Then
WScript.Echo “HTTP Error Status: ” & http.Status & ” ” & http.statusText
CallRestApi = “”
Exit Function
End If

‘ 【極めて重要】UTF-8のバイナリ(responseBody)を正確にテキスト化する
Dim stream
Set stream = CreateObject(“ADODB.Stream”)
stream.Type = 1 ‘adTypeBinary
stream.Open
stream.Write http.responseBody
stream.Position = 0
stream.Type = 2 ‘adTypeText
stream.Charset = “utf-8”

CallRestApi = stream.ReadText

stream.Close
Set stream = Nothing
Set http = Nothing
End Function

‘ ==============================================================================
‘ 簡易JSON値抽出関数(正規表現ベース)
‘ ※複雑なネスト構造がないフラットなJSONオブジェクトのパースに最適
‘ ==============================================================================
Function ExtractJsonValue(json, key)
Dim re, matches, val
Set re = New RegExp

‘ ダブルクォーテーションで囲まれたキーに続く値(文字列、数値、真偽値)をキャプチャ
re.Pattern = “””” & key & “””\s:\s(“”([^””])”|([0-9\.]+)|(true|false))”
re.IgnoreCase = True
re.Global = False

If re.Test(json) Then
Set matches = re.Execute(json)
‘ マッチしたグループから実際の値を取り出す
val = matches(0).SubMatches(0)
‘ 前後のダブルクォーテーションを除去
If Left(val, 1) = “””” And Right(val, 1) = “””” Then
val = Mid(val, 2, Len(val) – 2)
End If
ExtractJsonValue = val
Else
ExtractJsonValue = “”
End If

Set re = Nothing
End Function

‘ 実行トリガー
Call Main()

4. アーキテクトからの実践的アドバイス:ファイル・DB連携への拡張

上記スクリプトで取得したデータを、単にコンソールに出力して終わるわけにはいかない。実際の業務自動化では、これを基幹データベース(SQL Server / Oracle / Access)へのインサートや、監査ログとしてのCSV出力に繋げる必要がある。

  • データベース連携時の注意点

`ADODB.Connection` を用いる際、APIから取得した文字列にシングルクォート(`’`)が含まれている場合、SQLインジェクションや構文エラーの原因になる。必ず `Replace(val, “‘”, “””)` によるエスケープ処理、または `ADODB.Command` とパラメーターコレクションを使用した安全なバインド変数を活用すること。

  • ファイル出力時の文字コード

CSV等に出力する場合も、VBScript標準の `FileSystemObject` (FSO) の `CreateTextFile` はデフォルトでANSI(Shift-JIS)になるため、API由来の特殊文字や絵文字などが含まれていると文字化けする。ここでも前述の `ADODB.Stream` を用いて `Charset = “utf-8″`(BOM付き/無し)でファイル書き込みを行うのがプロの選択だ。

結びにかえて

VBScriptはレガシーな技術と揶揄されがちだが、その本質を理解し、適切なエラーハンドリングとリソース管理(オブジェクトの確実に `Nothing` を代入する作法など)を徹底すれば、現代のクラウドサービスやモダンWebAPIとも互角に渡り合える強力な武器となる。

「動けばいい」という妥協を捨て、障害耐性の高いコードを書くこと。それこそが、現場を真に支える自動化エンジニアの誇りである。さあ、このコードをあなたの環境にデプロイし、堅牢なシステム構築の第一歩を踏み出してほしい。

タイトルとURLをコピーしました