Go 和 Gin Web 框架编写 RESTful Web 服务 API 的基础知识.
package mainimport ("net/http""github.com/gin-gonic/gin"
)// album 表示有关专辑的数据.
type album struct {ID string `json:"id"`Title string `json:"title"`Artist string `json:"artist"`Price float64 `json:"price"`
}// 专辑切片以填充专辑数据记录.
var albums = []album{{ID: "1", Title: "Blue Train", Artist: "John Coltrane", Price: 56.99},{ID: "2", Title: "Jeru", Artist: "Gerry Mulligan", Price: 17.99},{ID: "3", Title: "Sarah Vaughan and Clifford Brown", Artist: "Sarah Vaughan", Price: 39.99},
}func main() {router := gin.Default()router.GET("/albums", getAlbums)router.GET("/albums/:id", getAlbumByID)router.POST("/albums", postAlbums)router.Run("localhost:8080")
}// getAlbums 以 JSON 格式响应所有专辑的列表.
func getAlbums(c *gin.Context) {c.IndentedJSON(http.StatusOK, albums)
}// postAlbums 从请求体中收到的JSON中添加一个专辑.
func postAlbums(c *gin.Context) {var newAlbum album// 调用 BindJSON 将收到的 JSON 绑定到// newAlbum.if err := c.BindJSON(&newAlbum); err != nil {return}// 将新专辑添加到切片.albums = append(albums, newAlbum)c.IndentedJSON(http.StatusCreated, newAlbum)
}// getAlbumByID 查找 ID 值与客户端发送的 id
// 参数匹配的专辑,然后返回该专辑作为响应.
func getAlbumByID(c *gin.Context) {id := c.Param("id")// 循环浏览专辑列表,查找// ID 值与参数匹配的专辑.for _, a := range albums {if a.ID == id {c.IndentedJSON(http.StatusOK, a)return}}c.IndentedJSON(http.StatusNotFound, gin.H{"message": "album not found"})
}
Go访问关系数据库
package mainimport ("database/sql""fmt""log""os""github.com/go-sql-driver/mysql"
)var db *sql.DBtype Album struct {ID int64Title stringArtist stringPrice float32
}func main() {// Capture connection properties.cfg := mysql.Config{User: os.Getenv("DBUSER"),Passwd: os.Getenv("DBPASS"),Net: "tcp",Addr: "127.0.0.1:3306",DBName: "recordings",AllowNativePasswords: true,}log.Println(cfg.FormatDSN())// Get a database handle.var err errordb, err = sql.Open("mysql", cfg.FormatDSN())if err != nil {log.Fatal(err)}pingErr := db.Ping()if pingErr != nil {log.Fatal(pingErr)}fmt.Println("Connected!")albums, err := albumsByArtist("John Coltrane")if err != nil {log.Fatal(err)}fmt.Printf("Albums found: %v\n", albums)// 在此处对 ID 2 进行硬编码以测试查询。alb, err := albumByID(2)if err != nil {log.Fatal(err)}fmt.Printf("Album found: %v\n", alb)albID, err := addAlbum(Album{Title: "The Modern Sound of Betty Carter",Artist: "Betty Carter",Price: 49.99,})if err != nil {log.Fatal(err)}fmt.Printf("ID of added album: %v\n", albID)
}// albumsByArtist对具有指定艺术家姓名的专辑进行查询.
func albumsByArtist(name string) ([]Album, error) {// 一个专辑切片,用于保存返回行中的数据.var albums []Albumrows, err := db.Query("SELECT * FROM album WHERE artist = ?", name)if err != nil {return nil, fmt.Errorf("albumsByArtist %q: %v", name, err)}defer rows.Close()// 遍历行,使用"扫描"将列数据分配给结构字段.for rows.Next() {var alb Albumif err := rows.Scan(&alb.ID, &alb.Title, &alb.Artist, &alb.Price); err != nil {return nil, fmt.Errorf("albumsByArtist %q: %v", name, err)}albums = append(albums, alb)}if err := rows.Err(); err != nil {return nil, fmt.Errorf("albumsByArtist %q: %v", name, err)}return albums, nil
}// albumByID查询指定ID的专辑。
func albumByID(id int64) (Album, error) {// 一个专辑将保存返回行的数据。var alb Albumrow := db.QueryRow("SELECT * FROM album WHERE id = ?", id)if err := row.Scan(&alb.ID, &alb.Title, &alb.Artist, &alb.Price); err != nil {if err == sql.ErrNoRows {return alb, fmt.Errorf("albumsById %d: no such album", id)}return alb, fmt.Errorf("albumsById %d: %v", id, err)}return alb, nil
}// addAlbum 将指定的专辑添加到数据库中,
// 返回新条目的专辑 ID
func addAlbum(alb Album) (int64, error) {result, err := db.Exec("INSERT INTO album (title, artist, price) VALUES (?, ?, ?)", alb.Title, alb.Artist, alb.Price)if err != nil {return 0, fmt.Errorf("addAlbum: %v", err)}id, err := result.LastInsertId()if err != nil {return 0, fmt.Errorf("addAlbum: %v", err)}return id, nil
}
官方Documentation