JSON ServerでダミーのAPIサーバをローカルに立ててみた

npmのためにnode jsを入れる https://nodejs.org/en/download/

Qiitaを参考に、http://qiita.com/yhikishima/items/46860ffc48913182a3ee

sudo npm install -g json-server

json.dbに書くJSONをここから確保 http://json.org/example.html json lintも通ることを確認

http://localhost:3000/Chromeからアクセスすると、動いてるよーという表示 http://localhost:3000/glossary にアクセスすると、JSONが表示

POSTでデータ保存できるらしい

curl -X POST http://localhost:3000/glossary -d title=fugafuga

やってみると、json.dbの値が書き換わった http://localhost:3000/glossary で返ってくるJSONも書き換わった後のものになる

curl -X POST http://localhost:3000/glossary -d aaa=bbb

としても書き換わる

curl -X POST http://localhost:3000/new -d aaa=bbb

としたらnewでJSON取得できると思ったけどできなかった。空が返ってくる {}

db.jsonを見てみると

{
  "glossary": {
    "aaa": "bbb"
  }
}

となっている。ここにnewがないから保存されなかったのか。

{
  "glossary": {
    "aaa": "bbb"
  },
  "new":{
    "ccc": "ddd"  
  }, 
  "xxx":{
    "yyy": "zzz"  
  }
}

こんな感じにエディタで追記すると、watchされているのでサーバは生きたまま反映される。ただしJSONの文法が違うとQuitされるので、事前にlintでチェックしておくといい

これでダミーの固定JSONを返すローカルのAPIサーバは立てることができた。次はDBとつなげてみたい。

Goでバッチ処理。system()など叩いてみた

DL https://golang.org/dl/

package main

import "fmt"

func main() {
    fmt.Printf("hello, world\n")
}

を保存して

go run hello.go

としたら実行できた。ruby hello.rb と同じ感じ。systemさえ叩ければいいかなと思い

package main

import "fmt"
import "os/exec"

func main() {
out, err := exec.Command("ls").Output()
fmt.Println(out) // 数値が出力される
fmt.Println(string(out)) // lsの結果が文字列で出力される
fmt.Println(err) // nil
}

これでsystem()は実行できた。GUIは決定版がないようなので、保留。一連のコマンド処理の自動化だとRubyの方が記述量が少なくて楽という印象。APIサーバ作るとかだとGoがいいんだろう。

blog.amedama.jp

その後に上記記事の「自作のプロジェクトを GitHub で管理する」まで読んだ。バイナリ化、パッケージ化して別コードから使う、テスト用コードまで理解した。

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