使用Go,Gin和Gorm開發(fā)簡單的CRUD API

原文鏈接:https://medium.com/@cgrant/developing-a-simple-crud-api-with-go-gin-and-gorm-df87d98e6ed1
翻譯:devabel

介紹

Golang是一種令人興奮的語言,但新手可能會(huì)被新的語法和各種框架所淹沒。基礎(chǔ)知識(shí)入門可能會(huì)成為一項(xiàng)挑戰(zhàn)。

在這個(gè)例子中,我想展示創(chuàng)建功能API所需的最少代碼。我們將開發(fā)一個(gè)簡單的API,為基本模型提供創(chuàng)建,讀取,更新和刪除(CRUD)功能。使用和對(duì)象關(guān)系映射(ORM)工具,我們將能夠快速更新我們的數(shù)據(jù)模型,所有數(shù)據(jù)模型都在100行代碼之下。所以讓我們開始吧。

https://github.com/cgrant/gin-gorm-api-example可以找到這篇文章的所有代碼。

入門

這個(gè)例子假設(shè)你已經(jīng)安裝并運(yùn)行g(shù)o語言的環(huán)境。如果您還沒有安裝,請(qǐng)轉(zhuǎn)到http://cgrant.io/tutorials/go/getting-started-with-go/獲取快速入門。

Gin Web框架

由于我們將通過HTTP提供我們的API,因此我們需要一個(gè)Web框架來處理路由并提供請(qǐng)求。有許多框架可用,具有不同的功能和性能指標(biāo)。在這個(gè)例子中,我們將使用Gin框架https://github.com/gin-gonic/gin 。由于速度和簡單性,Gin是API開發(fā)的一個(gè)很好的框架。

首先,讓我們?cè)? GOPATH / src / simple-api中為我們的服務(wù)創(chuàng)建一個(gè)新文件夾,然后添加一個(gè)main.go文件,如下所示

package main

import “fmt”

func main() {
 fmt.Println(“Hello World”)
}

在我們繼續(xù)學(xué)習(xí)前,讓我們測試一下,確保一切正常運(yùn)行。

$ go run main.go
Hello World

程序運(yùn)行正常?,F(xiàn)在讓我們使用Gin框架將它變成一個(gè)Web應(yīng)用程序。

package main

import “github.com/gin-gonic/gin”

func main() {
 r := gin.Default()
 r.GET(“/”, func(c *gin.Context) {
 c.String(200, “Hello World”)
 })
 r.Run() 
}

保存并運(yùn)行它

