Skip to main content

Gin Hello World

Welcome to the world of Gin, a fast and lightweight web framework for Go! In this tutorial, we'll create our first Gin application - a simple "Hello World" server that responds to HTTP requests. By the end of this guide, you'll understand the basic structure of a Gin application and be ready to build more complex web services.

What is Gin?

Gin is a high-performance HTTP web framework written in Go (Golang). It features a martini-like API but with much better performance - up to 40 times faster. If you need a lightweight but powerful web framework, Gin is an excellent choice for building web applications and microservices.

Prerequisites

Before we begin, make sure you have:

  1. Go installed on your machine (version 1.13 or higher recommended)
  2. Basic knowledge of Go programming language
  3. A code editor of your choice

Setting Up Your Environment

Let's start by creating a new directory for our project:

bash
mkdir gin-hello-world
cd gin-hello-world

Initialize a new Go module:

bash
go mod init gin-hello-world

Installing Gin

To use Gin in our project, we need to install it first:

bash
go get -u github.com/gin-gonic/gin

This command downloads and installs the latest version of Gin in your project.

Creating Your First Gin Application

Now, let's create a file named main.go with the following content:

go
package main

import (
"github.com/gin-gonic/gin"
"net/http"
)

func main() {
// Create a default gin router
router := gin.Default()

// Define a route for the root path
router.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "Hello World from Gin!",
})
})

// Start the server on port 8080
router.Run(":8080")
}

Understanding the Code

Let's break down the code step by step:

  1. Import Statements:

    go
    import (
    "github.com/gin-gonic/gin"
    "net/http"
    )

    Here we import the Gin package and the standard HTTP package.

  2. Creating a Router:

    go
    router := gin.Default()

    gin.Default() creates a router with default middleware: Logger and Recovery. The Logger middleware writes log of each request, while Recovery middleware recovers from any panics and returns a 500 error.

  3. Defining Routes:

    go
    router.GET("/", func(c *gin.Context) {
    c.JSON(http.StatusOK, gin.H{
    "message": "Hello World from Gin!",
    })
    })

    This code sets up a handler for GET requests to the root path (/). When a request comes in, Gin will execute the provided function, which sends a JSON response with an HTTP 200 OK status.

    • c is the Gin context, which carries request details, validates request data, and renders responses.
    • gin.H{} is a shortcut for map[string]interface{}
    • c.JSON() serializes the given struct as JSON and writes it to the response.
  4. Starting the Server:

    go
    router.Run(":8080")

    This starts the HTTP server on port 8080.

Running the Application

To run your application, use the following command:

bash
go run main.go

You should see output similar to:

[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] GET / --> main.main.func1 (3 handlers)
[GIN-debug] Listening and serving HTTP on :8080

Testing the Application

Open your web browser and navigate to http://localhost:8080/. You should see the JSON response:

json
{
"message": "Hello World from Gin!"
}

Alternatively, you can use curl in your terminal:

bash
curl http://localhost:8080/

Adding More Routes

Let's expand our application by adding a few more routes:

go
package main

import (
"github.com/gin-gonic/gin"
"net/http"
)

func main() {
// Create a default gin router
router := gin.Default()

// Define a route for the root path
router.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "Hello World from Gin!",
})
})

// Define a route with path parameters
router.GET("/user/:name", func(c *gin.Context) {
name := c.Param("name")
c.JSON(http.StatusOK, gin.H{
"message": "Hello " + name + "!",
})
})

// Define a route with query parameters
router.GET("/query", func(c *gin.Context) {
name := c.DefaultQuery("name", "Guest")
c.JSON(http.StatusOK, gin.H{
"message": "Hello " + name + "!",
})
})

// Start the server on port 8080
router.Run(":8080")
}

Now we've added two more endpoints:

  1. /user/:name - A path that accepts a name parameter as part of the URL.

    • Example: http://localhost:8080/user/John will respond with {"message":"Hello John!"}
  2. /query - A path that accepts a query parameter.

    • Example: http://localhost:8080/query?name=Jane will respond with {"message":"Hello Jane!"}
    • If no name is provided: http://localhost:8080/query will respond with {"message":"Hello Guest!"}

Serving HTML Content

Gin can also serve HTML content. Let's modify our application to serve an HTML page:

  1. First, create a templates directory and add an HTML file:
