LoginSignup
10
11

More than 5 years have passed since last update.

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

Posted at

以前の記事(GAE(Google App Engine) で Golang 使った REST API)を作りましたが、今回は echo (Golang 用のフレームワーク) を使った REST API を作ってみようと思います。

Google App Engine 用のサンプルはこちらを参考にしました。

プログラム構成

基本的にはサンプルプログラム通りですが、root ディレクトリに通常の go コマンドからの起動用のコード(app-standalone.go)を置いて本体のプログラムは gae_echo ディレクトリ直下に配置しています。

$ tree
├── README.md
├── app-standalone.go
└─── gae_echo
    ├── app-engine.go
    ├── app-engine.yaml
    ├── app.go
    └── users.go

ソースコード

通常の go コマンドからの起動用のプログラムと echo インスタンス生成用のコードになります。

app.go
package gae_echo

// reference our echo instance and create it early
var e = createMux()

func Start() {
    e.Logger.Fatal(e.Start(":8080"))
}

通常の go コマンドからの起動用のプログラムと echo インスタンス生成用のコードになります。

app-engine.go
package gae_echo

import (
    "net/http"

    "github.com/labstack/echo"
)

func createMux() *echo.Echo {
    e := echo.New()
    // note: we don't need to provide the middleware or static handlers, that's taken care of by the platform
    // app engine has it's own "main" wrapper - we just need to hook echo into the default handler
    http.Handle("/", e)
    return e
}

ユーザー情報(IDと名前だけだけど、、、)を登録/参照する API の本体で、データをメモリ上に保存します。

users.go
package gae_echo

import (
    "net/http"

    "github.com/labstack/echo"
    "github.com/labstack/echo/middleware"
)

type (
    user struct {
        ID   string `json:"id"`
        Name string `json:"name"`
    }
)

var (
    users map[string]user
)

func init() {
    users = map[string]user{
        "1": user{
            ID:   "1",
            Name: "Wreck-It Ralph",
        },
    }

    // hook into the echo instance to create an endpoint group
    // and add specific middleware to it plus handlers
    g := e.Group("/users")
    g.Use(middleware.CORS())

    g.POST("", createUser)
    g.GET("", getUsers)
    g.GET("/:id", getUser)
}

func createUser(c echo.Context) error {
    u := new(user)
    if err := c.Bind(u); err != nil {
        return err
    }
    users[u.ID] = *u
    return c.JSON(http.StatusCreated, u)
}

func getUsers(c echo.Context) error {
    return c.JSON(http.StatusOK, users)
}

func getUser(c echo.Context) error {
    return c.JSON(http.StatusOK, users[c.Param("id")])
}

サンプルの yaml から必要な部分だけ抜き出しています。

app-engine.yaml
application: hello-gae-go
version: 1
runtime: go
api_version: go1.8

handlers:
- url: /.*
  script: _go_app

サンプルはうまく動かなかったので、ちょっと変更しています。

app-standalone.go
// +build !appengine,!appenginevm

package main

import (
    "github.com/ynozue/hellow-gae-go/gae_echo"
)

func main() {
    gae_echo.Start()
}

動作確認

起動

$ goapp serve gae_echo/app-engine.yaml

INFO     2017-10-15 13:47:45,383 devappserver2.py:115] Skipping SDK update check.
INFO     2017-10-15 13:47:45,528 api_server.py:299] Starting API server at: http://localhost:57500
INFO     2017-10-15 13:47:45,539 dispatcher.py:224] Starting module "default" running at: http://localhost:8080
INFO     2017-10-15 13:47:45,541 admin_server.py:116] Starting admin server at: http://localhost:8000

curl での動作確認

一覧参照

$ curl http://localhost:8080/users | python -m json.tool

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    74  100    74    0     0   3755      0 --:--:-- --:--:-- --:--:--  3894
{
    "1": {
        "id": "1",
        "name": "Wreck-It Ralph"
    }

登録

$ curl -X POST \
 -H 'Content-Type: application/json' \
 -d '{"id":"2","name":"Joe Smith"}' \
 http://localhost:8080/users | python -m json.tool

    % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    58  100    29  100    29    896    896 --:--:-- --:--:-- --:--:--   906
{
    "id": "2",
    "name": "Joe Smith"
}

一覧参照(登録後)

$ curl http://localhost:8080/users | python -m json.tool
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    74  100    74    0     0   3755      0 --:--:-- --:--:-- --:--:--  3894
{
    "1": {
        "id": "1",
        "name": "Wreck-It Ralph"
    },
    "2": {
        "id": "2",
        "name": "Joe Smith"
    }
}

詳細参照

$ curl http://localhost:8080/users/2 | python -m json.tool

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    29  100    29    0     0   2759      0 --:--:-- --:--:-- --:--:--  2900
{
    "id": "2",
    "name": "Joe Smith"
}

まとめ

net/http パッケージを利用するよりかは POST データのパースや URI に対応するプログラムの切り分けなどが簡単にできました。
echo には色々な機能が用意されてるみたいなので、サンプルを試しながら調べていこうかと思います。

Appendix

10
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
11