วิธีสร้าง CRUD API ด้วย Gin และ MongoDB ของ Golang

วิธีสร้าง CRUD API ด้วย Gin และ MongoDB ของ Golang

Golang เป็นหนึ่งในภาษาการเขียนโปรแกรมที่มีความต้องการสูงและจ่ายเงินสูงพร้อมแอพพลิเคชั่นมากมาย เมื่อจับคู่กับเฟรมเวิร์กอย่าง Gin, Revel และ gorilla/mux คุณสามารถสร้าง API ด้วย Go ได้อย่างง่ายดาย





เรียนรู้วิธีสร้าง CRUD API ใน Golang โดยใช้เฟรมเวิร์ก Gin HTTP





การทำวิดีโอประจำวัน

การติดตั้งและการติดตั้งเบื้องต้น

เริ่มต้นกับ Golang โดยการติดตั้งบนคอมพิวเตอร์ของคุณหากคุณยังไม่ได้ดำเนินการ





ค้นหาบัญชีทั้งหมดที่เชื่อมโยงกับที่อยู่อีเมลของฉันฟรี

เมื่อติดตั้งแล้ว ขั้นตอนต่อไปคือการสร้างโฟลเดอร์รูทโปรเจ็กต์บนเครื่องของคุณและเริ่มต้นโมดูล Go ในไดเร็กทอรีรูทนั้น

เมื่อต้องการทำเช่นนี้ ให้เปิด คลินิก ไปที่โฟลเดอร์รูทของโปรเจ็กต์และเรียกใช้:



go mod init module_name 

คุณจะเห็นชื่อโมดูลของคุณ (เช่น CRUD_API ) และเวอร์ชันเมื่อคุณเปิด go.mod ไฟล์. แพ็คเกจที่กำหนดเองทั้งหมดจะมาจากโมดูลหลักนี้ ดังนั้นแพ็คเกจที่กำหนดเองที่นำเข้าจะมีรูปแบบ:

import(package CRUD_API/package-directory-name)

ถัดไป ติดตั้งแพ็คเกจที่จำเป็นสำหรับการสร้าง CRUD API ในกรณีนี้ ให้ใช้ Gin Gonic เพื่อกำหนดเส้นทางปลายทาง API:





go get github.com/gin-gonic/gin 

ตอนนี้ติดตั้งไดรเวอร์ MongoDB เพื่อเก็บข้อมูล:

go get go.mongodb.org/mongo-driver/mongo

วิธีเชื่อมต่อ ไปที่ MongoDB

สิ่งที่คุณต้องมีคือ MongoDB URI เพื่อเชื่อมต่อ Golang กับฐานข้อมูล โดยทั่วไปแล้วจะมีลักษณะเช่นนี้หากคุณเชื่อมต่อกับ MongoDB Atlas ในเครื่อง:





Mongo_URL = "mongodb://127.0.0.1:27017"

ตอนนี้สร้างโฟลเดอร์ใหม่ในไดเรกทอรีรากของโปรเจ็กต์แล้วเรียกมันว่า ฐานข้อมูล . สร้างไฟล์ Go ภายในโฟลเดอร์นี้แล้วตั้งชื่อว่า ฐานข้อมูล.go .

นี่คือแพ็คเกจฐานข้อมูลของคุณ และเริ่มต้นโดยการนำเข้าไลบรารีที่จำเป็น:

package database 

import (
"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
}

แนวทางปฏิบัติที่ดีที่สุดคือการซ่อนตัวแปรสภาพแวดล้อม เช่น สตริงการเชื่อมต่อฐานข้อมูลในa .env ไฟล์ โดยใช้แพ็คเกจ dotenv . ทำให้โค้ดของคุณพกพาได้สะดวกยิ่งขึ้นและสะดวกเมื่อใช้a อินสแตนซ์คลัสเตอร์คลาวด์ MongoDB , ตัวอย่างเช่น.

ดิ ConnectDB ฟังก์ชั่นสร้างการเชื่อมต่อและส่งคืนวัตถุ MongoDB Client ใหม่

สร้างชุดฐานข้อมูล