$ go run main.go
[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 / → main.main.func1 (3 handlers)
[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[GIN-debug] Listening and serving HTTP on :8080
[GIN] 2016/12/02–14:57:52 | 200 | 33.798μs | ::1 | GET /

然后瀏覽器訪問http://localhost:8080/

Hello World

成功!?。?/p>

我們正在構(gòu)建一個(gè)API,但不是一個(gè)Web應(yīng)用程序,所以讓我們將其切換到JSON響應(yīng)

package main

import “github.com/gin-gonic/gin”

func main() {
 r := gin.Default()
 r.GET(“/”, func(c *gin.Context) {
 c.JSON(200, gin.H{
 “message”: “Hello World”,
 })
 })
 r.Run() // listen and server on 0.0.0.0:8080
}

保存文件,重新運(yùn)行并刷新瀏覽器,您應(yīng)該看到我們的JSON 消息
{“message”:“Hello World”}

GORM的數(shù)據(jù)持久性

現(xiàn)在讓我們看看我們的持久層。對(duì)于本節(jié)我們將使用本地的基于SQLite文件的數(shù)據(jù)庫開始。稍后我們將切換到使用MySql來證明。

Gorm http://jinzhu.me/gorm/是一個(gè)用于go的對(duì)象關(guān)系映射(ORM)框架。它大大簡化了模型到數(shù)據(jù)庫的映射和持久化。盡管我不是大型復(fù)雜系統(tǒng)的ORM的忠實(shí)擁躉,但他們對(duì)原型開發(fā)新的綠地應(yīng)用程序確實(shí)很有效。Gorm在Go領(lǐng)域是一個(gè)非常受歡迎的工具,我們將在這里看看它。

為了解決gorm問題,我們將把我們剛寫的Gin代碼換掉,并且演示一下gorm的功能。學(xué)習(xí)完這塊,我們會(huì)將Gin重新添加到應(yīng)用程序中。

讓我們開始一個(gè)小例子。

package main

import (
 “github.com/jinzhu/gorm”
 _ “github.com/jinzhu/gorm/dialects/sqlite”
)

func main() {
 db, _ := gorm.Open(“sqlite3”, “./gorm.db”)
 defer db.Close()

}

如果你現(xiàn)在運(yùn)行這個(gè)程序,你會(huì)在你的文件系統(tǒng)中看到一個(gè)名為gorm.db的新文件。這是我們的數(shù)據(jù)庫文件系統(tǒng)將在應(yīng)用程序中使用。雖然我們可以看到我們的應(yīng)用程序正在運(yùn)行,而且gorm正在被使用,但我們的系統(tǒng)還沒有完成。讓我們添加更多的代碼。

package main

import (
 “fmt”

“github.com/jinzhu/gorm”
 _ “github.com/jinzhu/gorm/dialects/sqlite”
)

type Person struct {
 ID uint `json:”id”`
 FirstName string `json:”firstname”`
 LastName string `json:”lastname”`
}

func main() {
 db, _ := gorm.Open(“sqlite3”, “./gorm.db”)
 defer db.Close()

 p1 := Person{FirstName: “John”, LastName: “Doe”}
 p2 := Person{FirstName: “Jane”, LastName: “Smith”}

 fmt.Println(p1.FirstName)
 fmt.Println(p2.LastName)

}

在這里,我們剛剛添加了一個(gè)簡單的Person結(jié)構(gòu),并在使用它們打印出值之前創(chuàng)建了一些實(shí)例。請(qǐng)記住,Person結(jié)構(gòu)中的字段需要以大寫字母開頭,因?yàn)镚o定義這些是公共字段。

現(xiàn)在我們已經(jīng)有了一個(gè)可以使用Gorm的對(duì)象。

package main

import (
 “fmt”

“github.com/jinzhu/gorm”
 _ “github.com/jinzhu/gorm/dialects/sqlite”
)

type Person struct {
 ID uint `json:”id”`
 FirstName string `json:”firstname”`
 LastName string `json:”lastname”`
}

func main() {
 db, _ := gorm.Open(“sqlite3”, “./gorm.db”)
 defer db.Close()

 db.AutoMigrate(&Person{})

 p1 := Person{FirstName: “John”, LastName: “Doe”}
 p2 := Person{FirstName: “Jane”, LastName: “Smith”}

 db.Create(&p1)
 var p3 Person // identify a Person type for us to store the results in
 db.First(&p3) // Find the first record in the Database and store it in p3

 fmt.Println(p1.FirstName)
 fmt.Println(p2.LastName)
 fmt.Println(p3.LastName) // print out our record from the database

}

現(xiàn)在讓我們運(yùn)行它,看看輸出什么

$ go run main.go
John
Smith
Doe

哇,非常簡單。只需幾行代碼,我們就可以保存并從數(shù)據(jù)庫中檢索。Gorm在如何存儲(chǔ)和查詢他們的網(wǎng)站上有更多的選項(xiàng)。接下來我們將介紹幾個(gè)核心部分,但請(qǐng)查看他們的文檔以獲取更多選項(xiàng)。

制作API

我們已經(jīng)回顧了框架如何獨(dú)立運(yùn)作。現(xiàn)在是時(shí)候把所有東西放在一起成為一個(gè)可用的API

查詢所有信息

讓我們從查閱我們之前添加的數(shù)據(jù)開始閱讀CRUD的部分。我將刪除我們剛剛通過的一些行,并用一個(gè)新路由添加到Gin框架中,以查詢我們的數(shù)據(jù)庫。

package main

import (
 “fmt”

 “github.com/gin-gonic/gin”
 “github.com/jinzhu/gorm”
 _ “github.com/jinzhu/gorm/dialects/sqlite”
)

var db *gorm.DB
var err error

type Person struct {
 ID uint `json:”id”`
 FirstName string `json:”firstname”`
 LastName string `json:”lastname”`
}

func main() {

 // NOTE: See we’re using = to assign the global var
 // instead of := which would assign it only in this function
 db, err = gorm.Open(“sqlite3”, “./gorm.db”)
 if err != nil {
   fmt.Println(err)
 }
 defer db.Close()

 db.AutoMigrate(&Person{})

 r := gin.Default()
 r.GET(“/”, GetProjects)

 r.Run(“:8080”)
}

func GetProjects(c *gin.Context) {
 var people []Person
 if err := db.Find(&people).Error; err != nil {
    c.AbortWithStatus(404)
    fmt.Println(err)
 } else {
    c.JSON(200, people)
 }

}

現(xiàn)在運(yùn)行它并轉(zhuǎn)到http://localhost:8080/,你應(yīng)該看到

[{“id”: 1,”firstname”: “John”,”lastname”: “Doe”}]

哇只是幾行代碼,我們已經(jīng)獲得API響應(yīng)。大部分都是錯(cuò)誤處理!

查詢單條信息

OK讓我們以REST為導(dǎo)向更新上下文,并增加查找單條信息的功能。

package main

import (
 “fmt”

 “github.com/gin-gonic/gin”
 “github.com/jinzhu/gorm”
 _ “github.com/jinzhu/gorm/dialects/sqlite”
)

var db *gorm.DB
var err error

type Person struct {
 ID uint `json:”id”`
 FirstName string `json:”firstname”`
 LastName string `json:”lastname”`
}

func main() {

 // NOTE: See we’re using = to assign the global var
 // instead of := which would assign it only in this function
 db, err = gorm.Open(“sqlite3”, “./gorm.db”)
 if err != nil {
    fmt.Println(err)
 }
 defer db.Close()

 db.AutoMigrate(&Person{})

 r := gin.Default()
 r.GET(“/people/”, GetPeople)
 r.GET(“/people/:id”, GetPerson)

 r.Run(“:8080”)
}

func GetPerson(c *gin.Context) {
 id := c.Params.ByName(“id”)
 var person Person
 if err := db.Where(“id = ?”, id).First(&person).Error; err != nil {
    c.AbortWithStatus(404)
    fmt.Println(err)
 } else {
    c.JSON(200, person)
 }
}

func GetPeople(c *gin.Context) {
 var people []Person
 if err := db.Find(&people).Error; err != nil {
 c.AbortWithStatus(404)
    fmt.Println(err)
 } else {
    c.JSON(200, people)
 }

}

現(xiàn)在運(yùn)行服務(wù)器,但請(qǐng)注意,我們更改了上下文,現(xiàn)在您將轉(zhuǎn)到http:// localhost:8080 / people /查看您的列表。一旦將該ID添加到網(wǎng)址的末尾,您將得到單個(gè)記錄返回http:// localhost:8080 / people / 1

{“id”: 1,”firstname”: “John”,”lastname”: “Doe”}

創(chuàng)建

很難用僅有一條記錄來看出差異。很難區(qū)分[{...}]和{...}之間的區(qū)別所以讓我們添加Create函數(shù)和路由

package main

import (
 “fmt”

 “github.com/gin-gonic/gin”
 “github.com/jinzhu/gorm”
 _ “github.com/jinzhu/gorm/dialects/sqlite”
)

var db *gorm.DB
var err error

type Person struct {
 ID uint `json:”id”`
 FirstName string `json:”firstname”`
 LastName string `json:”lastname”`
}

func main() {

 // NOTE: See we’re using = to assign the global var
 // instead of := which would assign it only in this function
 db, err = gorm.Open(“sqlite3”, “./gorm.db”)
 if err != nil {
 fmt.Println(err)
 }
 defer db.Close()

db.AutoMigrate(&Person{})

 r := gin.Default()
 r.GET(“/people/”, GetPeople)
 r.GET(“/people/:id”, GetPerson)
 r.POST(“/people”, CreatePerson)

r.Run(“:8080”)
}

func CreatePerson(c *gin.Context) {

 var person Person
 c.BindJSON(&person)

 db.Create(&person)
 c.JSON(200, person)
}

func GetPerson(c *gin.Context) {
 id := c.Params.ByName(“id”)
 var person Person
 if err := db.Where(“id = ?”, id).First(&person).Error; err != nil {
    c.AbortWithStatus(404)
    fmt.Println(err)
 } else {
    c.JSON(200, person)
 }
}

func GetPeople(c *gin.Context) {
 var people []Person
 if err := db.Find(&people).Error; err != nil {
    c.AbortWithStatus(404)
    fmt.Println(err)
 } else {
    c.JSON(200, people)
 }

}

現(xiàn)在要測試這一個(gè),我們將從命令行運(yùn)行一個(gè)curl命令。我們還需要運(yùn)行服務(wù)器,以便打開另一個(gè)終端窗口,以便可以運(yùn)行這兩個(gè)命令。使用$ go run main.go在第一個(gè)窗口中運(yùn)行服務(wù)器

一旦運(yùn)行,在第二個(gè)窗口運(yùn)行:

$ curl -i -X POST http://localhost:8080/people -d ‘{ “FirstName”: “Elvis”, “LastName”: “Presley”}’

你應(yīng)該看到一個(gè)成功的回應(yīng)

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Sat, 03 Dec 2016 00:14:06 GMT
Content-Length: 50

{“id”:2,”firstname”:”Elvis”,”lastname”:”Presley”}

現(xiàn)在讓我們?cè)跒g覽器中列出我們的人員,看看它是否列出了我們所有的條目
http:// localhost:8080 / people /

