skip to Main Content

I am receiving an item from a package of an imported third-party module:

myItem := importedPackage.get()

It is a struct like this:

type ImportedStruct struct {
    Ip                  net.IP                  `json:"ip"`
    Index               uint32                  `json:"index"`
    LocalIndex          uint32                  `json:"localIndex"`
    RemoteIndex         []*udp.Addr             `json:"remoteIndex"`
    Certificates        *certificates           `json:"certificates"`
    VpnAddress          []iputil.VpnIp          `json:"vpnAddress"`
}

I would like to remove one or more of the items there, before returning it from my Golang Gin API as JSON:

c.JSON(200, &myItem)

The issue is trying to find the most resource efficient way to do this.

I have considered a loop and writing the fields I need to a new struct:

newItem := make([]ImportedStruct, len(myItem))

i := 0
for _, v := range myItem {
    newItem[i] = ...
    ...
}

c.JSON(200, &hostList)

I also considered marshalling and then unmarshalling to assign it to another struct before returning it through the API:

// Marshal the host map to json
marshaledJson, err := json.Marshal(newItem)
if err != nil {
    log.Error(err)
    c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
    return
}

// Unmarshal the json into structs
var unmarshalledJson []ImportedStruct
err = json.Unmarshal(marshaledJson, &unmarshalledJson)
if err != nil {
    log.Error(err)
    c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
    return
}

// Return the modified host map
c.JSON(200, &unmarshalledJson)

I’m hoping though to find a more efficient way to do this. myItem could contain over 3m lines of JSON, and looping through it all, or marshalling and unmarshalling seems like it involves more processes then it needs just to achieve something relatively simple.

Edit: The struct is a slice ([]).

2

Answers


  1. If you can change the struct, put a dash for the json tag. For example to remove LocalIndex:

    type ImportedStruct struct {
        Ip                  net.IP                  `json:"ip"`
        Index               uint32                  `json:"index"`
        LocalIndex          uint32                  `json:"-"`
        RemoteIndex         []*udp.Addr             `json:"remoteIndex"`
        Certificates        *certificates           `json:"certificates"`
        VpnAddress          []iputil.VpnIp          `json:"vpnAddress"`
    }
    
    

    If you can’t change the struct (3rd party package), and you aren’t interested in forking or something, you will have to make your own struct that includes or embeds ImportedStruct. Then, implement json.Marshaler and json.Unmarshaler on your new struct to do what you need it to do.

    Login or Signup to reply.
  2. Define a new struct that is a copy of the one you have, with different tags:

    type ImportedStructMarshal struct {
        Ip                  net.IP                  `json:"ip"`
        Index               uint32                  `json:"index"`
        LocalIndex          uint32                  `json:"-"`
        RemoteIndex         []*udp.Addr             `json:"remoteIndex"`
        Certificates        *certificates           `json:"certificates"`
        VpnAddress          []iputil.VpnIp          `json:"vpnAddress"`
    }
    

    Then, use this new struct to marshal:

    var input ImportedStruct
    forMarshal:=ImportedStructMarshal(input)
    ...
    

    This will work as long as the new struct is field-by-field compatible with the imported struct.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search