首页 > 后端开发 > Golang > 正文

Go 路由:使用 net/http 处理和分组路由

Barbara Streisand
发布: 2024-11-03 05:15:02
原创
712 人浏览过

Go Routing : Handling and Grouping Routes with net/http

Go 1.22 为 net/http 包的路由器带来了两项增强:方法匹配和通配符。这些功能使您可以将常见的路由表达为模式而不是 Go 代码。虽然它们解释和使用起来很简单,但当多个匹配请求时,想出正确的规则来选择获胜模式是一个挑战。

Go 1.22 在其 net/http 包中添加了新功能,使其成为使用第三方库的良好替代方案。在本文中,我们将了解如何使用 Golang 的 net/http 包处理路由。我们将从基本的路线处理开始,然后继续对这些路线进行分组。

笔记

  • 这假设您使用的 Go 版本 >= 1.22
  • 更多详细信息请参阅存储库

基本路由

让我们首先了解如何注册您的路线。

// main.go
package main

import (
    "log"
    "net/http"
)

func main() {
    router := http.NewServeMux()

    router.HandleFunc("GET /users/", getUsers)
    router.HandleFunc("POST /users/", createUser)
    router.HandleFunc("GET /users/{id}/", getUser)
    router.HandleFunc("DELETE /users/{id}/", deleteUser)

    err := http.ListenAndServe(":8000", router)
    if err != nil {
        log.Fatal(err)
    }
}

// Here goes the implementation for getUsers, getUser, createUser, deleteUser
// Check the repo in services/users/routes.go

