GAE(Google App Engine) で Golang 使った REST API(none framework 編) #golang


以前の記事（[GAE(Google App Engine) で Golang を開発するための環境を構築する](https://qiita.com/ynozue/items/d12c1da13bbdb9213ba4)）で環境まで作ったので今回は簡単な REST API を作ってみようと思います。

# こんな順番で進めます
1. 機能概要
2. ソースコード
3. 動作確認（ローカル）
4. 動作確認（GAE）

# 機能概要
* GET / POST に対応
* それぞれパラメータを受け取れる
* レスポンスは JSON 形式
* 対応していない HTTP Method (PUT/DELETE etc) はエラーを返す

# ソースコード
```hello.go
package main

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

// Response 用の構造体
type Result struct {
	Status int
	Description string
}

// hello に対して router を設定
func init() {
	http.HandleFunc("/hello", handler)
}

// hello に binding された function
func handler(w http.ResponseWriter, r *http.Request) {
	var result Result
	switch r.Method {
	case http.MethodGet:
		v := r.FormValue("get_value")
		result = Result{http.StatusOK, "http get result [" + v + "]"}
	case http.MethodPost:
		v := r.FormValue("post_value")
		result = Result{http.StatusOK, "http post result [" + v + "]"}
	default:
		result = Result{http.StatusNotImplemented, "not implemented http mehtod"}
	}
	res, err := json.Marshal(result)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	} else {
		w.Header().Set("Content-Type", "application/json")
		w.Write(res)
	}
}
```

```app.yaml
application: hello-gae-go
version: 1
runtime: go
api_version: go1.8
handlers:
- url: /.*
  script: _go_app
```

# 動作確認（ローカル）
## 起動
```sh
$ goapp serve

INFO     2017-10-08 12:49:16,475 devappserver2.py:115] Skipping SDK update check.
INFO     2017-10-08 12:49:16,535 api_server.py:299] Starting API server at: http://localhost:52820
INFO     2017-10-08 12:49:16,543 dispatcher.py:224] Starting module "default" running at: http://localhost:8080
INFO     2017-10-08 12:49:16,546 admin_server.py:116] Starting admin server at: http://localhost:8000
```
## 動作確認
### GET
```sh
$ curl http://localhost:8080/hello?get_value=test | python -m json.tool

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    53  100    53    0     0   3665      0 --:--:-- --:--:-- --:--:--  3785
{
    "Description": "http get result [test]",
    "Status": 200
}
```
### POST
```sh
$ curl http://localhost:8080/hello -X POST -d "post_value=test" | python -m json.tool
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    69  100    54  100    15   4340   1205 --:--:-- --:--:-- --:--:--  4153
{
    "Description": "http post result [test]",
    "Status": 200
}
```
### PUT
```sh
$ curl http://localhost:8080/hello -X PUT -d "put_value=test" | python -m json.tool
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    72  100    58  100    14   4944   1193 --:--:-- --:--:-- --:--:--  5272
{
    "Description": "not implemented http mehtod",
    "Status": 501
}
```
# 動作確認（GAE）
## 起動
```sh
$ goapp serve

INFO     2017-10-08 12:49:16,475 devappserver2.py:115] Skipping SDK update check.
INFO     2017-10-08 12:49:16,535 api_server.py:299] Starting API server at: http://localhost:52820
INFO     2017-10-08 12:49:16,543 dispatcher.py:224] Starting module "default" running at: http://localhost:8080
INFO     2017-10-08 12:49:16,546 admin_server.py:116] Starting admin server at: http://localhost:8000
```
## 動作確認
### GET
```sh
$ curl https://hello-gae-go.appspot.com/hello?get_value=test | python -m json.tool
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    53  100    53    0     0    912      0 --:--:-- --:--:-- --:--:--   913
{
    "Description": "http get result [test]",
    "Status": 200
}
```
### POST
```sh
$ curl https://hello-gae-go.appspot.com/hello -X POST -d "post_value=test" | python -m json.tool
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    69  100    54  100    15    719    199 --:--:-- --:--:-- --:--:--   710
{
    "Description": "http post result [test]",
    "Status": 200
}
```
### PUT
```sh
$ curl https://hello-gae-go.appspot.com/hello -X PUT -d "put_value=test" | python -m json.tool
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    72  100    58  100    14    787    189 --:--:-- --:--:-- --:--:--   794
{
    "Description": "not implemented http mehtod",
    "Status": 501
}
```

思ったより簡単に REST API っぽいのを作ることができました。

# Appendix
* [ソースコード](https://github.com/ynozue/hello-gae-go/tree/first)