読者です 読者をやめる 読者になる 読者になる

peroon's diary

game programmer

Golang + echoでAPIサーバを書いてみる

go get github.com/labstack/echo

したら$GOPATH/srcに入る

src/server.goに

ここのserver.goを書いて

go run src/server.go

で実行。http://localhost:1323ChromeからアクセスしてHello Worldが表示された。APIのURLを追加してみよう。

package main

import (
    "net/http"
    "github.com/labstack/echo"
    "github.com/labstack/echo/engine/standard"
)

func main() {
    e := echo.New()
    e.GET("/", func(c echo.Context) error {
        return c.String(http.StatusOK, "Hello, World!")
    })
    e.GET("/user", func(c echo.Context) error {
        return c.String(http.StatusOK, "Hello, user")
    })
    e.Run(standard.New(":1323"))
}

と書き足して、server.goを一度切ってから再実行し、http://localhost:1323/userにアクセス。Hello userが表示された。次はPOSTをしてみよう

package main

import (
    "net/http"
    "github.com/labstack/echo"
    "github.com/labstack/echo/engine/standard"
)

func main() {
    e := echo.New()
    e.GET("/", func(c echo.Context) error {
        return c.String(http.StatusOK, "Hello, World!")
    })
    e.GET("/user", func(c echo.Context) error {
        return c.String(http.StatusOK, "Hello, user")
    })
    e.POST("/user", func(c echo.Context) error {
        return c.String(http.StatusOK, "Hello, POST user")
    })
    e.Run(standard.New(":1323"))
}

書き足してserver.goを再起動し、Chrome ExtensionのPosterなどからPOSTでhttp://localhost:1323/userにアクセスするとHello POST userが表示された

DBと連携させたい。Mongo入れてみよう

brew install mongodb

273MBとか出てたのでサイズは大きい そしてインストール自体にも時間がかかる 10分くらい待ってやっと終わった!と思ったら

Error: Permission denied - /usr/local/var

ここのAnswerの2コマンドを入力。

再度brew installしたら、ビルドは再利用されたのだろう、すぐインストールが完了した

mongoと入力するとバージョンが表示された。Terminalで

sudo mongod

と入力。動いている様子

Terminalの別タブで

mongo

と入力するとクライアント側としてつながった。

> show dbs
local  0.078GB
> db
test
> use mydb
switched to db mydb

保存してみよう

> db.users.save({name:"あいう"})
WriteResult({ "nInserted" : 1 })
> db.users.save({name:"かきく"})
WriteResult({ "nInserted" : 1 })
> db.users.find()
{ "_id" : ObjectId("57a08bcd665449ed6ba92517"), "name" : "あいう" }
{ "_id" : ObjectId("57a08bd8665449ed6ba92518"), "name" : "かきく" }

mydb.usersに2件保存された状態。これをGoからアクセスしたい。Goからmongoに繋ぐパッケージを入れよう

export GOPATH=$HOME/gowork
go get gopkg.in/mgo.v2

とりあえず先ほど挿入したデータとは無関係に、サンプルを実行してみよう

package main

import (
    "fmt"
    mgo "gopkg.in/mgo.v2"
    "gopkg.in/mgo.v2/bson"
)

// Personに共通なものはここにまとめたいですよね
type Person struct {
    ID    bson.ObjectId `bson:"_id"`
    Name  string        `bson:"name"`
    Level int           `bson:"level"`
}

func (p *Person) Greet() string {
    return fmt.Sprintf("My name is %s.", p.Name)
}

// 派生したstructもつくりたいですよね
type Admin struct {
    Person
    Password    string   `bson:"password"`
    Permissions []string `bson:"permissions"`
}

func main() {
    session, _ := mgo.Dial("mongodb://localhost/test")
    defer session.Close()
    db := session.DB("mydb")

    admin := &Admin{
        Person{
            bson.NewObjectId(),
            "otiai10",
            10,
        },
        "hoge",
        []string{"write", "read"},
    }

    db.C("people").Insert(admin)
}

問題なく実行されて、mydb.peopleというCollectionが増えたし、データも入っていた。先ほど挿入したusersの中身も取得したい

package main

import (
    "fmt"
    mgo "gopkg.in/mgo.v2"
    //"gopkg.in/mgo.v2/bson"
)

type User struct {
    Name  string        `bson:"name"`
}

func main() {
    session, _ := mgo.Dial("mongodb://localhost/test")
    defer session.Close()
    db := session.DB("mydb")

    var results []User
    db.C("users").Find(nil).All(&results)
    fmt.Println("Results All: ", results)
}

こう書いて、go run connect.goで実行すると、取得できた。

Results All:  [{あいう} {かきく}]

POSTでuserIdを指定して、指定したユーザを取得するまでできれば、結構良さそう。それは後日 →追記:書きました

peroon.hatenablog.com