Go
golang
glide
goa

go言語のgoaでAPIをつくる

go言語のgoaというフレームワークを使ってAPIをつくってみます。
https://goa.design/

go初心者なのですが、習うより慣れろがモットーなので、
まずは、さくっといろいろお触りできる環境をつくりました。
手順のメモです。
(環境は、壊したり汚したりしても良いように、docker上につくりました)

  • centos7
  • go1.9
  • goa v1.3.0
  • glide v0.12.3 (パッケージ管理)

dockerコンテナを準備する

(dockerのインストール手順や扱い方は割愛します)

  • centos7の、docker image を取得する
docker pull centos:7
  • dockerコンテナを起動する
mkdir -p ~/Src/centos7-go
docker run --privileged -it -d -v ~/Src/centos7-go:/go -h go -p 8000:80 --name centos7-go centos:7 /sbin/init

  -v オプション:
   IDE大好き派なので、ローカルで作業できるよう共有ディレクトリを設定してます。
   ローカル環境の作業ディレクトリは、~/Src/centos7-go としました。
  -p
   それなりに動くものができたら、nginxとかで動かしたいために設定してます。
   (本エントリーでは扱いません)

  • dockerコンテナに接続する
docker exec -it centos7-go bash
  • centosの初期設定をば最低限

(地味に時間がかかるので、Dockerfile化 & build した。割愛。)

yum -y update
yum install -y git wget

goをインストールする

  • ダウンロードURLを本家サイトで調べる

https://golang.org/dl/

Kobito.egUJ1M.png

  • ダウンロードして展開する
cd /usr/local/src
wget https://storage.googleapis.com/golang/go1.9.linux-amd64.tar.gz
tar -C /usr/local/ -xzf go1.9.linux-amd64.tar.gz
  • PATHを指定する
vi ~/.bashrc
export GOROOT=/usr/local/go
export GOPATH=/go
export PATH=$PATH:$GOROOT/bin
export PATH=$PATH:$GOPATH/bin
source ~/.bashrc

 $GOPATH(=ローカルPCとの共有ディレクトリに設定)
 ここの配下にプログラムをガシガシつくっていくことになります。

  • インストールできてるか確認する
go version
  • $GOPATH に指定したディレクトリを作成しておく

 必要な場面で「そんなディレクトリないっす」って怒られたので。

mkdir -p $GOPATH/bin

glideをインストールする

rubyにおけるGemfile、PHPにおけるcomposer的なものは存在しないのだろうか?と、
ググってみたらgoにもいろいろありました。
glideが最強との説が多かったので導入します。

  • インストール
curl https://glide.sh/get | sh
  • 確認

$GOPAH/bin の下にインストールされました。

/go
|-- bin
|   `-- glide
`-- src

goaをインストールする

goaのドキュメントを参考にしました。
https://goa.design/design/vendoring/

  • アプリ用のディレクトリを作成する

ソースコードは $GOPATH/src ここの下に配置していくのだそうです。
このあとAPI作成で参考にするチュートリアルのために、cellar というプロジェクトをつくっていきます。

mkdir -p $GOPATH/src/cellar && cd $GOPATH/src/cellar
  • glide 初期化
glide init
  • 確認

glide init コマンドにより、glide.yaml というファイルがつくられます。

/go
|-- bin
|   `-- glide
`-- src
    `-- cellar
        `-- glide.yaml
  • glide.yamlを編集する
package: cellar
import:
- package: github.com/goadesign/goa
  version: master
  vcs: git
  subpackages:
  - client
  - design
  - design/apidsl
  - dslengine
  - goagen
  - middleware
- package: golang.org/x/tools
  subpackages:
  - go/ast/astutil
- package: gopkg.in/yaml.v2
  • パッケージをインストールする

glide.yaml に記載のとおりにパッケージがインストールされます。

glide install -v
  • 確認

    • vendor ディレクトリ以下に、パッケージがインストールされている
    • glide.lock ファイルが作成されている
      • バージョン、ブランチなどの指定は、glide.yaml にちゃんと書けば可能。安心。
      • Github Enterprise 管理とかの独自パッケージもインストールできます。
