像 Bitly 或 TinyURL 這樣的 URL 縮短器是非常流行的工具,但您有沒有想過如何建立一個工具?在這篇部落格中,我們將深入探討如何在 Go 中建立具有速率限制的自訂 URL 縮短器以及用於資料儲存和 IP 追蹤的 Redis 資料庫。我們將介紹核心功能、技術堆疊以及我在過程中遇到的挑戰。
此 URL 縮短器應用程式接受用戶的長 URL,產生更短的唯一鏈接,並允許用戶根據需要自訂縮短的別名。伺服器會將所有使用縮短 URL 的訪客重新導向到原始長 URL。
以下是主要組件的快速概述:
考慮到這些功能,讓我們分解實現。
核心文件和資料夾的組織方式如下:
. ├── main.go # Entry point for the application ├── routes/ │ ├── shorten.go # Handles URL shortening and redirects ├── database/ │ ├── redis.go # Database connection logic ├── helpers/ │ ├── helper.go # Utility functions for URL validation ├── .env # Environment variables ├── docker-compose.yml # Docker setup for Redis
我們的主應用程式檔案設定用於縮短和解析 URL 的路由。這是程式碼片段:
package main import ( "log" "os" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/logger" "github.com/joho/godotenv" "github.com/ravikisha/url-shortener/routes" ) func setupRoutes(app *fiber.App) { app.Get("/:url", routes.ResolveURL) app.Post("/api/v1", routes.ShortenURL) } func main() { err := godotenv.Load() if err != nil { log.Fatal("Error loading .env file") } app := fiber.New() app.Use(logger.New()) setupRoutes(app) log.Fatal(app.Listen(os.Getenv("APP_PORT"))) }
為了防止濫用,我們使用 Redis 來追蹤每個 IP 位址並限制允許的請求數量。流程如下:
. ├── main.go # Entry point for the application ├── routes/ │ ├── shorten.go # Handles URL shortening and redirects ├── database/ │ ├── redis.go # Database connection logic ├── helpers/ │ ├── helper.go # Utility functions for URL validation ├── .env # Environment variables ├── docker-compose.yml # Docker setup for Redis
在 redis.go 中,我們定義了一個輔助函數來連接到 Redis。此連線用於跨不同元件儲存短 URL 並實施速率限制。以下是如何設定 Redis 的簡單範例:
package main import ( "log" "os" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/logger" "github.com/joho/godotenv" "github.com/ravikisha/url-shortener/routes" ) func setupRoutes(app *fiber.App) { app.Get("/:url", routes.ResolveURL) app.Post("/api/v1", routes.ShortenURL) } func main() { err := godotenv.Load() if err != nil { log.Fatal("Error loading .env file") } app := fiber.New() app.Use(logger.New()) setupRoutes(app) log.Fatal(app.Listen(os.Getenv("APP_PORT"))) }
為了簡化 Redis 的設置,我使用了 Docker。這使得應用程式可移植且易於部署。
package routes import ( "os" "strconv" "time" "github.com/asaskevich/govalidator" "github.com/go-redis/redis/v8" "github.com/gofiber/fiber/v2" "github.com/ravikisha/url-shortener/database" "github.com/ravikisha/url-shortener/helpers" ) // Define structs for the request and response data type request struct { URL string `json:"url"` CustomShort string `json:"short"` Expiry time.Duration `json:"expiry"` } type response struct { URL string `json:"url"` CustomShort string `json:"short"` Expiry time.Duration `json:"expiry"` XRateRemaining int `json:"x-rate-remaining"` XRateLimitReset time.Duration `json:"x-rate-limit-reset"` }
運行 Redis 的 Docker 容器:
package database import ( "context" "github.com/go-redis/redis/v8" ) var Ctx = context.Background() func NewClient(dbNum int) *redis.Client { rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", DB: dbNum, }) return rdb }
在.env中設定環境變數:
version: '3' services: redis: image: "redis:alpine" ports: - "6379:6379"
運行 Go 應用程式:
docker-compose up -d
現在,應用程式已上線,您可以開始縮短網址!
使用以下 JSON 負載向 /api/v1 發送 POST 請求:
DB_ADDR="localhost:6379" DB_PASSWORD="" APP_PORT=":6767" DOMAIN="localhost:6767" APP_QUOTA=10
使用產生的短 URL,例如 http://localhost:6767/exmpl,重定向到 https://example.com。
我想在將來添加一些功能和最佳化:
建立這個 URL 縮短器是一次有益的體驗,也是探索 Go、Fiber 和 Redis 的好方法。無論您是學習後端開發還是探索 Go 在 Web 服務中的潛力,該專案都提供了堅實的基礎。
如果您想查看實際程式碼,請在此處查看 GitHub 儲存庫。讓我知道您的想法或您對改進專案有什麼建議!
以上是在 Go 中建立具有速率限制和 Redis 的 URL 縮短器的詳細內容。更多資訊請關注PHP中文網其他相關文章!