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 ภายในไดเร็กทอรีรากของโปรเจ็กต์ของคุณ โครงสร้างโครงการขั้นสุดท้ายของคุณควรมีลักษณะดังนี้:
ไฟล์นี้จัดการการทำงานของเราเตอร์สำหรับแต่ละปลายทาง:
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 เป็นภาษาโปรแกรมที่เหมาะสมสำหรับกรณีการใช้งานต่างๆ