Cách tạo API CRUD với Golang’s Gin và MongoDB
Golang là một trong những ngôn ngữ lập trình theo yêu cầu, trả phí cao nhất với nhiều ứng dụng. Khi được ghép nối với các khung công tác như Gin, Revel và gorilla / mux, bạn có thể dễ dàng tạo API với Go.
Tìm hiểu cách tạo API CRUD trong Golang bằng cách sử dụng khung HTTP Gin.
Mục Lục
Thiết lập và cài đặt ban đầu
Bắt đầu với Golang bằng cách cài đặt nó trên máy tính của bạn nếu bạn chưa làm như vậy.
Sau khi cài đặt, bước tiếp theo là tạo một thư mục gốc của dự án trên máy của bạn và khởi tạo mô-đun Go trong thư mục gốc đó.
Để thực hiện việc này, hãy mở CLI, điều hướng đến thư mục gốc dự án của bạn và chạy:
go mod init module_name
Bạn sẽ thấy tên mô-đun của mình (ví dụ: CRUD_API) và phiên bản của nó khi bạn mở go.mod tập tin. Tất cả các gói tùy chỉnh sẽ đến từ mô-đun mẹ này. Vì vậy, bất kỳ gói tùy chỉnh đã nhập nào có dạng:
import(package CRUD_API/package-directory-name)
Tiếp theo, cài đặt các gói cần thiết để tạo API CRUD. Trong trường hợp này, hãy sử dụng Gin gonic để định tuyến các điểm cuối API:
go get github.com/gin-gonic/gin
Bây giờ cài đặt Trình điều khiển MongoDB để lưu trữ dữ liệu:
go get go.mongodb.org/mongo-driver/mongo
Cách kết nối Đi tới MongoDB
Tất cả những gì bạn cần là MongoDB URI của mình để kết nối Golang với cơ sở dữ liệu. Nó thường trông như thế này nếu bạn đang kết nối cục bộ với MongoDB Atlas:
Mongo_URL = "mongodb://127.0.0.1:27017"
Bây giờ, hãy tạo một thư mục mới trong thư mục gốc dự án của bạn và gọi nó cơ sở dữ liệu. Tạo một tệp Go bên trong thư mục này và đặt tên cho nó database.go.
Đây là gói cơ sở dữ liệu của bạn và nó bắt đầu bằng cách nhập các thư viện bắt buộc:
package databaseimport (
"context"
"fmt"
"log"
"time"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func ConnectDB() *mongo.Client {
Mongo_URL := "mongodb://127.0.0.1:27017"
client, err := mongo.NewClient(options.Client().ApplyURI(Mongo_URL))
if err != nil {
log.Fatal(err)
}
ctx, cancel := context.WithTimeout(context.Background(), 10 * time.Second)
err = client.Connect(ctx)
defer cancel()
if err != nil {
log.Fatal(err)
}
fmt.Println("Connected to mongoDB")
return client
}
Cách tốt nhất là ẩn các biến môi trường như chuỗi kết nối cơ sở dữ liệu trong .env sử dụng gói dotenv. Điều này làm cho mã của bạn dễ di động hơn và có ích khi sử dụng phiên bản cụm đám mây MongoDB chẳng hạn.
Các ConnectDB hàm thiết lập một kết nối và trả về một đối tượng MongoDB Client mới.
Tạo Bộ sưu tập Cơ sở dữ liệu
MongoDB lưu trữ dữ liệu trong Bộ sưu tập, cung cấp giao diện cho dữ liệu cơ sở dữ liệu bên dưới.
Để xử lý chức năng tìm nạp bộ sưu tập, hãy bắt đầu bằng cách tạo một thư mục mới, Bộ sưu tập, trong gốc dự án của bạn. Bây giờ, hãy tạo một tệp Go mới, getCollection.golấy bộ sưu tập từ cơ sở dữ liệu:
package getcollectionimport (
"go.mongodb.org/mongo-driver/mongo"
)
func GetCollection(client *mongo.Client, collectionName string) *mongo.Collection {
collection := client.Database("myGoappDB").Collection("Posts")
return collection
}
Hàm này lấy Bộ sưu tập từ cơ sở dữ liệu MongoDB. Tên cơ sở dữ liệu, trong trường hợp này, là myGoappDBvới Bài đăng như bộ sưu tập của nó.
Tạo mô hình cơ sở dữ liệu
Tạo một thư mục mới bên trong thư mục gốc của bạn và gọi nó người mẫu. Thư mục này xử lý mô hình cơ sở dữ liệu của bạn.
Tạo một tệp Go mới bên trong thư mục đó và gọi nó model.go. Mô hình của bạn, trong trường hợp này, là một bài đăng trên blog với tiêu đề:
package modelimport (
"go.mongodb.org/mongo-driver/bson/primitive"
)
type Post struct {
ID primitive.ObjectID
Title string
Article string
}
Tạo một API CRUD với Go
Tiếp theo là tạo API CRUD. Để bắt đầu với phần này, hãy tạo một thư mục mới trong thư mục gốc của dự án để xử lý các điểm cuối của bạn. Gọi nó đi các tuyến đường.
Tạo một tệp Go riêng biệt trong thư mục này cho mỗi hành động. Ví dụ, bạn có thể đặt tên cho chúng create.go, read.go, update.govà delete.go. Bạn sẽ xuất các trình xử lý này dưới dạng các tuyến đường bưu kiện.
Cách tạo điểm cuối POST trong Go
Bắt đầu bằng cách xác định điểm cuối POST để ghi dữ liệu vào cơ sở dữ liệu.
Nội bộ route / create.gothêm những điều sau:
package routesimport (
getcollection "CRUD_API/Collection"
database "CRUD_API/databases"
model "CRUD_API/model"
"context"
"log"
"net/http"
"time"
"github.com/gin-gonic/gin"
"go.mongodb.org/mongo-driver/bson/primitive"
)
func CreatePost(c *gin.Context) {
var DB = database.ConnectDB()
var postCollection = getcollection.GetCollection(DB, "Posts")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
post := new(model.Posts)
defer cancel()
if err := c.BindJSON(&post); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"message": err})
log.Fatal(err)
return
}
postPayload := model.Posts{
Id: primitive.NewObjectID(),
Title: post.Title,
Article: post.Article,
}
result, err := postCollection.InsertOne(ctx, postPayload)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"message": err})
return
}
c.JSON(http.StatusCreated, gin.H{"message": "Posted successfully", "Data": map[string]interface{}{"data": result}})
}
Mã này bắt đầu bằng cách nhập các mô-đun tùy chỉnh của dự án. Sau đó, nó nhập các gói của bên thứ ba bao gồm Gin và Trình điều khiển MongoDB.
Hơn nữa, postCollection giữ bộ sưu tập cơ sở dữ liệu. Đáng chú ý, c.BindJSON (“bài đăng”) là một phiên bản mô hình được JSONified gọi mỗi trường mô hình là postPayload; điều này sẽ đi vào cơ sở dữ liệu.
Cách tạo điểm cuối GET
Điểm cuối GET, trong route / read.go, đọc một tài liệu từ cơ sở dữ liệu thông qua ID duy nhất của nó. Nó cũng bắt đầu bằng cách nhập các gói tùy chỉnh và bên thứ ba:
package routesimport (
getcollection "CRUD_API/Collection"
database "CRUD_API/databases"
model "CRUD_API/model"
"context"
"net/http"
"time"
"github.com/gin-gonic/gin"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
func ReadOnePost(c *gin.Context) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
var DB = database.ConnectDB()
var postCollection = getcollection.GetCollection(DB, "Posts")
postId := c.Param("postId")
var result model.Posts
defer cancel()
objId, _ := primitive.ObjectIDFromHex(postId)
err := postCollection.FindOne(ctx, bson.M{"id": objId}).Decode(&result)
res := map[string]interface{}{"data": result}
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"message": err})
return
}
c.JSON(http.StatusCreated, gin.H{"message": "success!", "Data": res})
}
Các postId biến là một khai báo tham số. Nó nhận được ID đối tượng của tài liệu là objId.
Tuy nhiên, kết quả là một phiên bản của mô hình cơ sở dữ liệu, mô hình này sau này giữ tài liệu trả về là res.
Cách tạo điểm cuối PUT
Trình xử lý PUT, trong route / update.go, tương tự như trình xử lý POST. Lần này, nó cập nhật một bài đăng hiện có bằng ID đối tượng duy nhất của nó:
package routesimport (
getcollection "CRUD_API/Collection"
database "CRUD_API/databases"
model "CRUD_API/model"
"context"
"net/http"
"time"
"github.com/gin-gonic/gin"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
func UpdatePost(c *gin.Context) {
ctx, cancel := context.WithTimeout(context.Background(), 10 * time.Second)
var DB = database.ConnectDB()
var postCollection = getcollection.GetCollection(DB, "Posts")
postId := c.Param("postId")
var post model.Posts
defer cancel()
objId, _ := primitive.ObjectIDFromHex(postId)
if err := c.BindJSON(&post); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"message": err})
return
}
edited := bson.M{"title": post.Title, "article": post.Article}
result, err := postCollection.UpdateOne(ctx, bson.M{"id": objId}, bson.M{"$set": edited})
res := map[string]interface{}{"data": result}
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"message": err})
return
}
if result.MatchedCount < 1 {
c.JSON(http.StatusInternalServerError, gin.H{"message": "Data doesn't exist"})
return
}
c.JSON(http.StatusCreated, gin.H{"message": "data updated successfully!", "Data": res})
}
Định dạng JSON của phiên bản mô hình (bưu kiện) gọi từng trường mô hình từ cơ sở dữ liệu. Biến kết quả sử dụng MongoDB $ set toán tử để cập nhật một tài liệu bắt buộc được gọi bởi ID đối tượng của nó.
Các kết quả. Số tiền đã khớp điều kiện ngăn không cho mã chạy nếu không có bản ghi nào trong cơ sở dữ liệu hoặc ID đã chuyển không hợp lệ.
Tạo điểm cuối XÓA
Điểm cuối DELETE, trong delete.goxóa tài liệu dựa trên ID đối tượng được truyền dưới dạng tham số URL:
package routesimport (
getcollection "CRUD_API/Collection"
database "CRUD_API/databases"
"context"
"net/http"
"time"
"github.com/gin-gonic/gin"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
func DeletePost(c *gin.Context) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
var DB = database.ConnectDB()
postId := c.Param("postId")
var postCollection = getcollection.GetCollection(DB, "Posts")
defer cancel()
objId, _ := primitive.ObjectIDFromHex(postId)
result, err := postCollection.DeleteOne(ctx, bson.M{"id": objId})
res := map[string]interface{}{"data": result}
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"message": err})
return
}
if result.DeletedCount < 1 {
c.JSON(http.StatusInternalServerError, gin.H{"message": "No data to delete"})
return
}
c.JSON(http.StatusCreated, gin.H{"message": "Article deleted successfully", "Data": res})
}
Mã này xóa một bản ghi bằng cách sử dụng DeleteOne hàm số. Nó cũng sử dụng result.DeletedCount để ngăn mã chạy nếu cơ sở dữ liệu trống hoặc ID đối tượng không hợp lệ.
Tạo tệp trình chạy API
Cuối cùng, tạo một main.go bên trong thư mục gốc dự án của bạn. Cấu trúc dự án cuối cùng của bạn sẽ trông như thế này:
Tệp này xử lý việc thực thi bộ định tuyến cho mỗi điểm cuối:
package mainimport (
routes "CRUD_API/routes"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
router.POST("/", routes.CreatePost)
router.GET("getOne/:postId", routes.ReadOnePost)
// called as localhost:3000/update/{id}
router.PUT("/update/:postId", routes.UpdatePost)
// called as localhost:3000/delete/{id}
router.DELETE("/delete/:postId", routes.DeletePost)
router.Run("localhost: 3000")
}
Tệp này là gói chính chạy các tệp khác. Nó bắt đầu bằng cách nhập các trình xử lý tuyến đường. Tiếp theo là bộ định tuyến biến, một gin ví dụ gợi lên các hành động HTTP và gọi mỗi điểm cuối bằng tên chức năng của nó từ các tuyến đường bưu kiện.
Dự án CRUD của bạn đang chạy trên localhost: 3000. Để chạy máy chủ và kiểm tra API CRUD, hãy chạy lệnh sau trong thư mục cơ sở của bạn:
go run main.go
Biến dự án Golang CRUD của bạn thành một sản phẩm có thể sử dụng được
Bạn đã tạo thành công API CRUD với Go; Xin chúc mừng! Mặc dù đây là một dự án nhỏ, nhưng bạn đã thấy những gì cần thiết để thực hiện các yêu cầu HTTP thông thường trong Go.
Bạn có thể sáng tạo hơn bằng cách mở rộng ứng dụng này thành một ứng dụng thiết thực hơn mang lại giá trị cho người dùng. Go là một ngôn ngữ lập trình phù hợp cho nhiều trường hợp sử dụng.