---
# System prepended metadata

title: 'Day 15 : Golang Gin(1) - 簡單HTTP Request'
tags: [About Go]

---

# Day 15 : Golang Gin(1) - 簡單HTTP Request 

## Getting and Run Gin
第一次使用可以透過 `go get -u github.com/gin-gonic/gin` 進行安裝
接下來就是使用Gin拉，首先透過`router  := gin.Default()`建立預設的路由引擎，這用來之後增加middleware和處裡請求，且由於Gin有支援RESTful，可以直接透過`router.`的方式來執行各種HTTP請求，最後透過router.Run(":8080")讓路由器在8080 port運轉。
其中關於Context的定義可以參考[官方文件](https://pkg.go.dev/github.com/gin-gonic/gin@v1.9.0#Context)。

```go!
package main

import "github.com/gin-gonic/gin"

func main(){
    router  := gin.Default()
    router.GET("/user",user)
    router.POST("/user/:id",addUser)
    router.Run(":8080")
}


func user(c *gin.Context){
    c.JSON(200,gin.H{
    	"name":"dylan",
    })
}

func addUser(c *gin.Context){
    id := c.Param("id")
    c.JSON(200,gin.H{
    	"id":id,
    	"name":"dylan",
    })
}
```
使用postman看到，使用POST 請求到/member/:id，可以回傳正確的結果
![](https://i.imgur.com/Re3oj61.png)
(圖一，參考來源:Postman)

## HTTP GET、POST、DELETE、PUT
這邊依照RESTful API的風格設計檢的新增刪除使用者的API，可以讓我們由路由就知道要對資料進行什麼操作。
接下來會新增三個檔案，分別是User.go、UserService.go、UserRouter.go，僅將main.go當作程式執行的入口
:::info
│  go.mod
│  go.sum
│  main.go
│
├─models
│&emsp;&emsp;User.go
│
├─service
│&emsp;&emsp;UserService.go
│
├─route
│&emsp;&emsp;UserRouter.go
:::
下面為修改過後的main.go和新增的UserRouter.go。
在main.go都過Group將路由做分配，如果是`"/api"`路徑開頭的全部放到`api`這個路由組。接著將定義好的`api`路由組當作參數，傳遞給AddUserRouter()函式，這裡面會定義如何再根據不同的路由規則，回應不同的handler function。
```go=
// main.go
package main

import (
    "golangGinPractice/route"
    "github.com/gin-gonic/gin"
)

func main(){
    router  := gin.Default()
    api := router.Group("/api")
    route.AddUserRouter(api)
    router.Run(":8080")
}
```


```go=
// UserRouter.go
package route

import (
    "github.com/gin-gonic/gin"
    "golangGinPractice/service"
)

func AddUserRouter(r *gin.RouterGroup) {
    user := r.Group("/users")
    user.GET("/", service.FindAllUsers)
    user.POST("/",service.PostUser)
    user.DELETE("/:id",service.DeleteUser)
    user.PUT("/:id",service.PutUser)
}

```
User.go 用結構體定義一個我們需要的類別。
```go=
// User.go
package models

type User struct {
    Id int `json:"UserId"`
    Name string `json:"UserName"`
    Password string `json:"UserPassword"`
    Email string `json:"UserEmail"`
}
```
handler function都記錄在UserService.go檔案
```go=
// UserService.go
package service

import (
	"golangGinPractice/models"
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
)

var userList = []models.User{}

// Get user
func FindAllUsers(c *gin.Context) {
	c.JSON(http.StatusOK, userList)
}

// Post user
func PostUser(c *gin.Context) {
	user := models.User{}
	err := c.BindJSON(&user)
	if err != nil {
		c.JSON(http.StatusNotAcceptable, "Error :"+err.Error())
	}
	userList = append(userList, user)
	c.JSON(http.StatusOK, "Successfully posted")
}

// Delete user
func DeleteUser(c *gin.Context) {
	userId, _ := strconv.Atoi(c.Param("id"))
	for index, user := range userList {
		if userId == user.Id {
			userList = append(userList[:index], userList[index+1:]...)
			c.JSON(http.StatusOK, "Successfully deleted")
			return
		}
	}
	c.JSON(http.StatusGone, "Error")
}

// Put user
func PutUser(c *gin.Context) {
	updateUser := models.User{}
	err := c.BindJSON(&updateUser)
	if err != nil {
		c.JSON(http.StatusNotAcceptable, "Error :"+err.Error())
	}
	userId, _ := strconv.Atoi(c.Param("id"))
	for index, user := range userList {
		if userId == user.Id {
			userList[index] = updateUser
			c.JSON(http.StatusOK, "Successfully updated")
			return
		}
	}
	c.JSON(http.StatusNotFound, "Error")
}
```
接下來透過下面gif檔案顯示透過Postman執行各個路由的結果

![](https://i.imgur.com/W783p7U.gif)



## Referencs
1. https://github.com/gin-gonic/gin
2. https://www.youtube.com/playlist?list=PLKDLBB0AVnh66JwQA9nWLwoncG96vkE2N
3. https://ithelp.ithome.com.tw/articles/10275626
4. https://ithelp.ithome.com.tw/articles/10269133

###### tags: `About Go`