Posted at

Windowsにcurlが無い?いいえ、Invoke-RestMethodがあります。GrailsアプリへのPOSTリクエストを試す

More than 5 years have passed since last update.

最近PowerShellな記事ばっかり書いてる気がしますが…WindowsマシンでGrails開発してるだけです!よ!

Invoke-RestMethod コマンドを使ってPOSTメソッドでAPIを叩くときには、こんな感じになります。

> Invoke-RestMethod -Uri "http://localhost:8080/myapp/mydomain/myaction/" -Method POST -Body "id=2014&filename=0609.csv&format=json"

Uri オプションのダブルクオートは無くても動きますが、Body オプションのダブルクオートは必須です。Body を連想配列で書く方法も用意されてますが…

> Invoke-RestMethod -Uri "http://localhost:8080/myapp/mydomain/myaction/" -Method POST -Body @{id="2014";filename="0609.csv";format="xml"}

Web屋さんなら & でつなぐ書き方の方が馴染みがありますし、何より文字数が少なくて済みますね。

このコマンドで叩いているGrails側のコントローラではこんな風に書いています。


MydomainController.groovy

package org.myapp

import grails.converters.JSON
import grails.converters.XML

class MydomainController {

static allowedMethods = [myaction: 'POST']

def myaction(String filename) {
println params // リクエストパラメータをコンソールに出力
println filename // filenameをコンソールに出力
withFormat{
json { render Mydomain.findByFilename(filename) as JSON
xml { render ([id:params.id] as XML) }
}
}
}


allowedMethods によってPOSTリクエスト以外を受け付けない指定なので、ブラウザで http://localhost:8080/myapp/mydomain/myaction/2014 とかを開いても HTTP 405 (Method Not Allowed) となります。

このGrailsのコントローラに対して、最初に書いた Invoke-RestMethod コマンドを叩くと…

> Invoke-RestMethod -Uri "http://localhost:8080/myapp/mydomain/myaction/" -Method POST -Body "id=2014&filename=0609.csv&format=json"

class : org.myapp.Mydomain
id : 2014
filename : 0609.csv
filetypeCode : 01
descriptionText : あれに使うCSVファイルです。

また、Grailsを実行しているコンソールに以下のような出力が出ます。

[id:2014, filename:0609.csv, format:null, action:myaction, controller:mydomain]

0609.csv

myaction() の引数である filename も、リクエストパラメータ params からバインドされた値であるため、params.filenamefilename の値は同じですね。params.formatnull になっていますが、Grailsが用意している withFormat により指定された format の出力を振り分けられるようになっています。

xmlの方を叩いてみましょう。

> Invoke-RestMethod -Uri "http://localhost:8080/myapp/mydomain/myaction/" -Method POST -Body "id=2014&filename=0609.csv&format=xml"

xml map
--- ---
version="1.0" encoding="UTF-8" map

む。ちょっとわかりにくいですね。OutFile オプションでファイルに書き出してやりましょう。

> Invoke-RestMethod -Uri "http://localhost:8080/myapp/mydomain/myaction/" -Method POST -Body "id=2014&filename=0609.csv&format=xml" -OutFile result.xml

>

こんな感じのファイルが吐かれます。


result.xml

<?xml version="1.0" encoding="UTF-8"?><map><entry key="id">2014</entry></map>


最初は allowedMethods を指定せずGETパラメータで試せば動作は確認できますが、「きちんとPOSTのみ受け付けるようになっているか」はこういった形で確認すべきですね。

Invoke-RestMethod のその他のオプション等については牟田口大介さんが「Invoke-WebRequest・Invoke-RestMethodコマンドレットを使い倒そう」という資料を公開しているので、こちらをどうぞ。