PowerShell で API を叩いてみる

# はじめに
表題のまま！
きっかけはこれ↓
[業務改善をしよう！目次編](https://qiita.com/startPG/items/7992575454c6e339792e)

※PC環境が Mac しかないため、PowerShell Core を Mac にインストールして実施しています。
 インストール方法は[こちら](https://docs.microsoft.com/ja-jp/powershell/scripting/install/installing-powershell-core-on-macos?view=powershell-7)

# 結論：Invoke-WebRequest か Invoke-RestMethod を使う
外部通信というと **curl** が思い浮かびますが、残念ながら **curl** そのものは初期状態では入っていません。
**2020/2/10 追記**
→バージョンにより curl が最初から入っている場合もあるそうです。コメントでご指摘いただきました。
@ktz_aliasさん、ありがとうございます！

今回は前提として他のチームメンバーにも共有しますので、あまりインストール作業とかさせないようにしたい…

それに、せっかくだから PowerShell のやり方でやってみたいしね

というわけで早速結論ですが、**Invoke-WebRequest** か **Invoke-RestMethod** を使うことで外部通信を行うことができます。
この2つの違いとは…？ここに載せても良かったのですが、日本語記事だと特にトップには出てこなかったので、せっかくなので別記事で書くことにしました。記事の記載が終わり次第こちらにもリンクを張っておきます。
**2020/2/10 追記**
**書きました。**
[Invoke-WebRequestとInvoke-RestMethodの違い](https://qiita.com/startPG/items/7b37c527667fa43ab173)

で、一応この違いを調査する前に **Invoke-WebRequest** で学習を進めてしまっていたので今回はこちらを簡単に紹介したいと思います。

# Invoke-WebRequest を使ってみる
とりあえずサッと叩いてみましょう。
適当に叩ける API を調べたら下記が出てきたので使わせてもらっています。
[【随時更新】一風変わったWeb APIをまとめてみた](https://qiita.com/danishi/items/42d8adf6291515e62284)

```
$web = Invoke-WebRequest "https://yesno.wtf/api"
$web

StatusCode        : 200
StatusDescription : OK
Content           : {"answer":"no","forced":false,"image":"https://yesno.wtf/as
                    sets/no/15-7446b1035f784986609f456e15d30a5b.gif"}
RawContent        : HTTP/1.1 200 OK
                    Transfer-Encoding: chunked
                    Connection: keep-alive
                    Status: 200 OK
                    Cache-Control: must-revalidate, max-age=0, private
                    Access-Control-Allow-Origin: *
                    ETag: "5c579cddf84cec8bef9c616b7da260…
Headers           : {[Transfer-Encoding, System.String[]], [Connection, System.
                    String[]], [Status, System.String[]], [Cache-Control, Syste
                    m.String[]]…}
Images            : {}
InputFields       : {}
Links             : {}
RawContentLength  : 108
RelationLink      : {}
```
ちなみに [**Invoke-WebRequest**] は全て小文字でも問題ないです。
というか PowerShell 特有のコマンド（正しくはコマンドレット）は基本的に大文字小文字関係ないみたいです。

叩き方は GET メソッドということもあり、そこまで curl と異なる感じでもなくむしろまんまですね。
流石にオプションは異なりますが、ややこしいこともなく、そんなに違和感感じないかと。

主に使うものとしてヘッダーの設定だけちょっと癖があるかなって感じですね。
PowerShell の場合はヘッダーの設定はこうなります。

```
Invoke-WebRequest -Method POST -Headers @{"Authorization"="Basic XXX";"Content-Type"="application/json"} ~...
```

さて話を戻しまして、レスポンスを見てもらえば分かる通り、少し通常の応答とは異なります。
これは PowerShell における独自のオブジェクトで、これらのいずれかを取得したい場合は下記のように記載します。

```
$web.Content

{"answer":"no","forced":false,"image":"https://yesno.wtf/assets/no/15-7446b1035f784986609f456e15d30a5b.gif"}
```

もちろんこうして使ってもよいのですが、こんなことも

```
$hoge = ConvertFrom-Json $web
$hoge

answer forced image
------ ------ -----
no      False https://yesno.wtf/assets/no/15-7446b1035f784986609f456e15d30a5b.…

$hoge.answer

no
```
PowerShell には **jq** 相当のコマンドは用意がないため、**jq** っぽく使いたい時は上記のようにオブジェクトを変換して指定してあげると使いやすいかと思います。

# 〆
ぶっちゃけ言いますと、先述したような Json の応答を期待する API を叩く時は **WebRequest** でなく **RestMethod** のほうが良さげです。
なんでかって話ですが、これまた先述したように別記事にあげますのでそちらを参照ください。
（というか実際に打ってみたほうが早い）

せっかく PowerShell を使うのであれば、特有のものを色々調べつつ進めていきたいですね。
それでは！