标签: go-fiber

如何从 go Fiber 中的本地上下文中提取值

我已设法使用本地上下文通过自定义中间件设置数据库查询结果。我试图了解如何对用户进行身份验证,然后从数据库中提取其详细信息并将其注入上下文中。这已经完成了。

路由上最后一个方法的本地数据实际上是一个接口,我想从之前的身份验证中间件设置的数据中提取字段。如何将此接口类型处理为某种形式(如结构或 json),以便获取用于执行某些逻辑的字段和值?

user := c.Locals("user") 
fmt.Println("checking for locals",user)
Run Code Online (Sandbox Code Playgroud)

从上面的用户是struct user

 {
Name string `json:"name"`
Emain string `json:"email"`
ID string `json:"id"`
Password string `json:"password"`
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能得到姓名和电子邮件?

go go-fiber

2
推荐指数
1
解决办法
3734
查看次数

如何从单独的文件中设置 Go Fiber V2 中的路由组?

我想为每个子主路线制作单独的文件。我正在使用 go 1.17

main.go

package main

import (
    "rolling_glory_go/routes"

    "github.com/gofiber/fiber/v2"
)

func main() {
    app := fiber.New()

    app.Get("/", func(c *fiber.Ctx) error {
        err := c.SendString("Hello golang!")
        return err
    })

    routes.R_login(app.Group("/login"))
    routes.R_users(app.Group("/users"))

    app.Listen(":3000")
}
Run Code Online (Sandbox Code Playgroud)

我想从中导入路由r_login.gor_users.go这样我就可以管理来自不同文件的许多路由,而不是将单个文件中的许多路由放入main.go. 我遇到这样的错误。

.\main.go:17:26: cannot use app.Group("/login") (type fiber.Router) as type *fiber.Group in argument to routes.R_login: need type assertion
.\main.go:18:26: cannot use app.Group("/users") (type fiber.Router) as type *fiber.Group in argument to routes.R_users: need type assertion

Run Code Online (Sandbox Code Playgroud)

我的结构文件夹

在此输入图像描述

r_login.go

package routes

import "github.com/gofiber/fiber/v2"

func …
Run Code Online (Sandbox Code Playgroud)

go go-fiber

2
推荐指数
1
解决办法
4036
查看次数

Go Fiber 无法在单元测试中解析主体

我正式向 Stack Overflow 上的仁慈的撒玛利亚人喊一声叔叔。

我正在尝试使用模拟数据库对我的 GORM (Postgres) + Fiber API 进行单元测试。我有一个Card模型和一个CreateCardReqBodyPOST 请求正文的模型。为了设置测试,我创建一个随机CreateCardReqBody实例,将其编组为 JSON,然后将其传递到*httptest.Request. 处理程序使用 Fiber 的(*fiber.Ctx).BodyParser函数将请求主体“解组”为空Card结构。但是,当我运行应该通过的测试时,Fiber 抛出“无法处理的实体”错误。

以下是我的代码的相关部分;测试文件是本教程Fiber 关于 (*App).Test 方法的文档的组合。(我意识到代码可以清理;我只是想获得生命的证明,然后专注于修改:)

我做了一些事情来调试这个:我使用与测试相同的值发出了 Postman POST 请求,并且它有效。在测试本身中,我对CreateCardReqBody结构进行编组然后解组,这样就可以了。我已经三次检查了 JSON 字段的拼写是否匹配、结构字段是否已导出等。我还运行了 VSCode 调试器,bodyFiber.Ctx 中的字段对我来说看起来也是正确的。

我开始怀疑这是否与 Fiber 从测试请求和真实请求中解析正文的方式有关。我将非常感谢任何人能分享对此的见解!

模型定义

type Card struct {
gorm.Model

// Implicit Gorm foreign key to fleet ID
FleetID uint `gorm:"index"  json:"fleet_id" validate:"required,min=1"`

// Card provider's account number
ProviderAccountNumber string `json:"provider_account_number"` …
Run Code Online (Sandbox Code Playgroud)

json unit-testing go httptestingcontroller go-fiber

1
推荐指数
1
解决办法
2571
查看次数

更新方法不更新零值

原始问题

Update在 GORM 中使用该方法时,不会保存新数据。即我想设置一个boolfrom trueto false,但即使在Update方法之后它仍然保持真实。

在该方法的描述中有一个警告:“使用结构更新时警告,GORM 不会更新具有零值的字段”

由于我使用结构来更新并且false是 的零值bool,这似乎是预期的行为,但我看不出有任何理由这样做以及如何克服这一点。

func UpdateData(c *fiber.Ctx) error {
    db := database.DBConn

    data := new([]entities.Data)

    if err := c.BodyParser(&data); err != nil {
        return err
    }

    db.Update(&data)
    return c.JSON(data)
}
Run Code Online (Sandbox Code Playgroud)

解决方案总结

首先,正如建议的那样,我new在实例化结构时省略了关键字。然后,我使用了一个辅助函数(来自此处)将结构转换为映射,同时将 json 别名保留为键:

// StructToMap Converts a struct to a map while maintaining the json alias as keys
func StructToMap(obj interface{}) (newMap map[string]interface{}, err error) {
    data, err …
Run Code Online (Sandbox Code Playgroud)

go go-gorm go-fiber

0
推荐指数
1
解决办法
1183
查看次数

通道未在第一个 API 请求上发送数据

我有一个SSE端点将数据发送到前端,并且该数据是从另一个API端点检索的。channels我对in还很陌生go,似乎我必须触发 API 端点两次,以便 SSE 端点将数据发送到前端一次。就目前而言,我还没有编写前端代码来建立 SSE 连接,因为我仍在使用通道。有人可以解释为什么这需要调用 API 两次才能让 SSE 发送数据吗?

上交所路线

func SendSSE(appCtx *fiber.Ctx, dataChannel chan string) error {
    appCtx.Set("Content-Type", "text/event-stream")
    appCtx.Set("Cache-Control", "no-cache")
    appCtx.Set("Connection", "keep-alive")
    appCtx.Set("Transfer-Encoding", "chunked")

    appCtx.Context().SetBodyStreamWriter(fasthttp.StreamWriter(func(w *bufio.Writer) {
        log.Println("SSE Opened")
        for {
            log.Println("Retrieving data channel..")
            fmt.Fprintf(w, "data: Message: %s\n\n", <-dataChannel)
            log.Println(<-dataChannel)

            err := w.Flush()
            if err != nil {
                // Refreshing page in web browser will establish a new
                // SSE connection, but only (the last) one is alive, …
Run Code Online (Sandbox Code Playgroud)

channel go go-fiber

0
推荐指数
1
解决办法
50
查看次数