GoでRESTful API をつくる
前回の記事ではGoの練習としてChat Applicationをつくってみました。
今回はRESTful APIをつくってみます。
内容はシンプルなTo Doリストを作ろうかなと思います。
面白みはないけど、他に思いつかない...。
今回の僕の中でのポイントはORMです。
これを通して理解を深めながら、Implementの練習になればいいなと思ってます。
まずRESTful APIとは
RESTful APIとはREpresentational State Transferの略でソフトウェア同士が互いにやりとりするためにAPIの一種。
RESTful APIではURIでリソースを判別しGET、POSTなどのhttpメソッドによってリソースを操作する。
難しい概念で僕の解釈などに間違いがある可能性もあるの注意。
ORMとは
Object-relational mappingの略。
簡単に言うと、オブジェクト指向言語でデータをいじろうと言うことです。多分。
リレーショナルデータベースにアクセスすることなく手慣れた言語でSQLを意識せずデータを操作することができます。
ORMにも色々と種類があります。
今回はGoのORMであるGORMを使います。
※追記(友人からのアップデート): MongoDBのようなドキュメントデータベースには必要であればODM(ObjectDocumentMapping/ObjectDataModeling)という技術を使うらしい。例(Mandango)
今回使用するものたち
- Go
- Gorm
- Gorilla mux
- MySQL
Gorilla mux
webツールキットであるGorilla muxを使ってルーティング制御を行います。
通例どうり4つのエンドポイントを用意します。
Create, Read, Update, Delete
Crudと呼ばれるものですね。
HTTPメソッドと
Create - POST
Read - GET
Update - PUT
Delete - DELETE
このように関連付けます。
実際につくっていく
GOAPI
なるフォルダにmain.go
とtodos.go
を作りました。
忘れないうちに
ゴリラをインストールしておきます。
$ go get github.com/gorilla/mux
Paths
/
今回はpathの動作確認にでも使っておきます
/todos
GET ToDoリストを羅列します
/todo/id
POST 新しくタスクを追加します
/todo/id
PUT すでにあるタスクを操作、編集します
/todo/id
DELETE タスクを削除します
/
まず動作確認もかねてただのテキストを返す/
を作ります
package main
import (
"log"
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func Hello(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello! I'm ok")
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/", Hello).Methods("GET")
log.Fatal(http.ListenAndServe(":8081", r))
}
import "github.com/gorilla/mux"
を忘れずに!
func Hello
まずは/
のリクエスト対応しテキストを返すファンクションを定義しておきます。
後に詳しく説明しますが、内容はただ
"Hello! I'm ok"
を返します(Writerがリスポンスとして書いてくれる?)。
func main
muxを使って新しいラウターを定義します。
HandleFunc
でuri
とそれに対応するレスポンスを紐づけます。
今回はに先ほど定義したfunc Hello
を/
に対応させています。
またMethod("GET")
によりHttpメソッドを指定することができます。
http.ListenAndServe(":8081", r)
によってポート8081でサーバを起動します。
rにはラウターが対応します。
muxなどのルータを使っていなければnil
にするらしい
ここで少し僕的に複雑だったHTTPのあれこれとHandleFunc
などについて詳しく調べて簡単にまとめてみます。興味のない方は飛ばしてね!!!
HandleFuncとかHandlerとか
httpパッケージに置いてhttp.Hadler
はHTTPリクエストに対応してレスポンスを返す。
http.Handle
はURLに対応するhttp.Hadler
を登録します。
http.HandlerFunc
はServeHTTP
を持っているのでこれだけでhttp.Hadler
を用意できます。
http.HandleFunc
はなんか登録します。
あまりよくわからないからまだまだ調べてみる必要がありそう。
メインでmuxを使って行ったことはhttp.HandleFunc
と同じことをしているらしい。
リクエストされたURLがパスにマッチしたら(http.ResponseWriter, *http.Request)
をパラメーターとしてハンドラーを呼び出します。
動作確認
go run main.go
走らせてみます。
http://localhost:8081
でHello! I'm ok
が表示されました!!
とりあえず無事ルートは確立できてるようです。
同じ要領でとりあえずパスを簡単なファンクションに紐付けてどんどんつくってしまいます。
- 他のパス
新しくtodo.go
を作ります。
package main
import (
"fmt"
"net/http"
)
func GetTodos(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "This is a Todos list")
}
func CreateTodo(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Successfully created new Todo")
}
func UpdateTodo(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Successfully updated Todo")
}
func DeleteTodo(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Destroyed that disgusting Todo")
}
さっきと同じでそれぞれの違ったテキストを入れました。
動作確認をしましょう。
動作確認
動作確認にはPostmanを使います。
PostmanはAPI構築の大きな助けになる便利なツールです!!
今回はHTTPリクエストとそれに対するリスポンスがちゃんと動作しているかを確認するのに使います。

メソッドの指定やURLの指定ができ、レスポンスが下の画面に現れます。
早速、go run .go
で走らせて、リクエストを送ってみます。


うまくできました!
他のもうまくできました!
ルートは無事マッピングできたようです!
まとめ
長くなりそうなので今回はここで区切って
次にORMを使ったデータの実装をしてみたいと思います。
サーバの確立は比較的簡単に実装できますね。
ただhttpのあれこれを完璧に理解しているかと言われると理解していないのでまだまだ研究が必要。