Building a URL Shortener
This tutorial guides you through creating a URL shortener using DiceDB, a key-value store, with Go. We’ll set up endpoints to generate short URLs and redirect them to the original URLs.
Prerequisites
Section titled “Prerequisites”- Go (version 1.18 or later): Download Go
- DiceDB: A DiceDB server running locally. Refer to the DiceDB Installation Guide if you haven’t set it up yet.
1. Install and Run DiceDB
Section titled “1. Install and Run DiceDB”Start a DiceDB server using Docker:
docker run -d -p 7379:7379 dicedb/dicedb
This command pulls the DiceDB Docker image and runs it, exposing it on port 7379
.
2. Initialize a New Go Project
Section titled “2. Initialize a New Go Project”Create a new directory for your project and initialize a Go module:
mkdir url-shortenercd url-shortenergo mod init url-shortener
3. Install Required Packages
Section titled “3. Install Required Packages”Install the DiceDB Go SDK and other dependencies:
go get github.com/dicedb/dicedb-go@v1.0.3go get github.com/gin-gonic/gingo get github.com/google/uuid
Understanding DiceDB Commands
Section titled “Understanding DiceDB Commands”We’ll use the following DiceDB commands:
SET
Command
Section titled “SET Command”Stores a key-value pair in DiceDB.
- Syntax:
SET key value [expiration]
key
: Unique identifier (e.g., short URL code)value
: Data to store (e.g., serialized JSON)expiration
: Optional; time-to-live in seconds (use0
for no expiration)
GET
Command
Section titled “GET Command”Retrieves the value associated with a key.
- Syntax:
GET key
key
: Identifier for the data to retrieve
Writing the Code
Section titled “Writing the Code”Create a file named main.go
and add the following code:
-
main.go
:package mainimport ("context""encoding/json""log""net/http""github.com/gin-gonic/gin""github.com/google/uuid""github.com/dicedb/dicedb-go" // DiceDB Go SDK)type URL struct {ID string `json:"id"`LongURL string `json:"long_url"`ShortURL string `json:"short_url"`}var db *dicedb.Client// Initialize DiceDB connectionfunc init() {db = dicedb.NewClient(&dicedb.Options{Addr: "localhost:7379",})}// Creates a short URL from a given long URLfunc CreateShortURL(c *gin.Context) {var requestBody URLif err := c.ShouldBindJSON(&requestBody); err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})return}// Generate unique short ID and construct the short URLshortID := uuid.New().String()[:8]requestBody.ID = shortIDrequestBody.ShortURL = "http://localhost:8080/" + shortID// Serialize URL struct to JSON and store it in DiceDBurlData, err := json.Marshal(requestBody)if err != nil {c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save URL"})return}if err := db.Set(context.Background(), shortID, urlData, 0).Err(); err != nil {c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save URL"})return}c.JSON(http.StatusCreated, gin.H{"short_url": requestBody.ShortURL})}// Redirects to the original URL based on the short URL IDfunc RedirectURL(c *gin.Context) {id := c.Param("id")// Retrieve stored URL data from DiceDBurlData, err := db.Get(context.Background(), id).Result()if err != nil {c.JSON(http.StatusNotFound, gin.H{"error": "URL not found"})return}// Deserialize JSON data back into URL structvar url URLif err := json.Unmarshal([]byte(urlData), &url); err != nil {c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to decode URL data"})return}// Redirect user to the original long URLc.Redirect(http.StatusFound, url.LongURL)}func main() {router := gin.Default()// Define endpoints for creating short URLs and redirectingrouter.POST("/shorten", CreateShortURL)router.GET("/:id", RedirectURL)// Start the server on port 8080if err := router.Run(":8080"); err != nil {log.Fatal("Failed to start server:", err)}}
Explanation
Section titled “Explanation”1. Initialize the DiceDB Client
Section titled “1. Initialize the DiceDB Client”We set up the DiceDB client in the init
function:
db = dicedb.NewClient(&dicedb.Options{ Addr: "localhost:7379",})
2. Create Short URL Endpoint
Section titled “2. Create Short URL Endpoint”- Input Validation: Ensures the
long_url
field is present. - Short ID Generation: Uses
uuid
to create a unique 8-character ID. - Data Serialization: Converts the
URL
struct to JSON. - Data Storage: Saves the JSON data in DiceDB with the
Set
command. - Response: Returns the generated short URL.
3. Redirect to Original URL Endpoint
Section titled “3. Redirect to Original URL Endpoint”- Data Retrieval: Fetches the URL data from DiceDB using the
Get
command. - Data Deserialization: Converts JSON back to the
URL
struct. - Redirection: Redirects the user to the
LongURL
.
4. Start the Server
Section titled “4. Start the Server”The main
function sets up the routes and starts the server on port 8080
.
Running the Application
Section titled “Running the Application”1. Start the Go Application
Section titled “1. Start the Go Application”go run main.go
This will start the application server on port 8080 by default, you should see output similar to
[GIN-debug] Listening and serving HTTP on :8080
2. Ensure DiceDB is Running
Section titled “2. Ensure DiceDB is Running”Ensure your DiceDB server is up and running on port 7379
.
Testing the application
Section titled “Testing the application”1. Shorten URL:
Section titled “1. Shorten URL:”Using curl
:
curl -X POST -H "Content-Type: application/json" -d '{"long_url": "https://example.com"}' http://localhost:8080/shorten
Response:
{ "short_url": "http://localhost:8080/<short ID generated by the server>"}
2. Redirect to Original URL:
Section titled “2. Redirect to Original URL:”Using curl
:
curl -L http://localhost:8080/abcd1234
Using a Browser: Navigate to:
http://localhost:8080/abcd1234
You should be redirected to https://example.com
.