[{“id”: 1,”firstname”: “John”,”lastname”: “Doe”},{“id”: 2,”firstname”: “Elvis”,”lastname”: “Presley”}]

太棒了,輸出結(jié)果!看到這里你認(rèn)為這很酷。

這次只發(fā)送部分Person數(shù)據(jù)

$ curl -i -X POST [http://localhost:8080/people](http://localhost:8080/people) -d ‘{ “FirstName”: “Madison”}’

刷新瀏覽器并查看它只添加了我們發(fā)送的數(shù)據(jù)

[{“id”: 1,”firstname”: “John”,”lastname”: “Doe”},{“id”: 2,”firstname”: “Elvis”,”lastname”: “Presley”},{“id”: 3,”firstname”: “Madison”,”lastname”: “”}]

這是Gin的一部分,請(qǐng)注意CreatePerson函數(shù)中的c.BindJSON(&person)行。它會(huì)自動(dòng)填充請(qǐng)求中的任何匹配數(shù)據(jù)字段。

你也可能錯(cuò)過了它,但我的數(shù)據(jù)庫中的情況和我通過的情況是不同的。Gin 對(duì)大小寫不敏感。我傳入了FirstName ,但數(shù)據(jù)庫使用了firstname.。

很簡單!

更新

盡管如此,我們不能讓Madison的last name為空。是時(shí)候添加我們的更新功能了

package main

import (
 “fmt”

 “github.com/gin-gonic/gin”
 “github.com/jinzhu/gorm”
 _ “github.com/jinzhu/gorm/dialects/sqlite”
)

var db *gorm.DB
var err error

type Person struct {
 ID uint `json:”id”`
 FirstName string `json:”firstname”`
 LastName string `json:”lastname”`
}

func main() {

 // NOTE: See we’re using = to assign the global var
 // instead of := which would assign it only in this function
 db, err = gorm.Open(“sqlite3”, “./gorm.db”)
 if err != nil {
    fmt.Println(err)
 }
 defer db.Close()

 db.AutoMigrate(&Person{})

 r := gin.Default()
 r.GET(“/people/”, GetPeople)
 r.GET(“/people/:id”, GetPerson)
 r.POST(“/people”, CreatePerson)
 r.PUT(“/people/:id”, UpdatePerson)

 r.Run(“:8080”)
}

func UpdatePerson(c *gin.Context) {

 var person Person
 id := c.Params.ByName(“id”)

 if err := db.Where(“id = ?”, id).First(&person).Error; err != nil {
    c.AbortWithStatus(404)
    fmt.Println(err)
 }
 c.BindJSON(&person)

 db.Save(&person)
 c.JSON(200, person)

}

func CreatePerson(c *gin.Context) {

 var person Person
 c.BindJSON(&person)

 db.Create(&person)
 c.JSON(200, person)
}

func GetPerson(c *gin.Context) {
 id := c.Params.ByName(“id”)
 var person Person
 if err := db.Where(“id = ?”, id).First(&person).Error; err != nil {
    c.AbortWithStatus(404)
    fmt.Println(err)
 } else {
    c.JSON(200, person)
 }
}

func GetPeople(c *gin.Context) {
 var people []Person
 if err := db.Find(&people).Error; err != nil {
    c.AbortWithStatus(404)
    fmt.Println(err)
 } else {
    c.JSON(200, people)
 }

}

為了測試這個(gè),我們將使用一個(gè)類似的curl命令,但是我們會(huì)在特定的用戶上調(diào)用PUT方法

$ curl -i -X PUT http://localhost:8080/people/3 -d ‘{ “FirstName”: “Madison”, “LastName”:”Sawyer” }’
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Sat, 03 Dec 2016 00:25:35 GMT
Content-Length: 51

{“id”:3,”firstname”:”Madison”,”lastname”:”Sawyer”}

果然,如果我們刷新我們的瀏覽器,我們看到它添加了Sawyer這條數(shù)據(jù)。

[{“id”: 1,”firstname”: “John”,”lastname”: “Doe”},{“id”: 2,”firstname”: “Elvis”,”lastname”: “Presley”},{“id”: 3,”firstname”: “Madison”,”lastname”: “Sawyer”}]

我們?cè)俅慰梢园l(fā)送部分?jǐn)?shù)據(jù)進(jìn)行部分更新

