Tạo web api CURD đơn giản với Golang và Gin-Gonic framework
Lấy 200$ cloud miễn phí để tha hồ deploy project và nghịch phá server ở đây nhé mọi người.
👇️👇️👇️
Giới thiệu
Năm 2006 Intel cho ra đời những con chíp dual-core processor đầu tiên. Một năm sau đó - năm 2007, để tận dụng sức mạnh tính toán của những con chíp đa lõi thế hệ mới này, google đã cho xây dựng một ngôn ngữ lập trình mới. Đến năm 2009 thì công bố một ngôn ngữ có tên là - Golang...bla..bla
Nghe nguy hiểm quá, mình muốn học Golang chẳng qua vì tò mò, hơn nữa cứ nhìn những ngôn ngữ thuộc vào hàng con ông cháu cha như Swift hay Kotlin mà xem... Người ta đua nhau học rần rần và ngày càng khẳng định được chỗ đứng vững chắc, nên mình cũng muốn tìm hiểu cho biết.
Vì vậy, nay mình hướng dẫn tạo một web api hết sức cơ bản với một số thao tác thêm, sửa, xóa. Để những ai có ý định tiếp cập với Go có thể có được một cái nhìn thoáng qua...
À, nhân tiện mình học khóa học này trên Udemy
, thấy cũng hay phết nè. Bạn nào ưa có thể mua về xem thử.
Chuẩn bị
-
Framework: Dạo qua một vòng thấy nhan nhản các thể loại framework. Nhưng xem ra
Gin-Gonic
là được biết đến nhiều nhất, và số lượng star trội nhất và nhìn có cái gì đó giản tiện giốngExpress
củaNodejs
. Nên mình quyết định dùng thử nó. Bởi đằng nào thì các Framework của Go cũng bắt đầu từnet/http
package cả, nên chắc chúng cũng hao hao nhau thôi. Bạn có thể xem quaGin-Gonic
tại đây -
Ngoài ra, mình cũng dùng một package để làm việc với Mysql tên là
go-sql-driver
. Bạn cũng có thể ngía qua một chút tại đây -
Tạo cấu trúc thư mục. Mình cũng chả biết thế này có chuẩn không nữa, sau một hồi dạo lòng vòng, tham khảo qua một số project nhỏ trên github. Cóp nhặt một thứ một tí mình tạm tổ chức project thế này. Nói chung, kiểu tổ chức này gần như do mình tự nghĩ ra, nên chỉ mang tính chất tham khảo thôi nhé ^^
Và mình sẽ thực hiện các thao tác thêm sửa xóa trên bảng post
như hình dưới đây, rất đơn giản:
Với 4 route CURD tương ứng
main.go
Dưới đây là file main.go
của mình. Ở đây mình tạo các route
thêm, sửa, xóa tương ứng:
package main
import (
"github.com/gin-gonic/gin"
"./controllers"
)
func setupRouter() *gin.Engine {
r := gin.Default()
r.Static("/public", "./public")
client := r.Group("/api")
{
client.GET("/story/:id", controllers.Read)
client.POST("/story/create", controllers.Create)
client.PATCH("/story/update/:id", controllers.Update)
client.DELETE("/story/:id", controllers.Delete)
}
return r
}
func main() {
r := setupRouter()
r.Run(":8080") // Ứng dụng chạy tại cổng 8080
}
Kết nối tới mysql
Mình tách việc kết nối database ra file connect.go
trong folder database
ở hình trên. connect.go
có nội dung như sau :
package database
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
func DBConn() (db *sql.DB) {
dbDriver := "mysql"
dbUser := "root"
dbPass := "789852"
dbName := "viblo-example"
db, err := sql.Open(dbDriver, dbUser+":"+dbPass+"@/"+dbName)
if err != nil {
panic(err.Error())
}
return db
}
Read
Okie, bây giờ ta bắt tay vào tạo thử api đầu tiên nào, lấy ra bài viết có id = 2
và trả về dưới dạng json. Trong file /controllers/client.go
tạo hàm Read
tương ứng như đã định nghĩa ở main.go
:
package controllers
import(
"github.com/gin-gonic/gin"
"../database"
)
type Post struct {
Id int `json:"id"`
Title string `json:"title"`
Content string `json:"body"`
}
func Read(c * gin.Context){
db := database.DBConn()
rows, err := db.Query("SELECT id, title, body FROM posts WHERE id = " + c.Param("id"))
if err != nil{
c.JSON(500, gin.H{
"messages" : "Story not found",
});
}
post := Post{}
for rows.Next(){
var id int
var title, body string
err = rows.Scan(&id, &title, &body)
if err != nil {
panic(err.Error())
}
post.Id = id
post.Title = title
post.Content = body
}
c.JSON(200, post)
defer db.Close() // Hoãn lại việc close database connect cho đến khi hàm Read() thực hiệc xong
}
Buid và chạy lại bằng lệnh go run main.go
. Và test thử bằng Postman
ta được như sau:
Create
Vẫn trong file conttrollers trên, ta tạo function Create như dưới đây để thực hiện thêm mới một bài viết:
func Create(c * gin.Context){
db := database.DBConn()
type CreatePost struct {
Title string `form:"title" json:"title" binding:"required"`
Body string `form:"body" json:"body" binding:"required"`
}
var json CreatePost
if err := c.ShouldBindJSON(&json); err == nil {
insPost, err := db.Prepare("INSERT INTO posts(title, body) VALUES(?,?)",)
if err != nil {
c.JSON(500, gin.H{
"messages" : err,
})
}
insPost.Exec(json.Title, json.Body)
c.JSON(200, gin.H{
"messages": "inserted",
})
} else {
c.JSON(500, gin.H{"error": err.Error()})
}
defer db.Close()
}
Ta test thử bằng post man và thu được kết quả như hình:
Update
func Update(c * gin.Context){
db := database.DBConn()
type UpdatePost struct {
Title string `form:"title" json:"title" binding:"required"`
Body string `form:"body" json:"body" binding:"required"`
}
var json UpdatePost
if err := c.ShouldBindJSON(&json); err == nil {
edit, err := db.Prepare("UPDATE posts SET title=?, body=? WHERE id= " + c.Param("id"))
if err != nil {
panic(err.Error())
}
edit.Exec(json.Title, json.Body)
c.JSON(200, gin.H{
"messages": "edited",
})
}else{
c.JSON(500, gin.H{"error": err.Error()})
}
defer db.Close()
}
Ta test lại với Postman
nào
Delete
func Delete(c * gin.Context){
db := database.DBConn()
delete, err := db.Prepare("DELETE FROM posts WHERE id=?")
if err != nil {
panic(err.Error())
}
delete.Exec(c.Param("id"))
c.JSON(200, gin.H{
"messages": "deleted",
})
defer db.Close()
}
Và kết quả:
Kết luận
Vậy là mình đã hoàn thành 4 api CURD cơ bản với Golang và Gin-Gonic. Tương lai mình dự kiến sẽ thử sức bằng cách xây hẳn một hệ thống trắc nghiệm online bằng golang thử xem sao. Hy vọng bài viết hữu cho những bạn mới tiếp cận với Golang như mình. Nhìn chung, mình thấy khá hứng thú khi đến với Golang. Và không hề hối hận với thời gian mình bỏ ra, vì nó rất nhanh và dễ tiếp cận. Cám ơn bạn vì đã giành thời gian xem bài viết của mình nhé ^^
All rights reserved