GoではじめるWebAssebmly その4「POST系ネットワーク処理」
WebAssebmlyはWebブラウザ上でバイナリファイル(テキスト形式もあり)を実行できる環境です。JavaScriptと異なりコードの漏洩がなく、実行速度も高速というのがメリットです。
WebAssebmlyは元々Rustで開発することが多かったですが、最近では様々なプログラミング言語が対応しています。その一つがGoです。Go 1.11からWebAssembly向けにもコンパイルできるようになっています。
一般的なWebAssemblyはDOMやネットワーク操作が行えません。それに対してGo 1.11ではJavaScript APIを使えるようにした syscall/js
パッケージを用いることで、DOMやネットワーク操作を可能にしています。
そこで今回はネットワーク処理(POST処理)の書き方を解説します。
使いどころ
POSTやPUT、DELETEはREST APIを扱うのに使われるでしょう。今回はPOSTリクエストでJSONを送信する方法を解説します。
ボタンを押したタイミングで処理
例えば今回はボタンを押したタイミングで入力されている内容をJSON化して送信します。そこでボタンのクリックイベントを設定します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cb1 := js.NewCallback(func(args []js.Value) { | |
// この中に処理を書く | |
}) | |
button.Call("addEventListener", "click", cb1) |
goroutineに注意
ネットワーク処理は非同期なのでデータを安全に送受信するためにgoroutineが使われています。そして単純にPOST処理を書くと、WebAssebmly全体で設定しているgoroutineが終了してデッドロックが発生してしまいました。
そこで処理全体を無名関数化して、それをgoで実行(goroutine化)します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
go func() { | |
todo := document.Call("getElementById", "todo") | |
var value = todo.Get("value").String() | |
input, err := json.Marshal(Input{Todo: value}) | |
res, err := http.Post(domain, "application/json", bytes.NewBuffer(input)) | |
if err != nil { | |
log.Fatal(err) | |
} else { | |
addTodo(document, value) | |
} | |
defer res.Body.Close() | |
}() |
この問題は 1.12 で直る予定です。
CORSに注意
Goでhttp.Postを使っていますが、実際にはWebブラウザのメインスレッド側でリクエスト処理が行われます。CORSは通常のJavaScriptと変わらず行われます。また、ネットワーク接続内容などは開発者ツールで見られますので、隠蔽できる訳ではありません。
Goを使ったWebAssemblyは他の言語では見られないDOM操作とネットワークアクセスが可能です。これは大きなメリットと言えるでしょう。ぜひこの特徴を活用し、高速で安全なWebアプリケーションを開発してください。
コメントは受け付けていません。