/go
|-- bin
|   `-- glide
`-- src
    `-- cellar
        |-- glide.lock
        |-- glide.yaml
        `-- vendor
            |-- github.com
            |   |-- armon
            |   |-- dimfeld
            |   |-- goadesign
            |   |-- manveru
            |   |-- satori
            |   |-- spf13
            |   `-- zach-klippenstein
            |-- golang.org
            |   `-- x
            `-- gopkg.in
                `-- yaml.v2
  • goagenをビルドする

実行ファイルが存在しないので、ビルドしてあげます。

cd ./vendor/github.com/goadesign/goa/goagen
go build
cd ../../../../../

※ パッケージが足りません、というエラーが出ると思います。
本エントリの下の方に対応方法を記載しています。

APIデザインを作成して、とりあえず動かしてみる

以降は、以下のサイトを参考に進めます。
https://goa.design/ja/learn/guide/

  • 参考サイトに記載のとおり design.go を作成する

まるっとコピペでOK。

mkdir -p $GOPATH/src/cellar/design
vi $GOPATH/src/cellar/design/design.go
  • 定形コードを生成する

desin.go の内容を元に、定形のディレクトリ構成、必要なファイルが生成されます。
でざいんふぁーすと!

cd $GOPATH/src/cellar
./vendor/github.com/goadesign/goa/goagen/goagen bootstrap -d cellar/design
  • bottle.go を編集する

参考サイトのとおりに編集します。(「Show メソッドを置き換えて」の部分)
import に "fmt" を追加する、という旨の説明が抜けているので、追記する。

vi $GOPATH/src/cellar/bottle.go
  • ここまでやると、APIとりあえず動く! 実行してみる
go run *.go
  • 動作確認
curl -i localhost:8080/bottles/1

以下のような結果が帰ってきました。YATTA〜!

[root@go cellar]# curl -i localhost:8080/bottles/1
HTTP/1.1 200 OK
Content-Type: application/vnd.goa.example.bottle+json
Date: Tue, 05 Sep 2017 05:57:31 GMT
Content-Length: 48

{"href":"/bottles/1","id":1,"name":"Bottle #1"}

ここから、いろいろ肉付けしていきます。

今回はここまで。
おわりです。


appendix

  • パッケージが足りないよのエラー対応

以下のようなエラーが出たら、glide.yaml にパッケージを追記します。

../design/definitions.go:11:2: cannot find package "github.com/dimfeld/httppath" in any of:
    /go/src/cellar/vendor/github.com/dimfeld/httppath (vendor tree)
    /usr/local/go/src/github.com/dimfeld/httppath (from $GOROOT)
    /go/src/github.com/dimfeld/httppath (from $GOPATH)

今回は、最終的にこうなりました。

glide.yaml
package: cellar
import:
- package: github.com/goadesign/goa
  version: master
  vcs: git
  subpackages:


  - client
  - design
  - design/apidsl
  - dslengine
  - goagen
  - middleware
- package: golang.org/x/tools
  subpackages:
  - go/ast/astutil
- package: gopkg.in/yaml.v2
- package: github.com/dimfeld/httppath
- package: github.com/manveru/faker
- package: github.com/satori/go.uuid
- package: github.com/spf13/cobra
- package: github.com/spf13/pflag
- package: github.com/zach-klippenstein/goregen
- package: github.com/armon/go-metrics
- package: github.com/dimfeld/httptreemux
- package: golang.org/x/net/websocket

以下のコマンドで、パッケージの追加インストールを行います。

cd $GOPATH/src/cellar
glide up

感想

未経験なのに突然、RoRやCakePHPのチュートリアルからはじめて、
「ruby, PHP できます!」 などと、宣言したくなってしまう心理が
ほんのちょっぴりだけ、分かったような、分からないような...

実は今回、goをちゃんと学ぶ前に、いきなりgoaの情報から漁るという暴挙に及んでしまったのです。
そのため、いらぬ試行錯誤や失敗が...orz 反省。
間違いや、他の良法などありましたら、コメントいただけますと幸いです。