LoginSignup
0
1

More than 1 year has passed since last update.

GoのGinで簡易APIサーバー

Last updated at Posted at 2023-03-13

作成:2023年3月13日
前回までで、Goで簡易APIサーバー(GETのみ)とReactで簡易APIクライアントを試作しました。
今回はGinを使って、Goの簡易APIサーバーにPOST等の機能を追加します。

Ginを使ってGET機能作成

Ginをインストールします。
また、CORS (Cross-Origin Resource Sharing ):javascript などで API を叩く時に下記のようなエラーが出る場合のサーバーサイド側の対応として cors をインストールします。

Access to XMLHttpRequest at 'http://api.sample.com' from origin 'http://sample.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

% go mod init example/go-api
go: creating new go.mod: module example/go-api
go: to add module requirements and sums:
	go mod tidy
% go get github.com/gin-gonic/gin
% go get github.com/gin-contrib/cors

GETまでコードを書きます(Github)

main.go
package main

import (
	"github.com/gin-gonic/gin"
	"github.com/gin-contrib/cors"
	"net/http"
	// "strconv"
)

type HealthData struct {
	Month	int		`json:"month"`
	Day		int		`json:"day"`
	Weight	float64	`json:"weight"`
}

var health_data = []HealthData{
	{Month:	1,	Day:	1,	Weight:	55.5},
	{Month:	1,	Day:	2,	Weight:	66.6},
	{Month:	1,	Day:	3,	Weight:	77.7},
}

func getHalthdata(c *gin.Context) {
	c.IndentedJSON(http.StatusOK, health_data)
}

func main() {
	router := gin.Default()

	// CORS 対応
	config := cors.DefaultConfig()
	config.AllowOrigins = []string{"http://localhost:3000"}
	router.Use(cors.New(config))

	router.GET("/health_data", getHalthdata)
	router.Run("localhost:8080")
}

実行して、PostmanでGETできていることが確認できました。

 % go run .
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:	export GIN_MODE=release
 - using code:	gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /health_data              --> main.getHalthdata (3 handlers)
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
[GIN-debug] Listening and serving HTTP on localhost:8080
[GIN] 2023/03/10 - 21:52:00 | 200 |      89.092µs |       127.0.0.1 | GET      "/health_data"

ReactのAPIクライアントでもGETできました(Github)

POST機能を追加

コードを追加します(Githubのコード置き場:qiita20230311

func postHalthdata(c *gin.Context) {
	var newHalthdata HealthData
	if err := c.BindJSON(&newHalthdata); err != nil {
		return
	}
	health_data = append(health_data, newHalthdata)
}

func main() {

	router.POST("/health_data", postHalthdata)

}

実行して Postman でPOSTしてみます。

試しに GET してみたら、ちゃんとデータ追加されていました。

以降の機能追加のために id を追加

コードに追加(Githubのコード:qiita20230311a

main.go
type HealthData struct {
	Id		int		`json:"id"`

var health_data = []HealthData{
	{Id:1, Month:1,	Day:1, Weight:55.5},
App.js
        {getData.map((data) => (
          <li key={data.day}>
            id : {data.id}, month : {data.month}, day : {data.day}, weight : {data.weight}

実行して GET したら id付きで取れています。

指定したidを1件GETする機能

コードを追加します(Githubのコード:qiita20230311c

main.go
func getHealthdataById(c *gin.Context) {
	id, err := strconv.Atoi(c.Param("id"))
	if err != nil {
		return
	}
	for _, t := range health_data {
		if t.ID == id {
			c.IndentedJSON(http.StatusOK, t)
			return
		}
	}
	c.IndentedJSON(http.StatusNotFound, gin.H{"message": "the ID data does not exit!!!"})
}

func main() {

	router.GET("/health_data/:id", getHealthdataById)

id に 2 を指定してデータが取れました。
image.png

PATCH でデータを更新する機能を追加

コードを更新します(Githubのコード置き場:qiita20230312

main.go
func patchHealthdata(c *gin.Context) {
	id, err := strconv.Atoi(c.Param("id"))
	if err != nil {
		return
	}

	var health_data_patch HealthData
	health_data_patch.ID = id
	if err = c.BindJSON(&health_data_patch); err != nil {
		return
	}

	for i, t := range health_data {
		if t.ID == id {
			health_data[i] = health_data_patch
			c.IndentedJSON(http.StatusOK, health_data_patch)
			return
		}
	}
	c.IndentedJSON(http.StatusNotFound, gin.H{"message": "the id's health data not fount"})
}

func main() {

	router.PATCH("/health_data/:id", patchHealthdata)

実行してPostmanで確認すると、id:2が更新されてレスポンスがありました。

DELETE で指定した id のデータを1件削除する機能

コードを更新します(Githubのコード置き場:qiitq20230313b

main.go
func deleteHealthdata(c *gin.Context) {
	id, err := strconv.Atoi(c.Param("id"))
	if err != nil {
		return
	}

	for i, t := range health_data {
		if t.ID == id {
			health_data = append(health_data[:i],health_data[i+1:]...)
			c.IndentedJSON(http.StatusOK, gin.H{"message": "health_data(" + strconv.Itoa(id) + ") is deleted"})
			return
		}
	}
	c.IndentedJSON(http.StatusNotFound, gin.H{"message": "health_data not found"})
}

func main() {

	router.DELETE("/health_data/:id", deleteHealthdata)

実行 % go run . すると、 id:2 が削除されました。

以上で、5つのAPIをGoのGinで実装できました。次は簡易APIクライアントのReactを更新していきたいと思います。

	router.GET("/health_data", getHealthdata)
	router.GET("/health_data/:id", getHealthdataById)
	router.POST("/health_data", postHealthdata)
	router.PATCH("/health_data/:id", patchHealthdata)
	router.DELETE("/health_data/:id", deleteHealthdata)

参考

GoのフレームワークGinを利用してRESTfulAPIを開発する方法
go mod init
Golang フレームワーク Gin で CORS対応
DockerComposeでGoのGinとMySqlの環境を作ってみた-第2弾

0
1
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
0
1