$ curl -i -X PUT http://localhost:8080/people/3 -d ‘{ “FirstName”: “Tom” }’

顯示為

[{“id”: 1,”firstname”: “John”,”lastname”: “Doe”},{“id”: 2,”firstname”: “Elvis”,”lastname”: “Presley”},{“id”: 3,”firstname”: “Tom”,”lastname”: “Sawyer”}]

刪除

現(xiàn)在要完成該解決方案讓dd在刪除功能

package main

import (
 “fmt”

 “github.com/gin-gonic/gin”
 “github.com/jinzhu/gorm”
 _ “github.com/jinzhu/gorm/dialects/sqlite”
)

var db *gorm.DB
var err error

type Person struct {
 ID uint `json:”id”`
 FirstName string `json:”firstname”`
 LastName string `json:”lastname”`
}

func main() {

 // NOTE: See we’re using = to assign the global var
 // instead of := which would assign it only in this function
 db, err = gorm.Open(“sqlite3”, “./gorm.db”)
 if err != nil {
    fmt.Println(err)
 }
 defer db.Close()

 db.AutoMigrate(&Person{})

 r := gin.Default()
 r.GET(“/people/”, GetPeople)
 r.GET(“/people/:id”, GetPerson)
 r.POST(“/people”, CreatePerson)
 r.PUT(“/people/:id”, UpdatePerson)
 r.DELETE(“/people/:id”, DeletePerson)

 r.Run(“:8080”)
}

