Как объявить что-то вроде пустого объекта/структуры внутри структуры?

# #go #struct #go-fiber #go-structtag

Вопрос:

Привет, я изучаю язык Go и хочу спросить, как создать пустой объект/структуру в качестве типа данных модели домена? я использую волокно в качестве своего фреймворка, и вот пример того, что я хочу получить от api ответа golang, что-то вроде этого :

 {
  "success": true,
  "message": "Success registered",
  "data": {
      "first_name": "asdfa",
      "last_name": "asdfa",
      "email": "fadsfa",
      "password": "asdfasfas"
  }
}
 

и вот как я стараюсь, вот мой ответ.иди :

 type ResponseDto struct {
    Success bool   `json:"success"`
    Message string   `json:"message"`
    Data    fiber.Map `json:"data"`
}
 

тогда вот как выглядел мой контроллер :

 func Register(c *fiber.Ctx) error {
    user := request.UserRequest{}
    //do something then return

    return c.JSON(models.ResponseDto{
        Success: false,
        Message: "Success registered",
        Data: fiber.Map{
            "data": user,
        },
    })
}
 

тогда вот вам ответ :

 {
  "success": false,
  "message": "Success registered",
  "data": {
    "data": {
      "first_name": "asdfa",
      "last_name": "asdfa",
      "email": "fadsfa",
      "password": "asdfasfas"
    }
  }
}
 

как вы можете видеть, у меня будут вложенные данные, но я не хочу, чтобы они были вложенными, я хочу, чтобы они были вложены только на один уровень, как в моем примере . Как я могу этого достичь? какой тип данных я должен использовать и как его использовать для присвоения значения?

Ответ №1:

Вы должны «преобразовать» пользователя в fiber.Map

 func Register(c *fiber.Ctx) error {
   user := request.UserRequest{}
   //do something then return

   return c.JSON(models.ResponseDto{
       Success: false,
       Message: "Success registered",
       Data: fiber.Map{
           "user_name": user.Name,
           "user_age": user.Age,
       },
   })
}
 

Или вы можете изменить ответ на

 type ResponseDto struct {
   Success bool   `json:"success"`
   Message string   `json:"message"`
   Data    request.UserRequest `json:"data"`
}
 

Комментарии:

1. хорошая идея о преобразовании, но если мне придется конвертировать его вручную, это займет время, когда я буду заниматься рефакторингом в будущем. есть ли инструмент или библиотека, такие как картограф для преобразования структуры в волокно. Карта автоматически?

2. Как вы можете видеть, fiber.Map -это просто map[string]interface{} . Вы можете создать метод преобразования request.UserRequest в fiber.Map . Для получения более общего решения прочитайте о reflect пакете в Golang.

Ответ №2:

Если вам не нужны вложенные данные, не вкладывайте их. Извините, если это звучит как тавтология, но я не знаю, как еще к этому подойти.

Конкретно: если data это a request.UserRequest , добавьте это как поле структуры:

 type ResponseDto struct {
    Success bool                `json:"success"`
    Message string              `json:"message"`
    Data    request.UserRequest `json:"data"`
}
 

Но это объединяет ваши модели запроса и ответа. Если вы хотите избежать этого (я бы хотел), вы должны смириться с наличием более подробного кода и устанавливать fiber.Map записи одну за другой. Нет, вы не можете перебирать поля структуры. Вы можете сделать свой код несколько более выразительным, определив специальный тип:

 type UserMap fiber.Map

type ResponseDto struct {
    Success bool    `json:"success"`
    Message string  `json:"message"`
    Data    UserMap `json:"data"`
}

resp := ResponseDto{
    Success: false,
    Message: "Success registered",
    Data: UserMap{
        "first_name": user.FirstName,
        // ...and so on
    },
}