Como criar uma API CRUD com Gin e MongoDB de Golang

Como criar uma API CRUD com Gin e MongoDB de Golang

Golang é uma das linguagens de programação mais bem pagas e sob demanda com muitos aplicativos. Quando emparelhado com estruturas como Gin, Revel e gorilla/mux, você pode criar facilmente uma API com Go.





Saiba como criar uma API CRUD em Golang usando a estrutura Gin HTTP.





MAKEUSEO VÍDEO DO DIA

Configuração e instalação iniciais

Comece com Golang instalando-o no seu computador, caso ainda não o tenha feito.





Uma vez instalado, o próximo passo é criar uma pasta raiz do projeto em sua máquina e inicializar um módulo Go nesse diretório raiz.

Para isso, abra uma CLI , navegue até a pasta raiz do projeto e execute:



go mod init module_name 

Você verá o nome do seu módulo (por exemplo, CRUD_API ) e sua versão ao abrir o go.mod Arquivo. Todos os pacotes personalizados virão deste módulo pai. Portanto, qualquer pacote personalizado importado assume o formato:

import(package CRUD_API/package-directory-name)

Em seguida, instale os pacotes necessários para criar a API CRUD. Neste caso, use Gin Gônica para rotear os endpoints da API:





7D64D0FBC853F8BDC948ADBBF20D8D91650F9403

Agora instale o Driver MongoDB para armazenar dados:

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

Como conectar-se ao MongoDB

Tudo o que você precisa é do seu URI do MongoDB para conectar o Golang ao banco de dados. Normalmente se parece com isso se você estiver se conectando ao MongoDB Atlas localmente:





Mongo_URL = "mongodb://127.0.0.1:27017"

Agora crie uma nova pasta no diretório raiz do seu projeto e chame-a bancos de dados . Crie um arquivo Go dentro desta pasta e nomeie-o banco de dados.go .

Este é o seu pacote de banco de dados e começa importando as bibliotecas necessárias:

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
}

É uma prática recomendada ocultar variáveis ​​de ambiente como a string de conexão do banco de dados em um .env Arquivo usando o pacote dotenv . Isso torna seu código mais portátil e é útil ao usar um Instância de cluster de nuvem MongoDB , por exemplo.

o ConnectDB A função estabelece uma conexão e retorna um novo objeto MongoDB Client.

Criar coleção de banco de dados

O MongoDB armazena dados em Collections, que fornecem uma interface para os dados subjacentes do banco de dados.

Para lidar com a funcionalidade de busca de coleção, comece criando uma nova pasta, Coleção , na raiz do seu projeto. Agora crie um novo arquivo Go, getCollection.go , que obtém a coleção do banco de dados:

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
}

Esta função obtém a coleção do banco de dados MongoDB. O nome do banco de dados, neste caso, é myGoappDB , com Postagens como sua coleção.

Criar o modelo de banco de dados

Crie uma nova pasta dentro do seu diretório raiz e chame-a modelo . Esta pasta lida com seu modelo de banco de dados.

Crie um novo arquivo Go dentro dessa pasta e chame-o model.go . Seu modelo, neste caso, é uma postagem de blog com o título:

package model 

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

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

Criando uma API CRUD com Go

Em seguida é a criação da API CRUD. Para começar com esta seção, crie uma nova pasta dentro do diretório raiz do projeto para lidar com seus endpoints. Chame-o rotas .

Crie um arquivo Go separado nesta pasta para cada ação. Por exemplo, você pode nomeá-los criar.go , leia.go , update.go , e delete.go . Você exportará esses manipuladores como o rotas pacote.

Como criar o endpoint POST em Go

Comece definindo o endpoint POST para gravar dados no banco de dados.

seja pago para testar aplicativos Android

Lado de dentro rotas/criar.go , adicione o seguinte:

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

Esse código começa importando os módulos personalizados do projeto. Em seguida, ele importa pacotes de terceiros, incluindo Gin e Driver MongoDB .

Mais longe, postColeção mantém a coleção de banco de dados. Notavelmente, c.BindJSON('postar') é uma instância de modelo JSONified que chama cada campo de modelo como postPayload ; isso vai para o banco de dados.

Como criar o ponto de extremidade GET

O endpoint GET, em rotas/read.go , lê um único documento do banco de dados por meio de seu ID exclusivo. Ele também começa importando pacotes personalizados e de terceiros:

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

o Postagens variável é uma declaração de parâmetro. Ele obtém o ID do objeto de um documento como objId .

No entanto, resultado é uma instância do modelo de banco de dados, que posteriormente contém o documento retornado como res .

Como criar o ponto de extremidade PUT

O manipulador PUT, em rotas/atualização.go , é semelhante ao manipulador POST. Desta vez, ele atualiza uma postagem existente por seu ID de objeto exclusivo:

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

Um formato JSON da instância do modelo ( publicar ) chama cada campo de modelo do banco de dados. A variável de resultado usa o MongoDB $set operador para atualizar um documento necessário chamado por seu ID de objeto.

o result.MatchedCount condição impede que o código seja executado se não houver registro no banco de dados ou o ID passado for inválido.

Criando um ponto de extremidade DELETE

O ponto de extremidade DELETE, em delete.go , remove um documento com base no ID do objeto passado como parâmetro de 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})
}

Este código exclui um registro usando o Excluir um função. Também utiliza o resultado.DeletedCount para impedir que o código seja executado se o banco de dados estiver vazio ou o ID do objeto for inválido.

Crie o arquivo do executor da API

Por fim, crie um main.go dentro do diretório raiz do seu projeto. A estrutura final do seu projeto deve ficar assim:

  Estrutura do projeto Golang CRUD

Este arquivo trata da execução do roteador para cada endpoint:

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

Este arquivo é o pacote principal que executa outros arquivos. Ele começa importando os manipuladores de rota. A seguir é o roteador variável, um Gin instância que evoca as ações HTTP e chama cada endpoint por seu nome de função do rotas pacote.

Seu projeto CRUD é executado em localhost:3000 . Para executar o servidor e testar a API CRUD , execute o seguinte comando em seu diretório base:

go run main.go

Transforme seu projeto Golang CRUD em um produto utilizável

Você criou com sucesso uma API CRUD com Go; Parabéns! Embora este seja um projeto menor, você viu o que é necessário para executar solicitações HTTP regulares em Go.

Você pode ser mais criativo expandindo isso para um aplicativo mais prático que agrega valor aos usuários. Go é uma linguagem de programação adequada para uma variedade de casos de uso.