PowerShellを使い始めBashと挙動の違いがあったのでまとめました。
Fivetran APIを使いユーザー情報を取得します。
Bashの場合
# APIとAPI秘密鍵を設定する
API_KEY="xxxxxxxx" #置き換える
API_SECRET_KEY="xxxxxxxxxxxxxxxxxxx" #置き換える
curl -X GET "https://api.fivetran.com/v1/users" -u $API_KEY:$API_SECRET_KEY | jq
ユーザー情報が表示されていますね。
PowerShellの場合
# APIとAPI秘密鍵を設定する
API_KEY="xxxxxxxx" #置き換える
API_SECRET_KEY="xxxxxxxxxxxxxxxxxxx" #置き換える
# Base64でエンコード
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $apiUser, $apiSecret)))
# ヘッダーの準備
$headers = @{
"Authorization" = "Basic $base64AuthInfo"
}
# APIエンドポイント
$url = "https://api.fivetran.com/v1/users"
# GETリクエストの実行
$response = Invoke-RestMethod -Uri $url -Method Get -Headers $headers
# レスポンスの表示
$response
PowerShellは書く処理が多くて嫌になりますね。
curlコマンドだとエンコードやヘッダーは自動でやってくれるそうでその分書く量が減ると知りました。
APIはBashと同じものを使っています。
Successと表示されているもののユーザー情報が表示されていません。
原因:PowerShell Invoke-RestMethodの仕様
この原因はInvoke-RestMethodコマンドレットにありました。
PowerShellでInvoke-RestMethodを使ってAPIからJSONレスポンスを受け取った場合、そのレスポンスは自動的にPowerShellオブジェクトに変換されます。
この挙動は便利ですが、結果の表示が必ずしも期待通りにはならない場合があります。
具体的には、Success @{items=System.Object[]}のように表示された場合、これはPowerShellがitemsプロパティがオブジェクトの配列を含んでいることを示していますが、配列内の各オブジェクトの内容までは直接表示しません。
by chatGPT
data
---
@{items=System.Object[]}
この出力結果はitemsが空という意味ではなく、このitemsプロパティはオブジェクトの配列配列を持つという意味だったそうです。
まじかよ。
なぜJSONを表示しないのかも聞きました。
PowerShellのデフォルトの出力フォーマットは、深いネストされたオブジェクトや配列の内容を全て展開して表示しないことがあります。これは、特にコンソールウィンドウでの読みやすさを考慮した結果です。System.Object[]は、配列内のオブジェクトがPowerShellによって一般的なオブジェクトとして認識されていることを示しますが、具体的な内容はこの表示からはわかりません。
なるほど。
ネストが深くなるJSONはわざと表示しないようにしているようですね。
解決方法:ConvertTo-Jsonを使う
ネストが深いJSONを表示するときはConvertTo-Jsonコマンドレットを使うと良いそうです。
そうすることでレスポンスオブジェクトを再びJSON文字列に変換してから表示します。
...
# GETリクエストの実行
$response = Invoke-RestMethod -Uri $url -Method Get -Headers $headers
# レスポンスの表示
$response| ConvertTo-Json | Write-Output # コマンド追加
ユーザー情報が表示されました。
表示されないときはエンコードやヘッダーがうまく設定できないと疑いましたが、最初から取れていたんですね。
今回のようにネストが深いときは警告文が出ています。
WARNING: Resulting JSON is truncated as serialization has exceeded the set depth of 2.
日本語
警告:シリアライズが設定された深さ 2 を超えたため、結果の JSON は切り捨てられます。
JSON関連で警告も出ていました。
itemsプロパティの値が整形できていないのはネストの上限値を超えたことが原因かもしれませんね。
設定で変更できるかもしれません。
まとめ
PowerShellでJSONを表示するときは必ず ConberTo-Json を付けましょう。
PowerShellでもAPIコールできないこともないですが、Bashの方が使いやすいなと思いました。