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:
- Go installed on your machine (version 1.13 or higher recommended)
- Basic knowledge of Go programming language
- A code editor of your choice
Setting Up Your Environment
Let's start by creating a new directory for our project:
mkdir gin-hello-world
cd gin-hello-world
Initialize a new Go module:
go mod init gin-hello-world
Installing Gin
To use Gin in our project, we need to install it first:
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:
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:
-
Import Statements:
goimport (
"github.com/gin-gonic/gin"
"net/http"
)Here we import the Gin package and the standard HTTP package.
-
Creating a Router:
gorouter := 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. -
Defining Routes:
gorouter.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 formap[string]interface{}
c.JSON()
serializes the given struct as JSON and writes it to the response.
-
Starting the Server:
gorouter.Run(":8080")
This starts the HTTP server on port 8080.
Running the Application
To run your application, use the following command:
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:
{
"message": "Hello World from Gin!"
}
Alternatively, you can use curl in your terminal:
curl http://localhost:8080/
Adding More Routes
Let's expand our application by adding a few more routes:
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:
-
/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!"}
- Example:
-
/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!"}
- Example:
Serving HTML Content
Gin can also serve HTML content. Let's modify our application to serve an HTML page:
- First, create a
templates
directory and add an HTML file:
mkdir templates
- Create a file
templates/index.html
with the following content:
<!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>
- Now update the
main.go
file to load and serve the template:
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:
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:
- GET
/api/tasks
- Returns all tasks - GET
/api/tasks/:id
- Returns a specific task by ID - POST
/api/tasks
- Creates a new task
To test the POST endpoint, you can use curl:
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:
- How to set up a basic Gin application
- Creating routes for different HTTP methods
- Using path parameters and query parameters
- Serving HTML content with templates
- 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:
Exercises
To strengthen your understanding, try these exercises:
- Add a DELETE endpoint to the task manager API to remove tasks by ID
- Add a PUT endpoint to update existing tasks
- Implement a simple middleware that logs the duration of each request
- Create a new route that filters tasks based on their completion status
- 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! :)