func DeletePerson(c *gin.Context) {
 id := c.Params.ByName(“id”)
 var person Person
 d := db.Where(“id = ?”, id).Delete(&person)
 fmt.Println(d)
 c.JSON(200, gin.H{“id #” + id: “deleted”})
}

func UpdatePerson(c *gin.Context) {

 var person Person
 id := c.Params.ByName(“id”)

 if err := db.Where(“id = ?”, id).First(&person).Error; err != nil {
    c.AbortWithStatus(404)
    fmt.Println(err)
 }
 c.BindJSON(&person)

 db.Save(&person)
 c.JSON(200, person)

}

func CreatePerson(c *gin.Context) {

 var person Person
 c.BindJSON(&person)

 db.Create(&person)
 c.JSON(200, person)
}

func GetPerson(c *gin.Context) {
 id := c.Params.ByName(“id”)
 var person Person
 if err := db.Where(“id = ?”, id).First(&person).Error; err != nil {
    c.AbortWithStatus(404)
    fmt.Println(err)
 } else {
    c.JSON(200, person)
 }
}

func GetPeople(c *gin.Context) {
 var people []Person
 if err := db.Find(&people).Error; err != nil {
    c.AbortWithStatus(404)
    fmt.Println(err)
 } else {
    c.JSON(200, people)
 }

}

為了測試這個(gè),我們將使用帶curl的Delete方法來調(diào)用它

$ curl -i -X DELETE http://localhost:8080/people/1

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Sat, 03 Dec 2016 00:32:40 GMT
Content-Length: 20

{“id #1”:”deleted”}

刷新瀏覽器,你會(huì)看到我們的John Doe已被刪除

[{“id”: 2,”firstname”: “Elvis”,”lastname”: “Presley”},{“id”: 3,”firstname”: “Tom”,”lastname”: “Sawyer”}]

修改模型

在定義基本的API后,現(xiàn)在是開始改變Person對(duì)象的好時(shí)機(jī)。我們可以通過只更改person結(jié)構(gòu)來輕松修改數(shù)據(jù)庫和api。

我要做的就是在Person Struct中添加一個(gè)city字段。沒有其他的,就一行。

type Person struct {
 ID uint `json:”id”`
 FirstName string `json:”firstname”`
 LastName string `json:”lastname”`
 City string `json:”city”`
}

刷新我們的瀏覽器并拉出列表,您可以看到我所有的對(duì)象現(xiàn)在都有city

[{“id”: 2,”firstname”: “Elvis”,”lastname”: “Presley”,”city”: “”},{“id”: 3,”firstname”: “Tom”,”lastname”: “Sawyer”,”city”: “”}]

我可以創(chuàng)建并更新新字段,而無需進(jìn)行其他更改

$ curl -i -X PUT http://localhost:8080/people/2 -d ‘{ “city”: “Memphis” }’
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Sat, 03 Dec 2016 00:40:57 GMT
Content-Length: 67

{“id”:2,”firstname”:”Elvis”,”lastname”:”Presley”,”city”:”Memphis”}

這全部由我們主函數(shù)中的db.AutoMigrate(&Person {})行處理。在生產(chǎn)環(huán)境中,我們希望更接近地管理架構(gòu),但對(duì)于原型來說,這是完美的

使用MySql

好的,我明白,沒問題,你想使用MySql而不是SQLite。

為此,我們只需要修改一個(gè)導(dǎo)入聲明和連接..

導(dǎo)入_“github.com/go-sql-driver/mysql”

連接

db, _ = gorm.Open(“mysql”, “user:pass@tcp(127.0.0.1:3306)/samples?charset=utf8&parseTime=True&loc=Local”)

完整的例子

package main

// only need mysql OR sqlite 
// both are included here for reference
import (
 “fmt”

 “github.com/gin-gonic/gin”
 _ “github.com/go-sql-driver/mysql” 
 “github.com/jinzhu/gorm”
 _ “github.com/jinzhu/gorm/dialects/sqlite”
)

var db *gorm.DB
var err error

type Person struct {
 ID uint `json:”id”`
 FirstName string `json:”firstname”`
 LastName string `json:”lastname”`
 City string `json:”city”`
}

func main() {

 // NOTE: See we’re using = to assign the global var
 // instead of := which would assign it only in this function
 //db, err = gorm.Open(“sqlite3”, “./gorm.db”)
 db, _ = gorm.Open(“mysql”, “user:pass@tcp(127.0.0.1:3306)/database?charset=utf8&parseTime=True&loc=Local”)

 if err != nil {
    fmt.Println(err)
 }
 defer db.Close()

 db.AutoMigrate(&Person{})

 r := gin.Default()
 r.GET(“/people/”, GetPeople)
 r.GET(“/people/:id”, GetPerson)
 r.POST(“/people”, CreatePerson)
 r.PUT(“/people/:id”, UpdatePerson)
 r.DELETE(“/people/:id”, DeletePerson)

 r.Run(“:8080”)
}

func DeletePerson(c *gin.Context) {
 id := c.Params.ByName(“id”)
 var person Person
 d := db.Where(“id = ?”, id).Delete(&person)
 fmt.Println(d)
 c.JSON(200, gin.H{“id #” + id: “deleted”})
}

func UpdatePerson(c *gin.Context) {

 var person Person
 id := c.Params.ByName(“id”)

 if err := db.Where(“id = ?”, id).First(&person).Error; err != nil {
    c.AbortWithStatus(404)
    fmt.Println(err)
 }
 c.BindJSON(&person)

 db.Save(&person)
 c.JSON(200, person)

}

func CreatePerson(c *gin.Context) {

 var person Person
 c.BindJSON(&person)

 db.Create(&person)
 c.JSON(200, person)
}

func GetPerson(c *gin.Context) {
 id := c.Params.ByName(“id”)
 var person Person
 if err := db.Where(“id = ?”, id).First(&person).Error; err != nil {
    c.AbortWithStatus(404)
    fmt.Println(err)
 } else {
    c.JSON(200, person)
 }
}

func GetPeople(c *gin.Context) {
 var people []Person
 if err := db.Find(&people).Error; err != nil {
    c.AbortWithStatus(404)
    fmt.Println(err)
 } else {
    c.JSON(200, people)
 }

}

結(jié)論
Go是一個(gè)靈活的語言,具有強(qiáng)大的環(huán)境。它非常容易使用少量代碼快速構(gòu)建功能豐富的應(yīng)用程序。我希望這是一個(gè)有用的練習(xí)。請(qǐng)隨時(shí)分享您的想法和問題。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容