Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      From Data To Decisions: UX Strategies For Real-Time Dashboards

      September 13, 2025

      Honeycomb launches AI observability suite for developers

      September 13, 2025

      Low-Code vs No-Code Platforms for Node.js: What CTOs Must Know Before Investing

      September 12, 2025

      ServiceNow unveils Zurich AI platform

      September 12, 2025

      DistroWatch Weekly, Issue 1139

      September 14, 2025

      Building personal apps with open source and AI

      September 12, 2025

      What Can We Actually Do With corner-shape?

      September 12, 2025

      Craft, Clarity, and Care: The Story and Work of Mengchu Yao

      September 12, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      Optimizely Mission Control – Part III

      September 14, 2025
      Recent

      Optimizely Mission Control – Part III

      September 14, 2025

      Learning from PHP Log to File Example

      September 13, 2025

      Online EMI Calculator using PHP – Calculate Loan EMI, Interest, and Amortization Schedule

      September 13, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured

      DistroWatch Weekly, Issue 1139

      September 14, 2025
      Recent

      DistroWatch Weekly, Issue 1139

      September 14, 2025

      sudo vs sudo-rs: What You Need to Know About the Rust Takeover of Classic Sudo Command

      September 14, 2025

      Dmitry — The Deep Magic

      September 13, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»Development»How to Use MongoDB with Go

    How to Use MongoDB with Go

    July 31, 2025

    Working with databases is a fundamental part of backend development, particularly when you’re building applications that require persisting, querying, and updating data.

    In Go, the official MongoDB driver provides a robust way to connect to and interact with MongoDB, a flexible NoSQL database that stores data in JSON-like documents.

    In this tutorial, you won’t just learn how to connect Go to MongoDB. You’ll take it a step further by building a simple blog application. Along the way, you’ll learn how to perform essential CRUD (Create, Read, Update, Delete) operations and display your results using the Gin web framework.

    Table of Contents

    • Prerequisites

    • Create a New Go Project

    • Basic MongoDB Operations

      • Insert data into the collection

      • Find documents in MongoDB

      • Update documents in MongoDB

      • Delete documents in MongoDB

    • How to Build a Blog App with go-mongodb-driver and Gin

      • Initialize the Gin application

      • Create the HTML templates

      • Create the handlers

      • Run the application

    • That’s How to Use MongoDB with Go

    Prerequisites

    Before you proceed, ensure that you have the following:

    • Basic knowledge of Go and its concepts

    • Go (version 1.24 or higher) installed

    • MongoDB Installed (running locally on port 27017)

    • Basic knowledge of NoSQL

    Create a New Go Project

    First, create a new Go project, change into the new project directory, and initialize a new Go module by running the following commands:

    mkdir go-mongodb-integration
    <span class="hljs-built_in">cd</span> go-mongodb-integrationgo 
    mod init go-mongodb
    

    Next, install the MongoDB Go driver by running the following command:

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

    The standard Go library includes the database/sql package for working with SQL databases, but it doesn’t support MongoDB out of the box. To work with MongoDB in Go, you’ll use the official MongoDB driver, which provides everything you need to connect to and interact with a MongoDB database.

    With the basic setup complete, let’s now examine basic operations in MongoDB.

    Basic MongoDB Operations

    In MongoDB, databases and collections are created automatically upon the first data insertion, adopting a “lazy creation” approach. Specifically, a database is created when you insert your first document, and a collection is likewise created when data is first inserted into it.

    It’s important to note that functions like client.Database() and db.Collection() only generate references to these structures – they don’t create the actual database or collection until data is inserted.

    Insert data into the collection

    Let’s walk through how to insert a document into a collection in MongoDB.

    First, open your project in a code editor, create a main.go file, and add the following code:

    <span class="hljs-keyword">package</span> main
    
    <span class="hljs-keyword">import</span> (
        <span class="hljs-string">"context"</span>
        <span class="hljs-string">"log"</span>
        <span class="hljs-string">"time"</span>
    
        <span class="hljs-string">"go.mongodb.org/mongo-driver/bson/primitive"</span>
        <span class="hljs-string">"go.mongodb.org/mongo-driver/mongo"</span>
        <span class="hljs-string">"go.mongodb.org/mongo-driver/mongo/options"</span>
    )
    
    <span class="hljs-keyword">type</span> User <span class="hljs-keyword">struct</span> {
        ID   primitive.ObjectID <span class="hljs-string">`bson:"_id,omitempty"`</span>
        Name <span class="hljs-keyword">string</span>             <span class="hljs-string">`bson:"name"`</span>
        Age  <span class="hljs-keyword">int</span>                <span class="hljs-string">`bson:"age"`</span>
    }
    
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
        clientOptions := options.Client().ApplyURI(<span class="hljs-string">"mongodb://localhost:27017"</span>)
    
        ctx, cancel := context.WithTimeout(context.Background(), <span class="hljs-number">10</span>*time.Second)
        <span class="hljs-keyword">defer</span> cancel()
    
        client, err := mongo.Connect(ctx, clientOptions)
        <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
            log.Fatal(err)
        }
        <span class="hljs-keyword">defer</span> client.Disconnect(ctx)
    
        err = client.Ping(ctx, <span class="hljs-literal">nil</span>)
        <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
            log.Fatal(err)
        }
    
        db := client.Database(<span class="hljs-string">"test_db"</span>)
        usersCollection := db.Collection(<span class="hljs-string">"users"</span>)
    
        newUser := User{
            Name: <span class="hljs-string">"John Doe"</span>,
            Age:  <span class="hljs-number">30</span>,
        }
    
        result, err := usersCollection.InsertOne(ctx, newUser)
        <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
            log.Fatal(err)
        }
    
        log.Printf(<span class="hljs-string">"Inserted user with ID: %vn"</span>, result.InsertedID)
    }
    

    In the code above, you define a User struct that represents your document structure, then insert a new user document into the collection using the InsertOne method. When you run this insert operation, MongoDB automatically creates both the test_db database and the users collection if they don’t already exist.

    Execute the code by running:

    go run main.go
    

    You should see the response below, indicating that a user was inserted successfully.

    A command line interface showing the command `go run main.go` with an output that says, "Inserted user with ID: ObjectID('6862f3112341b0492801633b')" on June 30, 2025.

    Find documents in MongoDB

    Now that you’ve inserted some data, it’s time to query the database and retrieve documents.

    Update your main.go file with the following code:

    <span class="hljs-keyword">package</span> main
    
    <span class="hljs-keyword">import</span> (
        <span class="hljs-string">"context"</span>
        <span class="hljs-string">"fmt"</span>
        <span class="hljs-string">"log"</span>
        <span class="hljs-string">"time"</span>
    
        <span class="hljs-string">"go.mongodb.org/mongo-driver/bson"</span>
        <span class="hljs-string">"go.mongodb.org/mongo-driver/bson/primitive"</span>
        <span class="hljs-string">"go.mongodb.org/mongo-driver/mongo"</span>
        <span class="hljs-string">"go.mongodb.org/mongo-driver/mongo/options"</span>
    )
    
    <span class="hljs-keyword">type</span> User <span class="hljs-keyword">struct</span> {
        ID   primitive.ObjectID <span class="hljs-string">`bson:"_id,omitempty"`</span>
        Name <span class="hljs-keyword">string</span>             <span class="hljs-string">`bson:"name"`</span>
        Age  <span class="hljs-keyword">int</span>                <span class="hljs-string">`bson:"age"`</span>
    }
    
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
        clientOptions := options.Client().ApplyURI(<span class="hljs-string">"mongodb://localhost:27017"</span>)
    
        ctx, cancel := context.WithTimeout(context.Background(), <span class="hljs-number">10</span>*time.Second)
        <span class="hljs-keyword">defer</span> cancel()
    
        client, err := mongo.Connect(ctx, clientOptions)
        <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
            log.Fatal(err)
        }
        <span class="hljs-keyword">defer</span> client.Disconnect(ctx)
    
        db := client.Database(<span class="hljs-string">"test_db"</span>)
        usersCollection := db.Collection(<span class="hljs-string">"users"</span>)
    
        cursor, err := usersCollection.Find(ctx, bson.M{})
        <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
            log.Fatal(err)
        }
        <span class="hljs-keyword">defer</span> cursor.Close(ctx)
    
        <span class="hljs-keyword">var</span> users []User
        <span class="hljs-keyword">if</span> err = cursor.All(ctx, &users); err != <span class="hljs-literal">nil</span> {
            log.Fatal(err)
        }
    
        <span class="hljs-keyword">for</span> _, user := <span class="hljs-keyword">range</span> users {
            fmt.Printf(<span class="hljs-string">"User: %s, Age: %d, ID: %sn"</span>, user.Name, user.Age, user.ID.Hex())
        }
    }
    

    In the code above, you use the Find method with an empty filter (`bson.M{}`) to retrieve all documents from the users collection. Then, you use cursor.All to decode all the results into a slice of User structs.

    Each document is printed to the terminal, showing the name, age, and ID of every user in the collection.

    To run the code, use:

    go run main.go
    

    You should see the response below in your terminal.

    Screenshot of a terminal showing a Go command execution and output with user information including name, age, and ID.

    Update documents in MongoDB

    To update a document in your collection, modify your main.go file as shown below:

    <span class="hljs-keyword">package</span> main
    
    <span class="hljs-keyword">import</span> (
        <span class="hljs-string">"context"</span>
        <span class="hljs-string">"log"</span>
        <span class="hljs-string">"time"</span>
    
        <span class="hljs-string">"go.mongodb.org/mongo-driver/bson"</span>
        <span class="hljs-string">"go.mongodb.org/mongo-driver/bson/primitive"</span>
        <span class="hljs-string">"go.mongodb.org/mongo-driver/mongo"</span>
        <span class="hljs-string">"go.mongodb.org/mongo-driver/mongo/options"</span>
    )
    
    <span class="hljs-keyword">type</span> User <span class="hljs-keyword">struct</span> {
        ID   primitive.ObjectID <span class="hljs-string">`bson:"_id,omitempty"`</span>
        Name <span class="hljs-keyword">string</span>             <span class="hljs-string">`bson:"name"`</span>
        Age  <span class="hljs-keyword">int</span>                <span class="hljs-string">`bson:"age"`</span>
    }
    
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
        clientOptions := options.Client().ApplyURI(<span class="hljs-string">"mongodb://localhost:27017"</span>)
        ctx, cancel := context.WithTimeout(context.Background(), <span class="hljs-number">10</span>*time.Second)
        <span class="hljs-keyword">defer</span> cancel()
    
        client, err := mongo.Connect(ctx, clientOptions)
        <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
            log.Fatal(err)
        }
        <span class="hljs-keyword">defer</span> client.Disconnect(ctx)
    
        db := client.Database(<span class="hljs-string">"test_db"</span>)
        usersCollection := db.Collection(<span class="hljs-string">"users"</span>)
    
        <span class="hljs-keyword">var</span> userToUpdate User
        err = usersCollection.FindOne(ctx, bson.M{<span class="hljs-string">"name"</span>: <span class="hljs-string">"John Doe"</span>}).Decode(&userToUpdate)
        <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
            log.Println(<span class="hljs-string">"No user found to update"</span>)
        } <span class="hljs-keyword">else</span> {
            update := bson.M{
                <span class="hljs-string">"$set"</span>: bson.M{
                    <span class="hljs-string">"name"</span>: <span class="hljs-string">"Jane Doe"</span>,
                    <span class="hljs-string">"age"</span>:  <span class="hljs-number">25</span>,
                },
            }
            result, err := usersCollection.UpdateOne(
                ctx,
                bson.M{<span class="hljs-string">"_id"</span>: userToUpdate.ID},
                update,
            )
            <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
                log.Fatal(err)
            }
            log.Printf(<span class="hljs-string">"Updated %v document(s)n"</span>, result.ModifiedCount)
        }
    }
    

    In the code above, you first search for a user named “John Doe” using the FindOne method. If a match is found, you use the UpdateOne method to update their name and age. The $set operator ensures that only the specified fields are updated, leaving the rest of the document unchanged.

    Execute the code by running:

    go run main.go
    

    You should see output in your terminal indicating how many documents were updated.

    Command line interface showing "go run main.go" and the output "2025/06/30 21:34:36 Updated 1 document(s)".

    Delete documents in MongoDB

    To remove documents from a collection, you can use the DeleteOne method. Update your main.go file with the following code:

    <span class="hljs-keyword">package</span> main
    
    <span class="hljs-keyword">import</span> (
        <span class="hljs-string">"context"</span>
        <span class="hljs-string">"log"</span>
        <span class="hljs-string">"time"</span>
    
        <span class="hljs-string">"go.mongodb.org/mongo-driver/bson"</span>
        <span class="hljs-string">"go.mongodb.org/mongo-driver/bson/primitive"</span>
        <span class="hljs-string">"go.mongodb.org/mongo-driver/mongo"</span>
        <span class="hljs-string">"go.mongodb.org/mongo-driver/mongo/options"</span>
    )
    
    <span class="hljs-keyword">type</span> User <span class="hljs-keyword">struct</span> {
        ID   primitive.ObjectID <span class="hljs-string">`bson:"_id,omitempty"`</span>
        Name <span class="hljs-keyword">string</span>             <span class="hljs-string">`bson:"name"`</span>
        Age  <span class="hljs-keyword">int</span>                <span class="hljs-string">`bson:"age"`</span>
    }
    
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
        clientOptions := options.Client().ApplyURI(<span class="hljs-string">"mongodb://localhost:27017"</span>)
        ctx, cancel := context.WithTimeout(context.Background(), <span class="hljs-number">10</span>*time.Second)
        <span class="hljs-keyword">defer</span> cancel()
    
        client, err := mongo.Connect(ctx, clientOptions)
        <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
            log.Fatal(err)
        }
        <span class="hljs-keyword">defer</span> client.Disconnect(ctx)
    
        db := client.Database(<span class="hljs-string">"test_db"</span>)
        usersCollection := db.Collection(<span class="hljs-string">"users"</span>)
    
        result, err := usersCollection.DeleteOne(ctx, bson.M{<span class="hljs-string">"name"</span>: <span class="hljs-string">"Jane Doe"</span>})
        <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
            log.Fatal(err)
        }
        log.Printf(<span class="hljs-string">"Deleted %v document(s)n"</span>, result.DeletedCount)
    }
    

    In the code above, you use the DeleteOne method to remove the first document that matches the filter { "name": "Jane Doe" }.

    You should see the result below in your terminal.

    A command line terminal showing the execution of "go run main.go" and outputting "2025/06/30 21:36:05 Deleted 1 document(s)".

    How to Build a Blog App with go-mongodb-driver and Gin

    Now that you understand how to perform basic CRUD operations with MongoDB in Go, you’re ready to build a more complete application.

    Start by creating a new directory for your project and initializing it as a Go module. Navigate to your chosen directory and run:

    mkdir go-blog
    <span class="hljs-built_in">cd</span> go-blog
    go mod init blog
    

    Next, install the required dependencies:

    go get github.com/gin-gonic/gin
    go get go.mongodb.org/mongo-driver/mongo
    go get go.mongodb.org/mongo-driver/bson
    

    Your project will have the following structure:

    go-blog/  
    ├── main.go  
    ├── handlers/  
    │   └── main.go  
    └── templates/  
        ├── index.html  
        ├── post.html  
        ├── create.html  
        └── edit.html
    

    Initialize the Gin application

    To initialize a new Gin application, create a new main.go file and add the below code snippet to it:

    <span class="hljs-keyword">package</span> main
    
    <span class="hljs-keyword">import</span> (
        <span class="hljs-string">"context"</span>
        <span class="hljs-string">"log"</span>
        <span class="hljs-string">"time"</span>
    
        <span class="hljs-string">"blog/handlers"</span>
    
        <span class="hljs-string">"github.com/gin-gonic/gin"</span>
        <span class="hljs-string">"go.mongodb.org/mongo-driver/mongo"</span>
        <span class="hljs-string">"go.mongodb.org/mongo-driver/mongo/options"</span>
    )
    
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
        ctx, cancel := context.WithTimeout(context.Background(), <span class="hljs-number">10</span>*time.Second)
        <span class="hljs-keyword">defer</span> cancel()
    
        clientOptions := options.Client().ApplyURI(<span class="hljs-string">"mongodb://localhost:27017"</span>)
        client, err := mongo.Connect(ctx, clientOptions)
        <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
            log.Fatal(err)
        }
        <span class="hljs-keyword">defer</span> client.Disconnect(ctx)
    
        err = client.Ping(ctx, <span class="hljs-literal">nil</span>)
        <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
            log.Fatal(err)
        }
        log.Println(<span class="hljs-string">"Connected to MongoDB!"</span>)
    
        db := client.Database(<span class="hljs-string">"blog_db"</span>)
        h := handlers.NewHandler(db)
    
        router := gin.Default()
        router.LoadHTMLGlob(<span class="hljs-string">"templates/*"</span>)
    
        router.GET(<span class="hljs-string">"/"</span>, h.HomePage)
        router.GET(<span class="hljs-string">"/post/:id"</span>, h.ViewPost)
        router.GET(<span class="hljs-string">"/create"</span>, h.CreatePost)
        router.GET(<span class="hljs-string">"/edit/:id"</span>, h.EditPost)
        router.POST(<span class="hljs-string">"/save"</span>, h.SavePost)
        router.GET(<span class="hljs-string">"/delete/:id"</span>, h.DeletePost)
    
        log.Println(<span class="hljs-string">"Server starting on :8080..."</span>)
        router.Run(<span class="hljs-string">":8080"</span>)
    }
    

    The code above sets up the MongoDB connection, initializes the Gin router, and registers your routes.

    Create the HTML templates

    Now, create the HTML templates for displaying the blog UI.

    First, create a templates directory and add the following files:

    index.html:

    <span class="hljs-meta"><!DOCTYPE <span class="hljs-meta-keyword">html</span>></span>  
    <span class="hljs-tag"><<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>></span>  
    <span class="hljs-tag"><<span class="hljs-name">head</span>></span>  
        <span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>></span>  
        <span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>></span>  
        <span class="hljs-tag"><<span class="hljs-name">title</span>></span>Go Blog with MongoDB<span class="hljs-tag"></<span class="hljs-name">title</span>></span>  
        <span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.tailwindcss.com"</span>></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>  
    <span class="hljs-tag"></<span class="hljs-name">head</span>></span>  
    <span class="hljs-tag"><<span class="hljs-name">body</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"bg-gray-100 min-h-screen"</span>></span>  
        <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container mx-auto px-4 py-8"</span>></span>  
            <span class="hljs-tag"><<span class="hljs-name">header</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"mb-8"</span>></span>  
                <span class="hljs-tag"><<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-3xl font-bold text-center text-blue-600"</span>></span>Go Blog with MongoDB<span class="hljs-tag"></<span class="hljs-name">h1</span>></span>  
                <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex justify-center mt-4"</span>></span>  
                    <span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/create"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded"</span>></span>Create New Post<span class="hljs-tag"></<span class="hljs-name">a</span>></span>  
                <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
            <span class="hljs-tag"></<span class="hljs-name">header</span>></span>
    
            <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"</span>></span>  
                {{range .}}  
                <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"bg-white rounded-lg shadow-md overflow-hidden hover:shadow-lg transition-shadow duration-300"</span>></span>  
                    <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"p-6"</span>></span>  
                        <span class="hljs-tag"><<span class="hljs-name">h2</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-xl font-semibold mb-2 text-gray-800"</span>></span>{{.Title}}<span class="hljs-tag"></<span class="hljs-name">h2</span>></span>  
                        <span class="hljs-tag"><<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-gray-600 mb-4 line-clamp-3"</span>></span>  
                            {{if gt (len .Content) 150}}  
                                {{slice .Content 0 150}}...  
                            {{else}}  
                                {{.Content}}  
                            {{end}}  
                        <span class="hljs-tag"></<span class="hljs-name">p</span>></span>  
                        <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex justify-between items-center text-sm text-gray-500"</span>></span>  
                            <span class="hljs-tag"><<span class="hljs-name">span</span>></span>{{.CreatedAt.Format "Jan 02, 2006"}}<span class="hljs-tag"></<span class="hljs-name">span</span>></span>  
                            <span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/post/{{.ID.Hex}}"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-blue-500 hover:text-blue-700"</span>></span>Read More<span class="hljs-tag"></<span class="hljs-name">a</span>></span>  
                        <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
                    <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
                    <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex border-t border-gray-200"</span>></span>  
                        <span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/edit/{{.ID.Hex}}"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"w-1/2 py-2 text-center text-sm text-gray-600 hover:bg-gray-100 border-r border-gray-200"</span>></span>Edit<span class="hljs-tag"></<span class="hljs-name">a</span>></span>  
                        <span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/delete/{{.ID.Hex}}"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"w-1/2 py-2 text-center text-sm text-red-600 hover:bg-gray-100"</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"return confirm('Are you sure you want to delete this post?')"</span>></span>Delete<span class="hljs-tag"></<span class="hljs-name">a</span>></span>  
                    <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
                <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
                {{else}}  
                <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-span-3 text-center py-12"</span>></span>  
                    <span class="hljs-tag"><<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-gray-600 text-lg"</span>></span>No posts yet. <span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/create"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-blue-500 hover:underline"</span>></span>Create one<span class="hljs-tag"></<span class="hljs-name">a</span>></span>!<span class="hljs-tag"></<span class="hljs-name">p</span>></span>  
                <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
                {{end}}  
            <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
        <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
    <span class="hljs-tag"></<span class="hljs-name">body</span>></span>  
    <span class="hljs-tag"></<span class="hljs-name">html</span>></span>
    

    This template lists all blog posts and includes buttons to create, edit, or delete posts.

    post.html:

    <span class="hljs-meta"><!DOCTYPE <span class="hljs-meta-keyword">html</span>></span>  
    <span class="hljs-tag"><<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>></span>  
    <span class="hljs-tag"><<span class="hljs-name">head</span>></span>  
        <span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>></span>  
        <span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>></span>  
        <span class="hljs-tag"><<span class="hljs-name">title</span>></span>{{.Title}} | Go Blog with MongoDB<span class="hljs-tag"></<span class="hljs-name">title</span>></span>  
        <span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.tailwindcss.com"</span>></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>  
    <span class="hljs-tag"></<span class="hljs-name">head</span>></span>  
    <span class="hljs-tag"><<span class="hljs-name">body</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"bg-gray-100 min-h-screen"</span>></span>  
        <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container mx-auto px-4 py-8"</span>></span>  
            <span class="hljs-tag"><<span class="hljs-name">header</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"mb-8"</span>></span>  
                <span class="hljs-tag"><<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-3xl font-bold text-center text-blue-600"</span>></span>Go Blog with MongoDB<span class="hljs-tag"></<span class="hljs-name">h1</span>></span>  
                <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex justify-center mt-4"</span>></span>  
                    <span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded"</span>></span>Back to Home<span class="hljs-tag"></<span class="hljs-name">a</span>></span>  
                <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
            <span class="hljs-tag"></<span class="hljs-name">header</span>></span>
    
            <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"max-w-3xl mx-auto bg-white rounded-lg shadow-md overflow-hidden"</span>></span>  
                <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"p-6"</span>></span>  
                    <span class="hljs-tag"><<span class="hljs-name">h2</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-2xl font-bold mb-4 text-gray-800"</span>></span>{{.Title}}<span class="hljs-tag"></<span class="hljs-name">h2</span>></span>  
    
                    <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex items-center text-sm text-gray-500 mb-6"</span>></span>  
                        <span class="hljs-tag"><<span class="hljs-name">span</span>></span>Posted: {{.CreatedAt.Format "Jan 02, 2006"}}<span class="hljs-tag"></<span class="hljs-name">span</span>></span>  
                        {{if ne .CreatedAt .UpdatedAt}}  
                        <span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"mx-2"</span>></span>•<span class="hljs-tag"></<span class="hljs-name">span</span>></span>  
                        <span class="hljs-tag"><<span class="hljs-name">span</span>></span>Updated: {{.UpdatedAt.Format "Jan 02, 2006"}}<span class="hljs-tag"></<span class="hljs-name">span</span>></span>  
                        {{end}}  
                    <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
    
                    <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"prose max-w-none"</span>></span>  
                        <span class="hljs-tag"><<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-gray-700 whitespace-pre-line"</span>></span>{{.Content}}<span class="hljs-tag"></<span class="hljs-name">p</span>></span>  
                    <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
                <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
    
                <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex border-t border-gray-200"</span>></span>  
                    <span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/edit/{{.ID.Hex}}"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"w-1/2 py-3 text-center text-blue-600 hover:bg-gray-100 border-r border-gray-200"</span>></span>Edit Post<span class="hljs-tag"></<span class="hljs-name">a</span>></span>  
                    <span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/delete/{{.ID.Hex}}"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"w-1/2 py-3 text-center text-red-600 hover:bg-gray-100"</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"return confirm('Are you sure you want to delete this post?')"</span>></span>Delete Post<span class="hljs-tag"></<span class="hljs-name">a</span>></span>  
                <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
            <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
        <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
    <span class="hljs-tag"></<span class="hljs-name">body</span>></span>  
    <span class="hljs-tag"></<span class="hljs-name">html</span>></span>
    

    This template displays a single post.

    create.html:

    <span class="hljs-meta"><!DOCTYPE <span class="hljs-meta-keyword">html</span>></span>  
    <span class="hljs-tag"><<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>></span>  
    <span class="hljs-tag"><<span class="hljs-name">head</span>></span>  
        <span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>></span>  
        <span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>></span>  
        <span class="hljs-tag"><<span class="hljs-name">title</span>></span>Create New Post | Go Blog with MongoDB<span class="hljs-tag"></<span class="hljs-name">title</span>></span>  
        <span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.tailwindcss.com"</span>></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>  
    <span class="hljs-tag"></<span class="hljs-name">head</span>></span>  
    <span class="hljs-tag"><<span class="hljs-name">body</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"bg-gray-100 min-h-screen"</span>></span>  
        <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container mx-auto px-4 py-8"</span>></span>  
            <span class="hljs-tag"><<span class="hljs-name">header</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"mb-8"</span>></span>  
                <span class="hljs-tag"><<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-3xl font-bold text-center text-blue-600"</span>></span>Go Blog with MongoDB<span class="hljs-tag"></<span class="hljs-name">h1</span>></span>  
                <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex justify-center mt-4"</span>></span>  
                    <span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded"</span>></span>Back to Home<span class="hljs-tag"></<span class="hljs-name">a</span>></span>  
                <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
            <span class="hljs-tag"></<span class="hljs-name">header</span>></span>
    
            <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"max-w-2xl mx-auto bg-white rounded-lg shadow-md overflow-hidden"</span>></span>  
                <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"p-6"</span>></span>  
                    <span class="hljs-tag"><<span class="hljs-name">h2</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-2xl font-bold mb-6 text-gray-800"</span>></span>Create New Post<span class="hljs-tag"></<span class="hljs-name">h2</span>></span>  
    
                    <span class="hljs-tag"><<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"/save"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"POST"</span>></span>  
                        <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"mb-4"</span>></span>  
                            <span class="hljs-tag"><<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"title"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"block text-gray-700 font-medium mb-2"</span>></span>Title<span class="hljs-tag"></<span class="hljs-name">label</span>></span>  
                            <span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"title"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"title"</span> <span class="hljs-attr">required</span>  
                                <span class="hljs-attr">class</span>=<span class="hljs-string">"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"</span>></span>  
                        <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
    
                        <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"mb-6"</span>></span>  
                            <span class="hljs-tag"><<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"content"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"block text-gray-700 font-medium mb-2"</span>></span>Content<span class="hljs-tag"></<span class="hljs-name">label</span>></span>  
                            <span class="hljs-tag"><<span class="hljs-name">textarea</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"content"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"content"</span> <span class="hljs-attr">rows</span>=<span class="hljs-string">"10"</span> <span class="hljs-attr">required</span>  
                                <span class="hljs-attr">class</span>=<span class="hljs-string">"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"</span>></span><span class="hljs-tag"></<span class="hljs-name">textarea</span>></span>  
                        <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
    
                        <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex justify-end"</span>></span>  
                            <span class="hljs-tag"><<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"bg-blue-500 hover:bg-blue-600 text-white px-6 py-2 rounded-md"</span>></span>  
                                Save Post  
                            <span class="hljs-tag"></<span class="hljs-name">button</span>></span>  
                        <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
                    <span class="hljs-tag"></<span class="hljs-name">form</span>></span>  
                <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
            <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
        <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
    <span class="hljs-tag"></<span class="hljs-name">body</span>></span>  
    <span class="hljs-tag"></<span class="hljs-name">html</span>></span>
    

    This template allows you to create a new post.

    edit.html:

    <span class="hljs-meta"><!DOCTYPE <span class="hljs-meta-keyword">html</span>></span>  
    <span class="hljs-tag"><<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>></span>  
    <span class="hljs-tag"><<span class="hljs-name">head</span>></span>  
        <span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>></span>  
        <span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>></span>  
        <span class="hljs-tag"><<span class="hljs-name">title</span>></span>Edit Post | Go Blog with MongoDB<span class="hljs-tag"></<span class="hljs-name">title</span>></span>  
        <span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.tailwindcss.com"</span>></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>  
    <span class="hljs-tag"></<span class="hljs-name">head</span>></span>  
    <span class="hljs-tag"><<span class="hljs-name">body</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"bg-gray-100 min-h-screen"</span>></span>  
        <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container mx-auto px-4 py-8"</span>></span>  
            <span class="hljs-tag"><<span class="hljs-name">header</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"mb-8"</span>></span>  
                <span class="hljs-tag"><<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-3xl font-bold text-center text-blue-600"</span>></span>Go Blog with MongoDB<span class="hljs-tag"></<span class="hljs-name">h1</span>></span>  
                <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex justify-center mt-4"</span>></span>  
                    <span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded"</span>></span>Back to Home<span class="hljs-tag"></<span class="hljs-name">a</span>></span>  
                <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
            <span class="hljs-tag"></<span class="hljs-name">header</span>></span>
    
            <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"max-w-2xl mx-auto bg-white rounded-lg shadow-md overflow-hidden"</span>></span>  
                <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"p-6"</span>></span>  
                    <span class="hljs-tag"><<span class="hljs-name">h2</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-2xl font-bold mb-6 text-gray-800"</span>></span>Edit Post<span class="hljs-tag"></<span class="hljs-name">h2</span>></span>  
    
                    <span class="hljs-tag"><<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"/save"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"POST"</span>></span>  
                        <span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"hidden"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"id"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"{{.ID.Hex}}"</span>></span>  
    
                        <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"mb-4"</span>></span>  
                            <span class="hljs-tag"><<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"title"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"block text-gray-700 font-medium mb-2"</span>></span>Title<span class="hljs-tag"></<span class="hljs-name">label</span>></span>  
                            <span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"title"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"title"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"{{.Title}}"</span> <span class="hljs-attr">required</span>  
                                <span class="hljs-attr">class</span>=<span class="hljs-string">"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"</span>></span>  
                        <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
    
                        <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"mb-6"</span>></span>  
                            <span class="hljs-tag"><<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"content"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"block text-gray-700 font-medium mb-2"</span>></span>Content<span class="hljs-tag"></<span class="hljs-name">label</span>></span>  
                            <span class="hljs-tag"><<span class="hljs-name">textarea</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"content"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"content"</span> <span class="hljs-attr">rows</span>=<span class="hljs-string">"10"</span> <span class="hljs-attr">required</span>  
                                <span class="hljs-attr">class</span>=<span class="hljs-string">"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"</span>></span>{{.Content}}<span class="hljs-tag"></<span class="hljs-name">textarea</span>></span>  
                        <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
    
                        <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex justify-between"</span>></span>  
                            <span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/post/{{.ID.Hex}}"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-gray-600 hover:text-gray-800"</span>></span>Cancel<span class="hljs-tag"></<span class="hljs-name">a</span>></span>  
                            <span class="hljs-tag"><<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"bg-blue-500 hover:bg-blue-600 text-white px-6 py-2 rounded-md"</span>></span>  
                                Update Post  
                            <span class="hljs-tag"></<span class="hljs-name">button</span>></span>  
                        <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
                    <span class="hljs-tag"></<span class="hljs-name">form</span>></span>  
                <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
            <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
        <span class="hljs-tag"></<span class="hljs-name">div</span>></span>  
    <span class="hljs-tag"></<span class="hljs-name">body</span>></span>  
    <span class="hljs-tag"></<span class="hljs-name">html</span>></span>
    

    This template is used to edit a post.

    Create the handlers

    Next, set up the handlers to connect with MongoDB and render the templates. Create a new folder called handlers in your project’s root directory, then add a main.go file inside it and insert the following code snippet:

    <span class="hljs-keyword">package</span> handlers
    
    <span class="hljs-keyword">import</span> (
        <span class="hljs-string">"context"</span>
        <span class="hljs-string">"log"</span>
        <span class="hljs-string">"net/http"</span>
        <span class="hljs-string">"time"</span>
    
        <span class="hljs-string">"github.com/gin-gonic/gin"</span>
        <span class="hljs-string">"go.mongodb.org/mongo-driver/bson"</span>
        <span class="hljs-string">"go.mongodb.org/mongo-driver/bson/primitive"</span>
        <span class="hljs-string">"go.mongodb.org/mongo-driver/mongo"</span>
    )
    
    <span class="hljs-keyword">type</span> Post <span class="hljs-keyword">struct</span> {
        ID        primitive.ObjectID <span class="hljs-string">`bson:"_id,omitempty" json:"id"`</span>
        Title     <span class="hljs-keyword">string</span>             <span class="hljs-string">`bson:"title" json:"title"`</span>
        Content   <span class="hljs-keyword">string</span>             <span class="hljs-string">`bson:"content" json:"content"`</span>
        CreatedAt time.Time          <span class="hljs-string">`bson:"created_at" json:"created_at"`</span>
        UpdatedAt time.Time          <span class="hljs-string">`bson:"updated_at" json:"updated_at"`</span>
    }
    
    <span class="hljs-keyword">type</span> Handler <span class="hljs-keyword">struct</span> {
        db         *mongo.Database
        collection *mongo.Collection
    }
    
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">NewHandler</span><span class="hljs-params">(db *mongo.Database)</span> *<span class="hljs-title">Handler</span></span> {
        <span class="hljs-keyword">return</span> &Handler{
            db:         db,
            collection: db.Collection(<span class="hljs-string">"posts"</span>),
        }
    }
    
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(h *Handler)</span> <span class="hljs-title">HomePage</span><span class="hljs-params">(c *gin.Context)</span></span> {
        ctx, cancel := context.WithTimeout(context.Background(), <span class="hljs-number">5</span>*time.Second)
        <span class="hljs-keyword">defer</span> cancel()
    
        cursor, err := h.collection.Find(ctx, bson.M{})
        <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
            c.JSON(http.StatusInternalServerError, gin.H{<span class="hljs-string">"error"</span>: err.Error()})
            <span class="hljs-keyword">return</span>
        }
        <span class="hljs-keyword">defer</span> cursor.Close(ctx)
    
        <span class="hljs-keyword">var</span> posts []Post
        <span class="hljs-keyword">if</span> err = cursor.All(ctx, &posts); err != <span class="hljs-literal">nil</span> {
            c.JSON(http.StatusInternalServerError, gin.H{<span class="hljs-string">"error"</span>: err.Error()})
            <span class="hljs-keyword">return</span>
        }
    
        c.HTML(http.StatusOK, <span class="hljs-string">"index.html"</span>, posts)
    }
    
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(h *Handler)</span> <span class="hljs-title">ViewPost</span><span class="hljs-params">(c *gin.Context)</span></span> {
        id := c.Param(<span class="hljs-string">"id"</span>)
        objID, err := primitive.ObjectIDFromHex(id)
        <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
            c.JSON(http.StatusBadRequest, gin.H{<span class="hljs-string">"error"</span>: <span class="hljs-string">"Invalid post ID"</span>})
            <span class="hljs-keyword">return</span>
        }
    
        ctx, cancel := context.WithTimeout(context.Background(), <span class="hljs-number">5</span>*time.Second)
        <span class="hljs-keyword">defer</span> cancel()
    
        <span class="hljs-keyword">var</span> post Post
        err = h.collection.FindOne(ctx, bson.M{<span class="hljs-string">"_id"</span>: objID}).Decode(&post)
        <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
            c.JSON(http.StatusNotFound, gin.H{<span class="hljs-string">"error"</span>: <span class="hljs-string">"Post not found"</span>})
            <span class="hljs-keyword">return</span>
        }
    
        c.HTML(http.StatusOK, <span class="hljs-string">"post.html"</span>, post)
    }
    
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(h *Handler)</span> <span class="hljs-title">CreatePost</span><span class="hljs-params">(c *gin.Context)</span></span> {
        c.HTML(http.StatusOK, <span class="hljs-string">"create.html"</span>, <span class="hljs-literal">nil</span>)
    }
    
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(h *Handler)</span> <span class="hljs-title">EditPost</span><span class="hljs-params">(c *gin.Context)</span></span> {
        id := c.Param(<span class="hljs-string">"id"</span>)
        objID, err := primitive.ObjectIDFromHex(id)
        <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
            c.JSON(http.StatusBadRequest, gin.H{<span class="hljs-string">"error"</span>: <span class="hljs-string">"Invalid post ID"</span>})
            <span class="hljs-keyword">return</span>
        }
    
        ctx, cancel := context.WithTimeout(context.Background(), <span class="hljs-number">5</span>*time.Second)
        <span class="hljs-keyword">defer</span> cancel()
    
        <span class="hljs-keyword">var</span> post Post
        err = h.collection.FindOne(ctx, bson.M{<span class="hljs-string">"_id"</span>: objID}).Decode(&post)
        <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
            c.JSON(http.StatusNotFound, gin.H{<span class="hljs-string">"error"</span>: <span class="hljs-string">"Post not found"</span>})
            <span class="hljs-keyword">return</span>
        }
    
        c.HTML(http.StatusOK, <span class="hljs-string">"edit.html"</span>, post)
    }
    
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(h *Handler)</span> <span class="hljs-title">SavePost</span><span class="hljs-params">(c *gin.Context)</span></span> {
        ctx, cancel := context.WithTimeout(context.Background(), <span class="hljs-number">5</span>*time.Second)
        <span class="hljs-keyword">defer</span> cancel()
    
        id := c.PostForm(<span class="hljs-string">"id"</span>)
        title := c.PostForm(<span class="hljs-string">"title"</span>)
        content := c.PostForm(<span class="hljs-string">"content"</span>)
    
        now := time.Now()
    
        <span class="hljs-keyword">if</span> id == <span class="hljs-string">""</span> {
            post := Post{
                Title:     title,
                Content:   content,
                CreatedAt: now,
                UpdatedAt: now,
            }
    
            result, err := h.collection.InsertOne(ctx, post)
            <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
                c.JSON(http.StatusInternalServerError, gin.H{<span class="hljs-string">"error"</span>: err.Error()})
                <span class="hljs-keyword">return</span>
            }
    
            log.Printf(<span class="hljs-string">"Created post with ID: %vn"</span>, result.InsertedID)
        } <span class="hljs-keyword">else</span> {
            objID, err := primitive.ObjectIDFromHex(id)
            <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
                c.JSON(http.StatusBadRequest, gin.H{<span class="hljs-string">"error"</span>: <span class="hljs-string">"Invalid post ID"</span>})
                <span class="hljs-keyword">return</span>
            }
    
            update := bson.M{
                <span class="hljs-string">"$set"</span>: bson.M{
                    <span class="hljs-string">"title"</span>:      title,
                    <span class="hljs-string">"content"</span>:    content,
                    <span class="hljs-string">"updated_at"</span>: now,
                },
            }
    
            result, err := h.collection.UpdateOne(ctx, bson.M{<span class="hljs-string">"_id"</span>: objID}, update)
            <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
                c.JSON(http.StatusInternalServerError, gin.H{<span class="hljs-string">"error"</span>: err.Error()})
                <span class="hljs-keyword">return</span>
            }
    
            log.Printf(<span class="hljs-string">"Updated post with ID: %s (Modified %d documents)n"</span>, id, result.ModifiedCount)
        }
    
        c.Redirect(http.StatusSeeOther, <span class="hljs-string">"/"</span>)
    }
    
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(h *Handler)</span> <span class="hljs-title">DeletePost</span><span class="hljs-params">(c *gin.Context)</span></span> {
        id := c.Param(<span class="hljs-string">"id"</span>)
        objID, err := primitive.ObjectIDFromHex(id)
        <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
            c.JSON(http.StatusBadRequest, gin.H{<span class="hljs-string">"error"</span>: <span class="hljs-string">"Invalid post ID"</span>})
            <span class="hljs-keyword">return</span>
        }
    
        ctx, cancel := context.WithTimeout(context.Background(), <span class="hljs-number">5</span>*time.Second)
        <span class="hljs-keyword">defer</span> cancel()
    
        result, err := h.collection.DeleteOne(ctx, bson.M{<span class="hljs-string">"_id"</span>: objID})
        <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
            c.JSON(http.StatusInternalServerError, gin.H{<span class="hljs-string">"error"</span>: err.Error()})
            <span class="hljs-keyword">return</span>
        }
    
        log.Printf(<span class="hljs-string">"Deleted %d document(s) with ID: %sn"</span>, result.DeletedCount, id)
        c.Redirect(http.StatusSeeOther, <span class="hljs-string">"/"</span>)
    }
    

    The code above contains all the logic for managing blog posts. Here’s what each component does:

    • Post struct: Defines the structure of a blog post document with fields for ID, title, content, and timestamps. The bson tags specify how fields are stored in MongoDB, while json tags handle JSON serialization.

    • Handler struct: Contains a reference to the MongoDB database and the posts collection, providing a centralized way to access the database throughout your handlers.

    • NewHandler function: Creates and initializes a new handler instance with the database connection and sets up the posts collection reference.

    • HomePage: Retrieves all blog posts from the database using Find() with an empty filter and renders them using the index.html template.

    • ViewPost: Fetches a single post by its ObjectID using FindOne() and displays it with the post.html template.

    • CreatePost & EditPost: Render the respective forms for creating new posts or editing existing ones.

    • SavePost: Handles both creating new posts and updating existing ones. It checks if an ID is provided. If not, it creates a new post using InsertOne(). Otherwise, it updates the existing post using UpdateOne() with MongoDB’s $set operator.

    • DeletePost: Removes a post from the database using DeleteOne() and redirects back to the homepage.

    Run the application

    With everything set up, you can now launch your blog. Open your terminal and run:

    go mod tidy && go run main.go
    

    Then, visit http://localhost:8080 in your browser to see your blog in action.

    Blog management interface with a header "Go Blog with MongoDB" and a "Create New Post" button. Two blog post entries are shown with options to edit or delete.

    That’s How to Use MongoDB with Go

    In this tutorial, you built a simple blog application using Go and MongoDB. You learned how to connect to a MongoDB database using the official Go driver, perform CRUD operations, and render your results with the Gin web framework.

    MongoDB’s flexible, document-based structure makes it a great fit for applications where data models need to evolve over time. It allows you to iterate quickly and adapt as your app grows.

    As you expand this project, consider adding features such as user authentication, tagging or categorization, comments, pagination, or search functionality to enhance the user experience.

    Cheers to building more with Go and MongoDB!

    Source: freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More 

    Facebook Twitter Reddit Email Copy Link
    Previous ArticleWhat is Unicode —The Secret Language Behind Every Text You See
    Next Article How to Upload Large Objects to S3 with AWS CLI Multipart Upload

    Related Posts

    Repurposing Protein Folding Models for Generation with Latent Diffusion
    Artificial Intelligence

    Repurposing Protein Folding Models for Generation with Latent Diffusion

    September 14, 2025
    Artificial Intelligence

    Scaling Up Reinforcement Learning for Traffic Smoothing: A 100-AV Highway Deployment

    September 14, 2025
    Leave A Reply Cancel Reply

    For security, use of Google's reCAPTCHA service is required which is subject to the Google Privacy Policy and Terms of Use.

    Continue Reading

    CVE-2025-2409 – ASPECT File Corruption Vulnerability (Write-What-Where)

    Common Vulnerabilities and Exposures (CVEs)

    Why no small business is too small for hackers – and 8 security best practices for SMBs

    News & Updates

    Customize Logseq With Themes and Plugins

    Linux

    CVE-2025-46814 – FastAPI Guard HTTP Header Injection Vulnerability

    Common Vulnerabilities and Exposures (CVEs)

    Highlights

    Advanced Laravel: 14 Topics and Links to Learn Them

    June 17, 2025

    Quite often I get a question from junior developers like “how to get better at…

    CVE-2025-5599 – PHPGurukul Student Result Management System SQL Injection Vulnerability

    June 4, 2025

    Android Trojan Crocodilus Now Active in 8 Countries, Targeting Banks and Crypto Wallets

    June 3, 2025

    Halo Studios Greenlights “Spartan Survivors,” A Vampire Survivors–Style Fan Game

    July 8, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.