MongoDB เก็บข้อมูลในคอลเล็กชัน ซึ่งให้อินเทอร์เฟซกับข้อมูลฐานข้อมูลพื้นฐาน

ในการจัดการฟังก์ชันดึงข้อมูลคอลเลกชัน ให้เริ่มต้นด้วยการสร้างโฟลเดอร์ใหม่ ของสะสม ในรูทโปรเจ็กต์ของคุณ ตอนนี้สร้างไฟล์ Go ใหม่ getCollection.go ที่ได้รับคอลเล็กชันจากฐานข้อมูล:

package getcollection 

import (
"go.mongodb.org/mongo-driver/mongo"
)

func GetCollection(client *mongo.Client, collectionName string) *mongo.Collection {
collection := client.Database("myGoappDB").Collection("Posts")
return collection
}

ฟังก์ชันนี้รับคอลเล็กชันจากฐานข้อมูล MongoDB ชื่อฐานข้อมูลในกรณีนี้คือ myGoappDB , กับ กระทู้ เป็นของสะสม

สร้างแบบจำลองฐานข้อมูล

สร้างโฟลเดอร์ใหม่ภายในไดเร็กทอรีรากของคุณและเรียกมันว่า แบบอย่าง . โฟลเดอร์นี้จัดการโมเดลฐานข้อมูลของคุณ

สร้างไฟล์ Go ใหม่ภายในโฟลเดอร์นั้นแล้วเรียกมันว่า model.go . โมเดลของคุณ ในกรณีนี้ คือบล็อกโพสต์ที่มีชื่อ:

เครื่องเล่นดีวีดีหลายภูมิภาคที่ดีที่สุดซื้อ
package model 

import (
"go.mongodb.org/mongo-driver/bson/primitive"
)

type Post struct {
ID primitive.ObjectID
Title string
Article string
}

การสร้าง CRUD API ด้วย Go

ถัดไปคือการสร้าง CRUD API ในการเริ่มต้นในส่วนนี้ ให้สร้างโฟลเดอร์ใหม่ภายในไดเรกทอรีรากของโปรเจ็กต์เพื่อจัดการปลายทางของคุณ เรียกมันว่า เส้นทาง .

สร้างไฟล์ Go แยกกันในโฟลเดอร์นี้สำหรับแต่ละการกระทำ ตัวอย่างเช่น คุณสามารถตั้งชื่อได้ create.go , read.go , update.go , และ delete.go . คุณจะส่งออกตัวจัดการเหล่านี้เป็น เส้นทาง บรรจุุภัณฑ์.

วิธีสร้าง POST Endpoint ใน Go

เริ่มต้นด้วยการกำหนดจุดสิ้นสุด POST เพื่อเขียนข้อมูลลงในฐานข้อมูล

ข้างใน เส้นทาง/create.go , เพิ่มสิ่งต่อไปนี้:

package routes 

import (
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}})
}

รหัสนี้เริ่มต้นด้วยการนำเข้าโมดูลที่กำหนดเองของโครงการ จากนั้นนำเข้าแพ็คเกจของบุคคลที่สามรวมถึง จิน และ ไดร์เวอร์ MongoDB .

ไกลออกไป, postCollection เก็บคอลเลกชันฐานข้อมูล โดยเฉพาะอย่างยิ่ง c.BindJSON('โพสต์') เป็นอินสแตนซ์โมเดล JSONified ที่เรียกแต่ละฟิลด์โมเดลเป็น postPayload ; สิ่งนี้จะเข้าสู่ฐานข้อมูล

วิธีสร้าง GET Endpoint

ปลายทาง GET ใน เส้นทาง/read.go , อ่านเอกสารเดียวจากฐานข้อมูลผ่าน ID เฉพาะ นอกจากนี้ยังเริ่มต้นด้วยการนำเข้าแพ็คเกจแบบกำหนดเองและของบริษัทอื่น:

package routes 

import (
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})
}

ดิ โพสต์ ตัวแปรคือการประกาศพารามิเตอร์ ได้รับ ID อ็อบเจ็กต์ของเอกสารเป็น objId .

