GoLang全然わからん ~httpレスポンス&リクエスト編~

目次

はじめに

全くGoLangを知らん私が、Windows 11 + WSL2(Ubuntu 21.04) + Visual Studio Codeで勉強していくログです。

img

記事一覧

やったこと

net/http モジュールを使って、httpリスナーを起動、別の端末からアクセスしてLINE Norifyへ通知を行うのをやってみた。

以下ソース(httpd.go)

package main

import (
	"fmt"
	"log"
	"net/http"
	"net/url"
	"os"
	"strings"
)

// http handler
func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Printf("msg=[%s]\n", r.FormValue("msg"))

	// get message parameter
	msg := r.FormValue("msg")
	if msg == "" {
		msg = "no msg"
	}

	// get line token
	line_token := r.FormValue("token") // first try from parameter
	if line_token == "" {
		line_token = os.Getenv("LINE_TOKEN") // second try from environment parameter
		if line_token == "" {
			log.Fatal("can't get token")
		}
	}

	URL := "https://notify-api.line.me/api/notify"
	u, err := url.ParseRequestURI(URL)
	if err != nil {
		log.Fatal(err)
	}

	client := &http.Client{}

	form := url.Values{}
	form.Add("message", msg)

	body := strings.NewReader(form.Encode())

	req, err := http.NewRequest("POST", u.String(), body)
	if err != nil {
		log.Fatal(err)
	}

	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Set("Authorization", "Bearer "+line_token)

	_, err = client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
}

func main() {
	http.HandleFunc("/", handler)
	http.ListenAndServe(":8080", nil)
}

動かした

LINE NotifyのTOKENはLINE Notifyのサイトから既に取得済み。

上記プログラムでは、環境変数もしくはGETメソッドのtokenパラメータで指定できるようにした。実際に送るメッセージはmsgパラメータで指定する。

サーバ側は以下のようにして起動しました。

$ LINE_TOKEN=<<LINE NotifyのTOKEN>> go run httpd.go 

これで、localhost:8080で待ち受けするので、別端末から以下のようにリクエスト

$ curl "localhost:8080?msg=こんにちは"

はい、ばっちり通知が届きました。

img

別のLINE端末に送りたいときにはtokenパラメータを指定して以下のように呼べば良いです。

$ curl "localhost:8080/asd?msg=こんにちは&token=<<LINE NotifyのTOKEN>>"

今回のまとめ

  • 基本的なモジュールは使えるようにならないとだめ(C言語でいうと、stdio.h, stdlib.h, string.h あたり?)
  • 変数名などのつけ方にも一定のルールがあるようなので、今後は調査して気を付けていこう
  • どうしてもC言語的な記述になってしまうが、GoLangのお作法も習うようにしよう
  • エラー処理とかは微妙かもだけど、とりあえずhttpリクエスト系の処理が書けたので、検証レベルのプログラムならなんとかなるかも