type User struct {
    ID    int    `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

var users []User = []User{
    {ID: 1, Name: "Bumblebee", Email: "bumblebee@autobots.com"},
    {ID: 2, Name: "Optimus Prime", Email: "optimus.prime@autobots.com"},
    {ID: 3, Name: "Ironhide", Email: "ironhide@autobots.com"},
    {ID: 4, Name: "Hot Rod", Email: "hot.rod@autobots.com"},
}

func getUsers(w http.ResponseWriter, r *http.Request) {
    response := map[string]any{
        "message": "Done",
        "users":   users,
    }
    utils.WriteJSONResponse(w, http.StatusOK, response)
}
登录后复制
登录后复制

让我们看一下上面的代码:

  1. router := http.NewServeMux() 这将创建一个新的请求多路复用器。当发出请求时,路由器会检查请求的 URL 并选择最合适的处理程序来处理该请求。
  2. router.HandleFunc("GET /users/", getUsers) 这会注册 /users/ 路由并表明这将是一个 GET 方法路由。
  3. utils.WriteJSONResponse 这是一个用于创建 JSON 响应的实用函数,可以在 utils/utils.go 的存储库中找到

注意: 提出请求时,请确保添加尾部斜杠。否则将返回 404 未找到响应
示例:

  • http://localhost:8000/users 返回 404
  • http://localhost:8000/users/ 返回正确的服务器响应

样品请求:

  • 请求:GET http://localhost:8000/users/
  • 回应:
// statusCode: 200
{
    "message": "Done",
    "users": [
        {
            "id": 1,
            "name": "Bumblebee",
            "email": "bumblebee@autobots.com"
        },
        {
            "id": 2,
            "name": "Optimus Prime",
            "email": "optimus.prime@autobots.com"
        },
        {
            "id": 3,
            "name": "Ironhide",
            "email": "ironhide@autobots.com"
        },
        {
            "id": 4,
            "name": "Hot Rod",
            "email": "hot.rod@autobots.com"
        }
    ]
}
登录后复制
登录后复制

分组路线

从上面我们可以看出,这需要我们在同一个地方注册所有端点,并且很快就会失控。通过将相关的路由和逻辑放在一起,对路由进行分组可以帮助您保持代码的组织性、可扩展性和可维护性。它允许您有选择地应用中间件,鼓励可重用性并提高可读性,特别是随着您的应用程序的增长。
现在让我们看看如何对路线进行分组

我们将首先在定义其处理函数的包中本地注册路由。下一步是将所有这些不同的路线整合在一起并启动服务器。

// services/users/routes.go
package user

import (
    "fmt"
    "net/http"
    "strconv"

    "<your-project-name>/gorouting/utils"
)

type Handler struct{}

func NewHandler() *Handler {
    return &Handler{}
}

func (h *Handler) RegisterRoutes() *http.ServeMux {
    r := http.NewServeMux()
    r.HandleFunc("GET /", getUsers)
    r.HandleFunc("POST /", createUser)

    r.HandleFunc("GET /{id}/", getUser)
    r.HandleFunc("DELETE /{id}/", deleteUser)

    return r
}
// ...
登录后复制

让我们看一下代码。

  1. func NewHandler() *Handler 这将创建一个新的处理程序,用于依赖注入,例如添加对数据库的访问(应该存在)。
  2. func (h *Handler) RegisterRoutes() *http.ServeMux 这里我们创建一个新的 ServeMux 并注册路由。
// main.go
package main

import (
    "log"
    "net/http"
)

func main() {
    router := http.NewServeMux()

    router.HandleFunc("GET /users/", getUsers)
    router.HandleFunc("POST /users/", createUser)
    router.HandleFunc("GET /users/{id}/", getUser)
    router.HandleFunc("DELETE /users/{id}/", deleteUser)

    err := http.ListenAndServe(":8000", router)
    if err != nil {
        log.Fatal(err)
    }
}

// Here goes the implementation for getUsers, getUser, createUser, deleteUser
// Check the repo in services/users/routes.go

type User struct {
    ID    int    `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

var users []User = []User{
    {ID: 1, Name: "Bumblebee", Email: "bumblebee@autobots.com"},
    {ID: 2, Name: "Optimus Prime", Email: "optimus.prime@autobots.com"},
    {ID: 3, Name: "Ironhide", Email: "ironhide@autobots.com"},
    {ID: 4, Name: "Hot Rod", Email: "hot.rod@autobots.com"},
}

func getUsers(w http.ResponseWriter, r *http.Request) {
    response := map[string]any{
        "message": "Done",
        "users":   users,
    }
    utils.WriteJSONResponse(w, http.StatusOK, response)
}
登录后复制
登录后复制

这里我们将重点关注 Run 方法。

  1. userHandler := user.NewHandler() 这将创建一个新的处理程序,在这里可以将数据库连接等内容传递到需要它们的端点。这称为依赖注入。
  2. userRouter := userHandler.RegisterRoutes() 这将创建一个包含用户路由的 ServeMux。
  3. router.Handle("/api/v1/users/", http.StripPrefix("/api/v1/users", userRouter)) 这会使用 /users/ 的基本 URL 注册用户。 StripPrefix 在将请求 URL 路由到 userRouter 之前删除指定的前缀。
// statusCode: 200
{
    "message": "Done",
    "users": [
        {
            "id": 1,
            "name": "Bumblebee",
            "email": "bumblebee@autobots.com"
        },
        {
            "id": 2,
            "name": "Optimus Prime",
            "email": "optimus.prime@autobots.com"
        },
        {
            "id": 3,
            "name": "Ironhide",
            "email": "ironhide@autobots.com"
        },
        {
            "id": 4,
            "name": "Hot Rod",
            "email": "hot.rod@autobots.com"
        }
    ]
}
登录后复制
登录后复制

“在 Go 1.22 中,net/http 现在更加通用,提供了提高清晰度和效率的路由模式。这种路由分组方法显示了在利用 Go 内置路由功能的同时维护可扩展代码是多么容易。”聊天GPT

现在我们已经成功对用户路线进行了分组。克隆存储库并尝试添加另一个服务。

以上是Go 路由:使用 net/http 处理和分组路由的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!