bash
mkdir templates
  1. Create a file templates/index.html with the following content:
html
<!DOCTYPE html>
<html>
<head>
<title>Gin Hello World</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 40px;
line-height: 1.6;
}
h1 {
color: #333;
}
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
border: 1px solid #ddd;
border-radius: 5px;
}
</style>
</head>
<body>
<div class="container">
<h1>Hello World from Gin!</h1>
<p>This is your first HTML page served by the Gin framework.</p>
</div>
</body>
</html>
  1. Now update the main.go file to load and serve the template:
go
package main

import (
"github.com/gin-gonic/gin"
"net/http"
)

func main() {
router := gin.Default()

// Load HTML templates
router.LoadHTMLGlob("templates/*")

// Serve static files
router.Static("/static", "./static")

// HTML route
router.GET("/html", func(c *gin.Context) {
c.HTML(http.StatusOK, "index.html", gin.H{
"title": "Gin Hello World",
})
})

// JSON API routes
router.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "Hello World from Gin!",
})
})

router.GET("/user/:name", func(c *gin.Context) {
name := c.Param("name")
c.JSON(http.StatusOK, gin.H{
"message": "Hello " + name + "!",
})
})

router.GET("/query", func(c *gin.Context) {
name := c.DefaultQuery("name", "Guest")
c.JSON(http.StatusOK, gin.H{
"message": "Hello " + name + "!",
})
})

router.Run(":8080")
}

Visit http://localhost:8080/html in your browser to see the HTML page.

Real-World Application Example

Let's create a simple API for a task management application. This example demonstrates more practical aspects of using Gin:

go
package main

import (
"github.com/gin-gonic/gin"
"net/http"
"strconv"
)

// Task represents a task in our application
type Task struct {
ID int `json:"id"`
Title string `json:"title"`
Completed bool `json:"completed"`
}

func main() {
router := gin.Default()

// In-memory tasks storage
tasks := []Task{
{ID: 1, Title: "Learn Gin Framework", Completed: false},
{ID: 2, Title: "Build a REST API", Completed: false},
}

// Route group for API
api := router.Group("/api")
{
// Get all tasks
api.GET("/tasks", func(c *gin.Context) {
c.JSON(http.StatusOK, tasks)
})

// Get a specific task
api.GET("/tasks/:id", func(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid ID"})
return
}

for _, task := range tasks {
if task.ID == id {
c.JSON(http.StatusOK, task)
return
}
}

c.JSON(http.StatusNotFound, gin.H{"error": "Task not found"})
})

// Create a new task
api.POST("/tasks", func(c *gin.Context) {
var newTask Task
if err := c.ShouldBindJSON(&newTask); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}

newTask.ID = len(tasks) + 1
tasks = append(tasks, newTask)

c.JSON(http.StatusCreated, newTask)
})
}

router.Run(":8080")
}

This mini-application provides:

  1. GET /api/tasks - Returns all tasks
  2. GET /api/tasks/:id - Returns a specific task by ID
  3. POST /api/tasks - Creates a new task

To test the POST endpoint, you can use curl:

bash
curl -X POST http://localhost:8080/api/tasks \
-H "Content-Type: application/json" \
-d '{"title": "Test the API", "completed": false}'

Summary

In this tutorial, you learned:

  1. How to set up a basic Gin application
  2. Creating routes for different HTTP methods
  3. Using path parameters and query parameters
  4. Serving HTML content with templates
  5. Building a simple RESTful API

Gin provides a robust framework for creating web applications in Go with its lightweight, fast, and feature-rich design. This Hello World example is just the beginning - Gin supports much more, including middleware, grouping routes, file uploads, and more advanced features.

Additional Resources

Here are some resources to continue learning about Gin:

  1. Official Gin Documentation
  2. Gin GitHub Repository
  3. Go Programming Language Documentation

Exercises

To strengthen your understanding, try these exercises:

  1. Add a DELETE endpoint to the task manager API to remove tasks by ID
  2. Add a PUT endpoint to update existing tasks
  3. Implement a simple middleware that logs the duration of each request
  4. Create a new route that filters tasks based on their completion status
  5. Add a basic authentication middleware that requires a username and password

Happy coding with Gin!



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)