Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
package main
// to run:
// launch mongodb container: docker run -p 27017:27017 --name local-dev-mongodb -d mongo:latest
// start service: go run main.go
import (
"context"
"log"
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/rs/xid"
"gopkg.in/mgo.v2/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/mongo/readpref"
)
type Todo struct {
ID string `json:"id"`
Title string `json:"title"`
Body string `json:"body"`
Completed string `json:"completed"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
var collection *mongo.Collection
func TodoCollection(c *mongo.Database) {
collection = c.Collection("todos")
}
func GetAllTodos(c *gin.Context) {
todos := []Todo{}
cursor, err := collection.Find(context.TODO(), bson.M{})
if err != nil {
log.Printf("Error while getting all todos, Reason: %v\n", err)
c.JSON(http.StatusInternalServerError, gin.H{
"status": http.StatusInternalServerError,
"message": "Something went wrong",
})
return
}
for cursor.Next(context.TODO()) {
var todo Todo
cursor.Decode(&todo)
todos = append(todos, todo)
}
c.JSON(http.StatusOK, gin.H{
"status": http.StatusOK,
"message": "All Todos",
"data": todos,
})
return
}
func CreateTodo(c *gin.Context) {
var todo Todo
c.BindJSON(&todo)
title := todo.Title
body := todo.Body
completed := todo.Completed
id := xid.New().String()
newTodo := Todo{
ID: id,
Title: title,
Body: body,
Completed: completed,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
_, err := collection.InsertOne(context.TODO(), newTodo)
if err != nil {
log.Printf("Error while inserting new todo into db, Reason: %v\n", err)
c.JSON(http.StatusInternalServerError, gin.H{
"status": http.StatusInternalServerError,
"message": "Something went wrong",
})
return
}
c.JSON(http.StatusCreated, gin.H{
"status": http.StatusCreated,
"message": "Todo created Successfully",
})
return
}
func GetSingleTodo(c *gin.Context) {
todoId := c.Param("todoId")
todo := Todo{}
err := collection.FindOne(context.TODO(), bson.M{"id": todoId}).Decode(&todo)
if err != nil {
log.Printf("Error while getting a single todo, Reason: %v\n", err)
c.JSON(http.StatusNotFound, gin.H{
"status": http.StatusNotFound,
"message": "Todo not found",
})
return
}
c.JSON(http.StatusOK, gin.H{
"status": http.StatusOK,
"message": "Single Todo",
"data": todo,
})
return
}
func EditTodo(c *gin.Context) {
todoId := c.Param("todoId")
var todo Todo
c.BindJSON(&todo)
completed := todo.Completed
newData := bson.M{
"$set": bson.M{
"completed": completed,
"updated_at": time.Now(),
},
}
_, err := collection.UpdateOne(context.TODO(), bson.M{"id": todoId}, newData)
if err != nil {
log.Printf("Error, Reason: %v\n", err)
c.JSON(http.StatusInternalServerError, gin.H{
"status": 500,
"message": "Something went wrong",
})
return
}
c.JSON(http.StatusOK, gin.H{
"status": 200,
"message": "Todo Edited Successfully",
})
return
}
func DeleteTodo(c *gin.Context) {
todoId := c.Param("todoId")
_, err := collection.DeleteOne(context.TODO(), bson.M{"id": todoId})
if err != nil {
log.Printf("Error while deleting a single todo, Reason: %v\n", err)
c.JSON(http.StatusInternalServerError, gin.H{
"status": http.StatusInternalServerError,
"message": "Something went wrong",
})
return
}
c.JSON(http.StatusOK, gin.H{
"status": http.StatusOK,
"message": "Todo deleted successfully",
})
return
}
func Connect() {
clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")
client, err := mongo.NewClient(clientOptions)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
err = client.Connect(ctx)
defer cancel()
err = client.Ping(context.Background(), readpref.Primary())
if err != nil {
log.Fatal("Couldn't connect to the database", err)
} else {
log.Println("Connected!")
}
db := client.Database("go_mongo")
TodoCollection(db)
return
}
func Routes(router *gin.Engine) {
router.GET("/", welcome)
router.GET("/todos", GetAllTodos)
router.POST("/todo", CreateTodo)
router.GET("/todo/:todoId", GetSingleTodo)
router.PUT("/todo/:todoId", EditTodo)
router.DELETE("/todo/:todoId", DeleteTodo)
router.NoRoute(notFound)
}
func welcome(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"status": 200,
"message": "Welcome To API",
})
return
}
func notFound(c *gin.Context) {
c.JSON(http.StatusNotFound, gin.H{
"status": 404,
"message": "Route Not Found",
})
return
}
func main() {
Connect()
router := gin.Default()
Routes(router)
log.Fatal(router.Run(":8080"))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment