36
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Goで簡易的なAPIサーバーを立てる

Posted at

Goで簡易的なAPIサーバーを作ってみました。
フレームワークに頼る前に自分でシンプルな構成で立ててみたかったので、今回はフレームワークは使いません

環境

  • MacOS 10.15.2
  • go version go1.14.4 darwin/amd64
  • mysql 8.0.19

インストール

brewに従います。

brew install go

hello world

こんにちは世界

package main

import "fmt"

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

fmt は入出力系のパッケージです。
他言語でみたことある方は違和感なく使えそうです。

HTTP server 構築

net/http はHTTP client and server のパッケージです。
なんとたったこれだけでHTTP serverが立てられてしまうそうです。すごい

package main

import (
  "fmt"
  "log"
  "net/http"
)

func homePage(w http.ResponseWriter, r *http.Request){
  fmt.Fprintf(w, "Welcome to the HomePage!")
  fmt.Println("Endpoint Hit: homePage")
}

func handleRequests() {
  http.HandleFunc("/", homePage)
  log.Fatal(http.ListenAndServe(":8081", nil))
}

func main() {
    handleRequests()
}

Get リクエストを送ると設定しているテキストが返ってきます。
image.png

JSON 形式での返却

通常のAPIサーバーではJSON形式が返って来るのが一般的です
structencoding/json を使って、よくあるAPI形式で結果を返却してみます
https://golang.org/pkg/encoding/json/

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
)

type Article struct {
	Title   string `json:"Title"`
	Desc    string `json:"desc"`
	Content string `json:"content"`
}

type Articles []Article

func homePage(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Welcome to the HomePage!")
	fmt.Println("Endpoint Hit: homePage")
}

func handleRequests() {
	http.HandleFunc("/", homePage)
	http.HandleFunc("/articles", returnAllArticles)
	log.Fatal(http.ListenAndServe(":8081", nil))
}
func returnAllArticles(w http.ResponseWriter, r *http.Request) {
	articles := Articles{}
	for i := 0; i < 10; i++ {
		title := "Hello_%d"
		articles = append(
			articles,
			Article{Title: fmt.Sprintf(title, i), Desc: "Article Description", Content: "Article Content"})
	}
	fmt.Println("Endpoint Hit: returnAllArticles")
	json.NewEncoder(w).Encode(articles)
}

func main() {
	handleRequests()
}

image.png

こちらの記事を完全参考にしました。。。ありがたいです!
https://hodalog.com/creating-restfulapi-with-golang/

DBの内容を返却

APIで返却する内容はDBへのSQL結果を利用する場合が多いです。
gorm と言うORMを利用し、実現しました

環境準備

go get でパッケージのインストールをします

$ go get github.com/jinzhu/gorm
$ go get github.com/go-sql-driver/mysql

テーブル作成

gorm でマイグレーションの機能があるのですが普通にcreate tableで作成しました。

CREATE TABLE `gorm-example`.`players` (
  `id` INT NOT NULL,
  `name` VARCHAR(255) NULL,
  `created_at` DATETIME NULL,
  `updated_at` DATETIME NULL,
  `deleted_at` DATETIME NULL,
  PRIMARY KEY (`id`));

DB接続and データ取得

GetDBConn() GetDBConfig() でDB接続処理を行い
fetchPlayers でデータ取得した結果をJSONに変更して返却しています。

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"

	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)

type Player struct {
	gorm.Model
	Name string
}

var player Player
var players []Player

func handleRequests() {
	http.HandleFunc("/", homePage)
	http.HandleFunc("/players", fetchPlayers)
	log.Fatal(http.ListenAndServe(":8081", nil))
}

func fetchPlayers(w http.ResponseWriter, r *http.Request) {
	db := GetDBConn()

	db.Find(&players)
	fmt.Println(players)
	profJson, _ := json.Marshal(players)
	fmt.Fprintf(w, string(profJson))
}

func GetDBConn() *gorm.DB {
	db, err := gorm.Open(GetDBConfig())
	if err != nil {
		panic(err)
	}

	db.LogMode(true)
	return db
}

func GetDBConfig() (string, string) {
	DBMS := "mysql"
	USER := "root"
	PASS := ""
	PROTOCOL := ""
	DBNAME := "gorm-example"
	OPTION := "charset=utf8&parseTime=True&loc=Local"

	CONNECT := USER + ":" + PASS + "@" + PROTOCOL + "/" + DBNAME + "?" + OPTION

	return DBMS, CONNECT
}

func homePage(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Welcome to the HomePage!")
	fmt.Println("Endpoint Hit: homePage")
}

func main() {
	handleRequests()
}

データを取得すると想定通りに値が返ってきています。
(何故か大文字になるけど)

image.png
参考記事: https://medium.com/@taka.abc.hiko/gorm%E3%81%A8%E3%81%84%E3%81%86orm%E3%81%8C%E8%B6%85%E7%B5%B6%E4%BE%BF%E5%88%A9%E3%81%A0%E3%81%A3%E3%81%9F%E4%BB%B6-8d279489c38f

まとめ

  • GoでAPIサーバーを立てるのは、標準ライブラリが揃ってて簡単
  • ルーター/認証などフレームワークに乗っ取ったりする部分はどうするかまだわからない

最後に

visual stadio code のGoが素晴らしい。型安全(๑˃̵ᴗ˂̵)
image.png

36
16
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
36
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?