Home About
golang, micronaut

Golang で POST する(備忘録)

Golang を使ってウェブサーバに POST する最小限のサンプルをつくる。 POSTを受けるサーバは Micronaut で用意する。

なお、OS は Ubuntu 20.04, go version go1.16.4 linux/amd64, Micronaut Version: 2.5.7 で試しています。

Micronaut で POST を受けるエンドポイントを用意

$ mn create-app myapp --build=gradle --lang=groovy
$ cd myapp
$ mn create-controller item

生成したコントローラ src/main/groovy/myapp/ItemController.groovy を編集:

package myapp

import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Post
import io.micronaut.http.annotation.Body

@Controller("/item")
class ItemController {
    @Post(uri="/", produces="text/plain")
    def index(@Body String contents) {
        contents
    }
}

http://localhost:8080/item/ に POST すると POST された内容をそのままオウム返します。
./gradlew run してサーバを起動しておきます。

curl でテスト

$ curl -X POST "http://localhost:8080/item/" -d '{ "hello": "world" }' -H "Content-Type: application/json"
{ "hello": "world" }

できました。

golang で実装

curl と同じ機能を果たすクライアントを実装します。

$ mkdir client
$ cd client
$ go mod init client

main.go を準備:

package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"net/http"
	"time"
)

type Params struct {
	url  string
	json string
}

func contents(resp *http.Response) (string, error) {
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}
	return string(b), nil
}

func doPost(params *Params) (string, error) {
	req, err := http.NewRequest("POST", params.url, bytes.NewBuffer([]byte(params.json)))
	if err != nil {
		return "", err
	}

	client := &http.Client{Timeout: time.Second * 10}
	response, err := client.Do(req)
	if err != nil {
		return "", err
	}
	defer response.Body.Close()

	statusCode := response.StatusCode
	if statusCode != 200 {
		return "", fmt.Errorf("StatusCode %d is not expected.", statusCode)
	}

	result, err := contents(response)
	if err != nil {
		return "", err
	}
	return result, nil
}

func main() {
	params := Params{
		url:  "http://localhost:8080/item/",
		json: "{\"hello\":\"world\"}",
	}

	result, err := doPost(&params)
	if err != nil {
		fmt.Println(fmt.Errorf("Got error %s", err.Error()))
	}
	fmt.Println( fmt.Sprintf("%s", result) )
}

実行:

$ go run main.go
{"hello":"world"}

できました。