Have you ever wondered how Bit.ly or TinyURL work? Today, we're building our URL shortener in Golang!
By the end of this tutorial, you'll have a fully working URL shortener that generates short links and redirects users. Let’s get started!
Before we dive into coding, let's understand how a URL shortener works:
- The user enters a long URL
- We generate a short code
- Save it in a memory or database
- When someone visits the short link, we redirect them
Step 1: Project Setup
First, create a new project and initialize Go modules.
mkdir go-url-shortener && cd go-url-shortener
go mod init github.com/yourusername/go-url-shortener
go get github.com/gin-gonic/gin
Now, open main.go
and set up a simple Gin server.
package main
import (
"crypto/rand"
"encoding/base64"
"github.com/gin-gonic/gin"
"net/http"
)
// Map to store short URLs -> original URLs
var urlStore = make(map[string]string)
func main() {
r := gin.Default()
r.POST("/shorten", shortenURL)
r.GET("/:short", redirectURL)
r.Run(":8080") // Run on port 8080
}
This creates a basic Gin server. Now let’s add URL shortening!
Step 2: Generate Short URLs
Now, we need a function to generate a short random URL.
func generateShortURL() string {
b := make([]byte, 6)
rand.Read(b)
return base64.URLEncoding.EncodeToString(b)[:6]
}
Step 3: Shorten URL API
Next, let’s create the /shorten endpoint that takes a long URL and returns a short one.
func shortenURL(c *gin.Context) {
var req struct {
OriginalURL string `json:"original_url"`
}
if err := c.BindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
return
}
shortCode := generateShortURL()
urlStore[shortCode] = req.OriginalURL
c.JSON(http.StatusOK, gin.H{
"short_url": "http://localhost:8080/" + shortCode,
})
}
This stores the original URL in a map and returns a short URL.
Now, let’s handle redirection!
Step 4: Redirect Short URLs
We need an endpoint that looks up the short URL and redirects users.
func redirectURL(c *gin.Context) {
shortCode := c.Param("short")
originalURL, exists := urlStore[shortCode]
if !exists {
c.JSON(http.StatusNotFound, gin.H{"error": "URL not found"})
return
}
c.Redirect(http.StatusFound, originalURL)
}
Step 5: Testing the API
Let’s test this API using cURL!
Run the application by typing.
go run .
Shorten a URL
Request:
curl -X POST http://localhost:8080/shorten -H "Content-Type: application/json" -d '{"original_url": "https://google.com"}'
Response:
{
"short_url": "http://localhost:8080/abc123"
}
Redirect (Visit the short URL)
curl -v http://localhost:8080/abc123
Full code: https://github.com/luthfisauqi17/go-url-shortner
There you go, that is how you build a URL Shortener using Golang. Thank you for reading, and have a nice day!
📝 Revision
I just realized that sync.Mutex
is needed to safeguard golang's map during concurrent writes. The final code including this revision is already added to the GitHub code.
Top comments (2)
Thanks for the article,
I just wanted to point out that multiple concurrent writes to a map are never safe without proper synchronization in Go.
Your application will handle concurrent traffic therefore you have to use a mutex( sync.Mutex) with the map that stores the URLs
Hi, thanks for pointing that out!
Yes, I just realized that mutex(sync.Mutex) is needed to safeguard golang's map during concurrent writes. I add the revision to this article.