อย่างไรก็ตาม, ผลลัพธ์ เป็นอินสแตนซ์ของโมเดลฐานข้อมูล ซึ่งต่อมาเก็บเอกสารที่ส่งคืนเป็น res .

วิธีสร้าง PUT Endpoint

ตัวจัดการ PUT ใน เส้นทาง/update.go คล้ายกับตัวจัดการ POST คราวนี้จะอัปเดตโพสต์ที่มีอยู่ด้วย ID อ็อบเจ็กต์ที่ไม่ซ้ำกัน:

package routes 

import (
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})
}

รูปแบบ JSON ของอินสแตนซ์โมเดล ( โพสต์ ) เรียกแต่ละฟิลด์โมเดลจากฐานข้อมูล ตัวแปรผลลัพธ์ใช้ MongoDB $set โอเปอเรเตอร์เพื่ออัปเดตเอกสารที่จำเป็นที่เรียกโดย ID อ็อบเจ็กต์

ดิ ผลลัพธ์.MatchedCount เงื่อนไขป้องกันไม่ให้รหัสทำงานหากไม่มีบันทึกในฐานข้อมูลหรือ ID ที่ส่งผ่านไม่ถูกต้อง

การสร้างปลายทาง DELETE

ปลายทาง DELETE ใน delete.go , ลบเอกสารตาม ID อ็อบเจ็กต์ที่ส่งผ่านเป็นพารามิเตอร์ URL:

package routes 

import (
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})
}

รหัสนี้จะลบบันทึกโดยใช้ DeleteOne การทำงาน. นอกจากนี้ยังใช้ ผล.DeletedCount คุณสมบัติเพื่อป้องกันไม่ให้โค้ดทำงานหากฐานข้อมูลว่างเปล่าหรือ ID อ็อบเจ็กต์ไม่ถูกต้อง

วิธีหาหนังสือเมื่อคุณไม่รู้ชื่อหรือผู้แต่ง

สร้างไฟล์ API Runner

สุดท้าย สร้าง a main.go ภายในไดเร็กทอรีรากของโปรเจ็กต์ของคุณ โครงสร้างโครงการขั้นสุดท้ายของคุณควรมีลักษณะดังนี้:

  โครงสร้างโครงการ Golang CRUD

ไฟล์นี้จัดการการทำงานของเราเตอร์สำหรับแต่ละปลายทาง:

package main 

import (
routes "CRUD_API/routes"
"github.com/gin-gonic/gin"
)

func main() {
router := gin.Default()

router.POST("/", routes.CreatePost)

// called as localhost:3000/getOne/{id}
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")
}

ไฟล์นี้เป็นแพ็คเกจหลักที่รันไฟล์อื่นๆ เริ่มต้นด้วยการนำเข้าตัวจัดการเส้นทาง ต่อไปคือ เราเตอร์ ตัวแปร a จิน อินสแตนซ์ที่กระตุ้นการดำเนินการ HTTP และเรียกแต่ละจุดปลายทางโดยใช้ชื่อฟังก์ชันจาก เส้นทาง บรรจุุภัณฑ์.

โครงการ CRUD ของคุณทำงานบน localhost:3000 . ในการรันเซิร์ฟเวอร์และ ทดสอบ CRUD API ให้รันคำสั่งต่อไปนี้ในไดเร็กทอรีฐานของคุณ:

go run main.go

เปลี่ยนโครงการ Golang CRUD ของคุณให้เป็นผลิตภัณฑ์ที่ใช้งานได้

คุณสร้าง CRUD API ด้วย Go สำเร็จแล้ว ยินดีด้วย! แม้ว่าจะเป็นโครงการย่อย แต่คุณได้เห็นสิ่งที่ต้องใช้ในการดำเนินการคำขอ HTTP ปกติใน Go

คุณสามารถสร้างสรรค์ได้มากขึ้นโดยขยายสิ่งนี้เป็นแอปพลิเคชันที่ใช้งานได้จริงซึ่งมอบคุณค่าให้กับผู้ใช้ Go เป็นภาษาโปรแกรมที่เหมาะสมสำหรับกรณีการใช้งานต่างๆ