Как да създадете CRUD API с Gin на Golang и MongoDB

Как да създадете CRUD API с Gin на Golang и MongoDB

Golang е един от най-добре плащащите и търсени езици за програмиране с много приложения. Когато сте сдвоени с рамки като Gin, Revel и gorilla/mux, можете лесно да създадете API с Go.





Научете как да създадете CRUD API в Golang с помощта на Gin HTTP framework.





MAKEUSEOF ВИДЕО НА ДЕНЯ

Първоначална настройка и инсталация

Започнете с 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
}

Най-добрата практика е да скриете променливите на средата като низа за свързване към базата данни в a .env файл с помощта на пакета dotenv . Това прави вашия код по-преносим и е полезен, когато използвате a Екземпляр на облачен клъстер MongoDB , например.

The ConnectDB функцията установява връзка и връща нов клиентски обект на MongoDB.

Създаване на колекция от бази данни

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 в 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('пост') е екземпляр на модел JSON, който извиква всяко поле на модел като postPayload ; това влиза в базата данни.

Как да създадете GET крайна точка

Крайната точка GET, в routes/read.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})
}

The публикации променливата е декларация на параметър. Получава идентификатор на обект на документ като objId .

Въпреки това, резултат е екземпляр на модела на базата данни, който по-късно съхранява върнатия документ като рез .

Как да създадете крайна точка 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 оператор за актуализиране на изискван документ, извикан от неговия идентификатор на обект.

The result.MatchedCount условие предотвратява изпълнението на кода, ако няма запис в базата данни или предаденият идентификатор е невалиден.

Създаване на 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

Накрая създайте a main.go в главната директория на вашия проект. Вашата окончателна структура на проекта трябва да изглежда така:

  Структура на проекта Golang CRUD

Този файл управлява изпълнението на рутера за всяка крайна точка:

копирайте файлове от mac на компютър
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 проект продължава локален хост: 3000 . За да стартирате сървъра и тествайте CRUD API , изпълнете следната команда във вашата основна директория:

go run main.go

Превърнете проекта си Golang CRUD в използваем продукт

Успешно създадохте CRUD API с Go; Честито! Въпреки че това е малък проект, видяхте какво е необходимо за изпълнение на редовни HTTP заявки в Go.

Можете да станете по-креативни, като разширите това в по-практично приложение, което предоставя стойност на потребителите. Go е подходящ език за програмиране за редица случаи на употреба.