How to declare something like empty Object/Struct inside Struct?

522 Views Asked by At

Hi i am process of learning the Go language, and i want to ask how to create empty Object/Struct as domain model data type? i am using Fiber as my framework and here is the example of what i want to get from golang response api is something like this :

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

and here is how i try, here is my responseDto.go :

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

then here is how my controller looked like :

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,
        },
    })
}

then here is the response :

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

as you can see, i will have nested data, but i don't want it to be nested, i want it just one level nested, like my example . How can i achieve it? what data type should i use and how to use it to assign the value?

2

There are 2 best solutions below

2
On

You have to "convert" user to 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,
       },
   })
}

Or you can change ResponseDto

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

If you don't want nested data, don't nest it. Sorry if this sounds like a tautology, but I'm not sure how else to address it.

Concretely: if the data is a request.UserRequest, add that as struct field:

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

But that couples your request and response models. If you want to avoid that (I would want to), you must put up with having some more verbose code and set the fiber.Map entries one by one. No, you can't iterate over struct fields. You can make your code somewhat more expressive by defining a dedicated type:

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
    },
}