像 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中文网其他相关文章!