Hur man skapar ett CRUD API med Golangs Gin och MongoDB

Hur man skapar ett CRUD API med Golangs Gin och MongoDB

Golang är ett av de bäst betalande, efterfrågade programmeringsspråken med många applikationer. När du paras ihop med ramverk som Gin, Revel och gorilla/mux kan du enkelt skapa ett API med Go.





Lär dig hur du skapar ett CRUD API i Golang med hjälp av Gin HTTP-ramverket.





MAKEUSE AV DAGENS VIDEO

Initial installation och installation

Kom igång med Golang genom att installera det på din dator om du inte redan har gjort det.





När det är installerat är nästa steg att skapa en projektrotmapp på din dator och initiera en Go-modul i den rotkatalogen.

För att göra detta, öppna en CLI , navigera till din projektrotmapp och kör:



go mod init module_name 

Du kommer att se ditt modulnamn (t.ex. CRUD_API ) och dess version när du öppnar go.mod fil. Alla anpassade paket kommer från denna överordnade modul. Så alla importerade anpassade paket tar formen:

import(package CRUD_API/package-directory-name)

Installera sedan de paket som krävs för att skapa CRUD API. Använd i det här fallet Gin Gonic för att dirigera API-slutpunkterna:





go get github.com/gin-gonic/gin 

Installera nu MongoDB-drivrutinen för att lagra data:

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

Hur man ansluter Gå till MongoDB

Allt du behöver är din MongoDB URI för att koppla Golang till databasen. Det ser vanligtvis ut så här om du ansluter till MongoDB Atlas lokalt:





Mongo_URL = "mongodb://127.0.0.1:27017"

Skapa nu en ny mapp i ditt projekts rotkatalog och anrop den databaser . Skapa en Go-fil i den här mappen och namnge den database.go .

Detta är ditt databaspaket, och det börjar med att importera de nödvändiga biblioteken:

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 är bästa praxis att dölja miljövariabler som databasanslutningssträngen i en .env fil använder dotenv-paketet . Detta gör din kod mer portabel och kommer väl till pass när du använder en MongoDB molnklusterinstans , till exempel.

behöver jag ett modem och en router

De ConnectDB funktionen upprättar en anslutning och returnerar ett nytt MongoDB Client-objekt.

Skapa databassamling

MongoDB lagrar data i samlingar, som ger ett gränssnitt till underliggande databasdata.

För att hantera samlingshämtningsfunktionen, börja med att skapa en ny mapp, Samling , i din projektrot. Skapa nu en ny Go-fil, getCollection.go , som hämtar samlingen från 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
}

Denna funktion hämtar samlingen från MongoDB-databasen. Databasnamnet, i det här fallet, är myGoappDB , med Inlägg som sin samling.

Skapa databasmodellen

Skapa en ny mapp i din rotkatalog och anropa den modell . Den här mappen hanterar din databasmodell.

Skapa en ny Go-fil i den mappen och anropa den model.go . Din modell, i det här fallet, är ett blogginlägg med dess titel:

hur man tar bort konton på ps4
package model 

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

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

Skapa ett CRUD API med Go

Nästa upp är CRUD API-skapandet. För att börja med det här avsnittet, skapa en ny mapp i projektets rotkatalog för att hantera dina slutpunkter. Kalla det rutter .

Skapa en separat Go-fil i den här mappen för varje åtgärd. Du kan till exempel namnge dem create.go , läs.gå , update.go , och delete.go . Du exporterar dessa hanterare som rutter paket.

Hur man skapar POST-slutpunkten i Go

Börja med att definiera POST-slutpunkten för att skriva data till databasen.

Inuti routes/create.go , lägg till följande:

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

Denna kod börjar med att importera projektets anpassade moduler. Den importerar sedan tredjepartspaket inklusive Gin och Drivrutinen för MongoDB .

Ytterligare, postsamling innehar databassamlingen. I synnerhet, c.BindJSON('post') är en JSONifierad modellinstans som anropar varje modellfält som postPayload ; detta går in i databasen.

Hur man skapar GET-slutpunkten

GET-slutpunkten, in routes/read.go , läser ett enstaka dokument från databasen via dess unika ID. Det börjar också med att importera anpassade och tredjepartspaket:

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

De inlägg variabel är en parameterdeklaration. Den får ett dokuments objekt-ID som objId .

I alla fall, resultat är en instans av databasmodellen, som senare håller det returnerade dokumentet som res .

Hur man skapar PUT Endpoint

PUT-hanteraren, in routes/update.go , liknar POST-hanteraren. Den här gången uppdaterar den ett befintligt inlägg med dess unika 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})
}

Ett JSON-format för modellinstansen ( posta ) anropar varje modellfält från databasen. Resultatvariabeln använder MongoDB $set operatör för att uppdatera ett obligatoriskt dokument som anropas av dess objekt-ID.

De resultat.MatchedCount villkor förhindrar att koden körs om det inte finns någon post i databasen eller om det skickade ID:t är ogiltigt.

Skapa en DELETE-slutpunkt

DELETE-slutpunkten, in delete.go , tar bort ett dokument baserat på det objekt-ID som skickats 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})
}

Denna kod tar bort en post med hjälp av DeleteOne fungera. Den använder också resultat.DeletedCount egenskap för att förhindra att koden körs om databasen är tom eller om objekt-ID är ogiltigt.

Skapa API Runner-filen

Slutligen, skapa en main.go i ditt projekts rotkatalog. Din slutliga projektstruktur bör se ut så här:

hur man fixar eko i hörlurar
  Golang CRUD projektstruktur

Den här filen hanterar routerkörning för varje 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")
}

Den här filen är huvudpaketet som kör andra filer. Det börjar med att importera rutthanterarna. Nästa är router variabel, a gin instans som framkallar HTTP-åtgärderna och anropar varje slutpunkt med dess funktionsnamn från rutter paket.

Ditt CRUD-projekt fortsätter lokal värd: 3000 . För att köra servern och testa CRUD API , kör följande kommando i din baskatalog:

go run main.go

Förvandla ditt Golang CRUD-projekt till en användbar produkt

Du har framgångsrikt skapat ett CRUD API med Go; grattis! Även om detta är ett mindre projekt, har du sett vad som krävs för att utföra vanliga HTTP-förfrågningar i Go.

Du kan bli mer kreativ genom att utöka detta till en mer praktisk applikation som levererar värde till användarna. Go är ett lämpligt programmeringsspråk för en rad användningsfall.