Sådan opretter du en CRUD API med Golang's Gin og MongoDB

Sådan opretter du en CRUD API med Golang's Gin og MongoDB

Golang er et af de bedst betalende, efterspurgte programmeringssprog med mange applikationer. Når du er parret med rammer som Gin, Revel og gorilla/mux, kan du nemt oprette en API med Go.





Lær, hvordan du opretter en CRUD API i Golang ved hjælp af Gin HTTP-rammeværket.





MAKEUSE AF DAGENS VIDEO

Indledende opsætning og installation

Kom godt i gang med Golang ved at installere det på din computer, hvis du ikke allerede har gjort det.





Når det er installeret, er næste trin at oprette en projektrodmappe på din maskine og initialisere et Go-modul i den rodmappe.

For at gøre dette skal du åbne en CLI , naviger til din projektrodmappe og kør:



go mod init module_name 

Du vil se dit modulnavn (f.eks. CRUD_API ) og dens version, når du åbner go.mod fil. Alle tilpassede pakker kommer fra dette overordnede modul. Så enhver importeret tilpasset pakke har formen:

import(package CRUD_API/package-directory-name)

Installer derefter de nødvendige pakker til at oprette CRUD API. Brug i dette tilfælde Gin Gonic for at dirigere API-endepunkterne:





go get github.com/gin-gonic/gin 

Installer nu MongoDB-driveren for at gemme data:

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

Sådan forbinder du Gå til MongoDB

Alt du behøver er din MongoDB URI for at forbinde Golang med databasen. Det ser typisk sådan ud, hvis du opretter forbindelse til MongoDB Atlas lokalt:





Mongo_URL = "mongodb://127.0.0.1:27017"

Opret nu en ny mappe i dit projekts rodmappe og kald den databaser . Opret en Go-fil i denne mappe, og navngiv den database.go .

Dette er din databasepakke, og den starter med at importere de nødvendige biblioteker:

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
}

Det er bedste praksis at skjule miljøvariabler som databaseforbindelsesstrengen i en .env fil ved hjælp af dotenv-pakken . Dette gør din kode mere bærbar og er praktisk, når du bruger en MongoDB cloud cluster instans , for eksempel.

hvordan du blokerer dit nummer, når du foretager et opkald

Det ConnectDB funktionen etablerer en forbindelse og returnerer et nyt MongoDB Client-objekt.

Opret databasesamling

MongoDB gemmer data i samlinger, som giver en grænseflade til de underliggende databasedata.

For at håndtere samlingshentningsfunktionen skal du starte med at oprette en ny mappe, Kollektion , i dit projektrod. Opret nu en ny Go-fil, getCollection.go , der henter samlingen fra databasen:

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
}

Denne funktion henter samlingen fra MongoDB-databasen. Databasenavnet er i dette tilfælde myGoappDB , med Indlæg som sin samling.

Opret databasemodellen

Lav en ny mappe inde i din rodmappe og kald den model . Denne mappe håndterer din databasemodel.

Opret en ny Go-fil i den mappe, og kald den model.go . Din model er i dette tilfælde et blogindlæg med titlen:

package model 

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

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

Oprettelse af en CRUD API med Go

Næste op er oprettelsen af ​​CRUD API. For at starte med denne sektion skal du lave en ny mappe i dit projekts rodbibliotek til at håndtere dine slutpunkter. Kald det ruter .

Opret en separat Go-fil i denne mappe for hver handling. For eksempel kan du navngive dem create.go , læs.gå , update.go , og delete.go . Du eksporterer disse behandlere som ruter pakke.

Sådan opretter du POST-endepunktet i Go

Start med at definere POST-slutpunktet for at skrive data ind i databasen.

Inde routes/create.go , tilføj følgende:

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

Denne kode starter med at importere projektets brugerdefinerede moduler. Det importerer derefter tredjepartspakker, inklusive Gin og MongoDB driver .

Yderligere, postsamling holder databasesamlingen. Især c.BindJSON('post') er en JSONificeret modelforekomst, der kalder hvert modelfelt som postPayload ; dette går ind i databasen.

hvordan man sletter en fil, der er åben i et andet program

Sådan opretter du GET-slutpunktet

GET-endepunktet, i routes/read.go , læser et enkelt dokument fra databasen via dets unikke ID. Det starter også med at importere brugerdefinerede og tredjepartspakker:

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

Det indlæg variabel er en parametererklæring. Den får et dokuments objekt-id som objId .

Imidlertid, resultat er en instans af databasemodellen, som senere holder det returnerede dokument som res .

Sådan opretter du PUT-endepunktet

PUT-handleren, i routes/update.go , ligner POST-handleren. Denne gang opdaterer den et eksisterende indlæg ved dets unikke objekt-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})
}

Et JSON-format af modelforekomsten ( stolpe ) kalder hvert modelfelt fra databasen. Resultatvariablen bruger MongoDB $sæt operatør for at opdatere et påkrævet dokument kaldet af dets objekt-id.

Det resultat.MatchedCount betingelse forhindrer koden i at køre, hvis der ikke er nogen post i databasen, eller det beståede ID er ugyldigt.

hvad skal man kontrollere, når man køber en brugt iphone

Oprettelse af et DELETE-slutpunkt

DELETE-slutpunktet, i delete.go , fjerner et dokument baseret på det objekt-id, der er sendt som en URL-parameter:

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

Denne kode sletter en post ved hjælp af DeleteOne fungere. Den bruger også resultat.DeletedCount egenskab for at forhindre koden i at køre, hvis databasen er tom, eller objekt-id'et er ugyldigt.

Opret API Runner-filen

Til sidst skal du oprette en main.go inde i dit projekts rodmappe. Din endelige projektstruktur skal se sådan ud:

  Golang CRUD projektstruktur

Denne fil håndterer routerkørsel for hvert slutpunkt:

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

Denne fil er hovedpakken, der kører andre filer. Det starter med at importere rutebehandlerne. Næste er router variabel, en gin instans, der fremkalder HTTP-handlingerne og kalder hvert slutpunkt ved dets funktionsnavn fra ruter pakke.

Dit CRUD-projekt kører videre lokalvært: 3000 . For at køre serveren og test CRUD API , kør følgende kommando i din basismappe:

go run main.go

Gør dit Golang CRUD-projekt til et brugbart produkt

Du har oprettet en CRUD API med Go; Tillykke! Selvom dette er et mindre projekt, har du set, hvad der skal til for at udføre almindelige HTTP-anmodninger i Go.

Du kan blive mere kreativ ved at udvide dette til en mere praktisk applikation, der leverer værdi til brugerne. Go er et velegnet programmeringssprog til en række anvendelsestilfælde.