Πώς να δημιουργήσετε ένα CRUD API με το Golang's Gin και το MongoDB

Πώς να δημιουργήσετε ένα CRUD API με το Golang's Gin και το MongoDB

Η Golang είναι μια από τις πιο ακριβοπληρωμένες, σε ζήτηση γλώσσες προγραμματισμού με πολλές εφαρμογές. Όταν συνδυάζονται με πλαίσια όπως το Gin, το Revel και το gorilla/mux, μπορείτε εύκολα να δημιουργήσετε ένα API με το Go.





Μάθετε πώς να δημιουργείτε ένα CRUD API στο Golang χρησιμοποιώντας το πλαίσιο Gin HTTP.





ΚΑΤΑΣΚΕΥΗ ΒΙΝΤΕΟ ΤΗΣ ΗΜΕΡΑΣ

Αρχική εγκατάσταση και εγκατάσταση

Ξεκινήστε με το Golang εγκαθιστώντας το στον υπολογιστή σας, εάν δεν το έχετε κάνει ήδη.





Μόλις εγκατασταθεί, το επόμενο βήμα είναι να δημιουργήσετε έναν ριζικό φάκελο έργου στον υπολογιστή σας και να αρχικοποιήσετε μια λειτουργική μονάδα Go σε αυτόν τον ριζικό κατάλογο.

Για να το κάνετε αυτό, ανοίξτε ένα CLI , μεταβείτε στον ριζικό φάκελο του έργου σας και εκτελέστε:



go mod init module_name 

Θα δείτε το όνομα της μονάδας σας (π.χ. CRUD_API ) και την έκδοσή του όταν ανοίγετε το go.mod αρχείο. Όλα τα προσαρμοσμένα πακέτα θα προέρχονται από αυτήν τη γονική μονάδα. Έτσι, κάθε εισαγόμενο προσαρμοσμένο πακέτο έχει τη μορφή:

import(package CRUD_API/package-directory-name)

Στη συνέχεια, εγκαταστήστε τα πακέτα που είναι απαραίτητα για τη δημιουργία του CRUD API. Σε αυτή την περίπτωση, χρησιμοποιήστε Τζιν Γκόνιτς για να δρομολογήσετε τα τελικά σημεία του 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
}

Η καλύτερη πρακτική είναι να αποκρύπτετε μεταβλητές περιβάλλοντος όπως η συμβολοσειρά σύνδεσης βάσης δεδομένων σε α .env αρχείο χρησιμοποιώντας το πακέτο dotenv . Αυτό κάνει τον κώδικά σας πιο φορητό και είναι χρήσιμο όταν χρησιμοποιείτε α Παράδειγμα συμπλέγματος σύννεφων 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 σε αυτόν τον φάκελο για κάθε ενέργεια. Για παράδειγμα, μπορείτε να τα ονομάσετε δημιουργία.πηγαίνω , διαβάστε.πηγαίνετε , update.go , και delete.go . Θα εξαγάγετε αυτούς τους χειριστές ως διαδρομές πακέτο.

Πώς να δημιουργήσετε το τελικό σημείο POST στο Go

Ξεκινήστε ορίζοντας το τελικό σημείο POST για την εγγραφή δεδομένων στη βάση δεδομένων.

Μέσα routes/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

Το τελικό σημείο GET, σε διαδρομές/διαβάζω.go , διαβάζει ένα μεμονωμένο έγγραφο από τη βάση δεδομένων μέσω του μοναδικού αναγνωριστικού του. Ξεκινά επίσης με την εισαγωγή προσαρμοσμένων πακέτων και πακέτων τρίτων:

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

ο αναρτήσεις μεταβλητή είναι μια δήλωση παραμέτρου. Λαμβάνει το αναγνωριστικό αντικειμένου ενός εγγράφου ως objId .

Ωστόσο, αποτέλεσμα είναι ένα στιγμιότυπο του μοντέλου βάσης δεδομένων, το οποίο αργότερα διατηρεί το επιστρεφόμενο έγγραφο ως res .

Πώς να δημιουργήσετε το τελικό σημείο PUT

Ο χειριστής PUT, μέσα routes/update.go , είναι παρόμοιο με το πρόγραμμα χειρισμού POST. Αυτή τη φορά, ενημερώνει μια υπάρχουσα ανάρτηση με το μοναδικό αναγνωριστικό αντικειμένου:

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 χειριστή για να ενημερώσει ένα απαιτούμενο έγγραφο που καλείται από το αναγνωριστικό αντικειμένου του.

ο αποτέλεσμα.MatchedCount Η συνθήκη εμποδίζει την εκτέλεση του κώδικα εάν δεν υπάρχει εγγραφή στη βάση δεδομένων ή εάν το αναγνωριστικό που περάσατε δεν είναι έγκυρο.

γιατί τα δεδομένα verizon μου είναι τόσο αργά

Δημιουργία τερματικού σημείου DELETE

Το τελικό σημείο DELETE, σε delete.go , καταργεί ένα έγγραφο που βασίζεται στο αναγνωριστικό αντικειμένου που μεταβιβάστηκε ως παράμετρος 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 ιδιότητα για να αποτρέψει την εκτέλεση του κώδικα εάν η βάση δεδομένων είναι άδεια ή το αναγνωριστικό αντικειμένου δεν είναι έγκυρο.

Δημιουργήστε το αρχείο API Runner

Τέλος, δημιουργήστε ένα 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")
}

Αυτό το αρχείο είναι το κύριο πακέτο που εκτελεί άλλα αρχεία. Ξεκινά με την εισαγωγή των χειριστών διαδρομής. Επόμενο είναι το δρομολογητή μεταβλητός, α τζιν παράδειγμα που προκαλεί τις ενέργειες HTTP και καλεί κάθε τελικό σημείο με το όνομα της συνάρτησής του από το διαδρομές πακέτο.

Το έργο σας CRUD εκτελείται localhost: 3000 . Για να εκτελέσετε τον διακομιστή και δοκιμάστε το CRUD API , εκτελέστε την ακόλουθη εντολή στον βασικό σας κατάλογο:

go run main.go

Μετατρέψτε το Golang CRUD Project σας σε ένα προϊόν που μπορεί να χρησιμοποιηθεί

Δημιουργήσατε με επιτυχία ένα CRUD API με το Go. Συγχαρητήρια! Αν και αυτό είναι ένα μικρό έργο, έχετε δει τι χρειάζεται για την εκτέλεση κανονικών αιτημάτων HTTP στο Go.

Μπορείτε να γίνετε πιο δημιουργικοί επεκτείνοντας το σε μια πιο πρακτική εφαρμογή που προσφέρει αξία στους χρήστες. Η Go είναι μια κατάλληλη γλώσσα προγραμματισμού για μια σειρά περιπτώσεων χρήσης.