go言語でhtmlから取得したデータをjson形式で保存する

# Goの勉強録
昨日あたりからGoに対するエンジニアの成長曲線の傾きが正に大きい部分に入ったのでは？と思うくらいGoを書くのが開発環境構築したてのころと比べて苦じゃ無くなりました。以前はエラーが出ると何処エラーしてるんやとか、うーんわからんみたいな感情があったのですが、結構早くエラーにならないように記述する事ができるようになりました。(潜在的なバグなどはわかりませんけれど。。)
昨日JavaScriptから送られて来るリクエストからデータを取得してコンソールに出力することができ、取得したこのデータを煮るなり焼くなりと言ったのでまずは手始めに、JSON形式で外部ファイルに保存しようと思いました。
あっさりJSONファイルにデータを保存することができたのでブログに残しておきます。

ちなみに過去のGo勉強録記事は下から飛べるようにしています。
### 過去の記事
* [Go言語の環境構築 Hello Worldまで](https://qiita.com/lkeix_/items/161d448bea2547ae2d8b)
* [go言語 静的ページの作成](https://qiita.com/lkeix_/items/a5005efed487bba7c36e)
* [AngularJSのhttp通信からのpostリクエストをgo側で取得](https://qiita.com/lkeix_/items/8f859415cc87a1e9ca07)

## 本題
go言語はPHPやruby on rails、Node.js(サーバサイド)と言った言語と同じようにサーバサイドのプログラムを記述することができます。サーバサイドのプログラムを記述できるということは、サーバから必要なデータを引っ張ってきたり、データを書き込んだりするのが主な動作になります。
そこで今回はデータを書き込むという如何にもサーバサイドの動作を実装しました。

ちなみにワークスペースの階層は以下のようになっています。Dataの中にdata.jsonが作られるようにします。(新幹線で作業をしたのでAngularのフレームワークをHTMLの中にぶっこんでいます。)
昨日のものを少しカスタマイズした感じですね。

```
workspace/
  ├ Data/ 
  │
  ├ HTML/
  │    ├ index.html
  │    ├ test.js
  │    ├ Angular.min.js
  │
  ├ POST/
  │    ├ Process.go
  │
  ├ Host.go
```

## ソースコード
Host.go
サーバを立てて、来るリクエストに対してデータを取得し、jsonに書き込むという処理が記述されています。

```go:Host.go
package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"

	"./Post"
)

func main() {
	HostingServer()
}

// Json形式でデータを保存するようにHandleを定義
func SaveJson() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		// ファイルの生成
		file, err := os.Create("./Data/data.json")
		if err != nil {
			fmt.Println("ファイルの生成に失敗しました")
		}
		defer file.Close()
		// Process.goからGetDataを呼び出し、リクエストのデータをData形式で取得する
		var data = Post.GetData(w, r)
		// 出力用にData形式のdataをjson形式にencode
		encodedjson, _ := json.Marshal(&data)
		// 正常に生成されたファイルに書き込み
		file.Write(([]byte)(string(encodedjson)))
		// エンコードされたデータをコンソールに表示
		fmt.Println(string(encodedjson))
	})
}

// サーバを立てる処理
func HostingServer() {
	// Handlerの追加
	SaveJson()
	dir, _ := os.Getwd()
	// サーバを立てる為にstripprefixを設定
	fileserver := http.FileServer(http.Dir(dir + "/HTML/"))
	stripprefix := http.StripPrefix("/datatest/", fileserver)
	http.Handle("/datatest/", stripprefix)
	// serve :8080
	log.Fatal(http.ListenAndServe(":8080", nil))
}

```

Process.go
リクエストのデータをData形式で取得し、それを返す処理をしています。

```go:Process.go
package Post

import (
	"encoding/json"
	"fmt"
	"net/http"
	"reflect"
)

type Data struct {
	Name   string
	Age    int
	Gender string
}

func GetData(w http.ResponseWriter, r *http.Request) Data {
	// parse
	r.ParseForm()
	var data = Data{}
	decoder := json.NewDecoder(r.Body)
	decoder.Decode(&data)
	fmt.Println(reflect.TypeOf(data))
	return data
}
```

index.html
表示用のスクリプト

```HTML:index.html
<!DOCTYPE html>
<html ng-app="idx">
    <head>
        <title>FileIO</title>
        <script src="./Angular.min.js"></script>
        <script src="./test.js"></script>
    </head>
    <body ng-controller="form">
        <input type="text" ng-model="name">
        <br />
        <input type="number" ng-model="age">
        <br />
        男:<input type="radio" ng-model="gender" value="man">
        <br />
        女:<input type="radio" ng-model="gender" value="woman">
        <br />
        <input type="button" ng-click="req()" value="送信">
    </body>
</html>
```

test.js
index.htmlでボタンを押された時に呼び出すイベントリスナーを定義しています。

```JavaScript:test.js
var idx = angular.module("idx",[])

idx.controller("form",function($scope,$http){
    $scope.req = function(){
        // 送信用のデータ
        data = {
            name: $scope.name,
            age: $scope.age,
            gender: $scope.gender
        }
        // POSTでhttp通信
        $http({
            method: 'POST',
            url: '../Host.go',
            contentType: 'application/JSON',
            data: data
        }).then(function DoneCallback(res){
          console.log("通信成功");
          console.log(res)
        },function failCallback(res){
            console.log("通信失敗");
        });
    }
})
```

`go run Host.go`を実行し、`http://localhost:8080/datatest/`にアクセスすると
簡易的な入力フォームができています。
そこに値を入力しボタンを押すと`Data/data.json`が生成され、中身は

```JSON:data.json
{"Name":"test","Age":20,"Gender":"woman"}
```

とJSON形式で保存されます。

## まとめ
go側で無事データをJSON形式で保存する事ができました。（ようやく面白くなってきたぞ(-ω- )o）
次はファイルの読み込みなどを書くと思います。後々DBなどの接続や、並列処理と言った所の記事がかけていけたらなと思っています！(勉強することは山積みですな)
まだまだ、go初心者なので間違っている部分があれば、気軽にコメントを描いてください！