Building a CRUD App with GoFiber and MongoDB: A Step-by-Step Guide

58 views

Building a CRUD Application with GoFiber and MongoDB

Creating a CRUD (Create, Read, Update, Delete) application using GoFiber and MongoDB demonstrates the power and simplicity of GoFiber in handling database-driven web applications. In this guide, we'll walk through the steps to set up a basic CRUD application to manage a collection of documents in MongoDB.

Prerequisites

  • Go installed on your system
  • MongoDB installed and running locally or a MongoDB Atlas account
  • Basic knowledge of Go and MongoDB

Setting Up the Project

  1. Initialize Your Project

    Create a new directory for your project and initialize a new Go module:

    mkdir gofiber-crud
    cd gofiber-crud
    go mod init gofiber-crud
    
  2. Install Dependencies

    Install GoFiber, the MongoDB driver, and other necessary packages:

    go get -u github.com/gofiber/fiber/v2
    go get go.mongodb.org/mongo-driver/mongo
    go get go.mongodb.org/mongo-driver/mongo/options
    
  3. Create a Basic File Structure

    Organize your project files:

    ├── main.go
    ├── handler
    │   └─�� user.go
    └── model
        └── user.go
    

Coding the Application

  1. Defining the User Model

    Create the user.go file inside the model directory:

    package model
    
    import "go.mongodb.org/mongo-driver/bson/primitive"
    
    type User struct {
        ID        primitive.ObjectID `json:"id,omitempty" bson:"_id,omitempty"`
        Name      string             `json:"name" bson:"name"`
        Email     string             `json:"email" bson:"email"`
    }
    
  2. Handling the CRUD Operations

    Create the user.go file inside the handler directory to handle CRUD operations:

    package handler
    
    import (
        "context"
        "gofiber-crud/model"
        "log"
    
        "github.com/gofiber/fiber/v2"
        "go.mongodb.org/mongo-driver/bson"
        "go.mongodb.org/mongo-driver/bson/primitive"
        "go.mongodb.org/mongo-driver/mongo"
        "go.mongodb.org/mongo-driver/mongo/options"
    )
    
    var userCollection *mongo.Collection
    
    func InitDB() {
        clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")
        client, err := mongo.Connect(context.TODO(), clientOptions)
        if err != nil {
            log.Fatal(err)
        }
        err = client.Ping(context.TODO(), nil)
        if err != nil {
            log.Fatal(err)
        }
        userCollection = client.Database("gofiber_crud").Collection("users")
    }
    
    func CreateUser(c *fiber.Ctx) error {
        var user model.User
        if err := c.BodyParser(&user); err != nil {
            return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid JSON"})
        }
        result, err := userCollection.InsertOne(context.TODO(), user)
        if err != nil {
            return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Could not create user"})
        }
        return c.JSON(result)
    }
    
    func GetUser(c *fiber.Ctx) error {
        idParam := c.Params("id")
        id, err := primitive.ObjectIDFromHex(idParam)
        if err != nil {
            return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid user ID"})
        }
    
        var user model.User
        filter := bson.M{"_id": id}
        err = userCollection.FindOne(context.TODO(), filter).Decode(&user)
        if err != nil {
            return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "User not found"})
        }
        return c.JSON(user)
    }
    
    func UpdateUser(c *fiber.Ctx) error {
        idParam := c.Params("id")
        id, err := primitive.ObjectIDFromHex(idParam)
        if err != nil {
            return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid user ID"})
        }
    
        var user model.User
        if err := c.BodyParser(&user); err != nil {
            return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid JSON"})
        }
    
        filter := bson.M{"_id": id}
        update := bson.M{"$set": user}
        result, err := userCollection.UpdateOne(context.TODO(), filter, update)
        if err != nil {
            return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Could not update user"})
        }
        return c.JSON(result)
    }
    
    func DeleteUser(c *fiber.Ctx) error {
        idParam := c.Params("id")
        id, err := primitive.ObjectIDFromHex(idParam)
        if err != nil {
            return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid user ID"})
        }
    
        filter := bson.M{"_id": id}
        result, err := userCollection.DeleteOne(context.TODO(), filter)
        if err != nil {
            return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Could not delete user"})
        }
        return c.JSON(result)
    }
    
  3. Creating the Main Application

    Finally, create the main.go file and set up the routes:

    package main
    
    import (
        "gofiber-crud/handler"
    
        "github.com/gofiber/fiber/v2"
    )
    
    func main() {
        // Initialize the database connection
        handler.InitDB()
    
        // Create a new Fiber app
        app := fiber.New()
    
        // Define the routes and their handlers
        app.Post("/users", handler.CreateUser)
        app.Get("/users/:id", handler.GetUser)
        app.Put("/users/:id", handler.UpdateUser)
        app.Delete("/users/:id", handler.DeleteUser)
    
        // Start the server
        app.Listen(":3000")
    }
    

Running the Application

To run your application, use the following command:

go run main.go

Your server should now be running, and you can test your CRUD endpoints using tools like Postman or cURL. For example, to create a new user, you can send a POST request to http://localhost:3000/users with a JSON body:

{
    "name": "John Doe",
    "email": "john@example.com"
}

Conclusion

This guide provides a foundational setup for a CRUD application using GoFiber and MongoDB. By leveraging GoFiber's simplicity and Go's performance, along with MongoDB's flexibility, you can efficiently build and scale web applications. This example can be further extended with more functionalities, error handling, and deployments, depending on your project requirements.