Grails
PowerShell

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

More than 3 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コマンドレットを使い倒そう」という資料を公開しているので、こちらをどうぞ。