Removing fields from struct or hiding them in JSON Response

后端 未结 13 1344
孤街浪徒
孤街浪徒 2020-12-12 09:37

I\'ve created an API in Go that, upon being called, performs a query, creates an instance of a struct, and then encodes that struct as JSON before sending back to the caller

相关标签:
13条回答
  • 2020-12-12 10:09

    use `json:"-"`

    // Field is ignored by this package.
    Field int `json:"-"`
    
    // Field appears in JSON as key "myName".
    Field int `json:"myName"`
    
    // Field appears in JSON as key "myName" and
    // the field is omitted from the object if its value is empty,
    // as defined above.
    Field int `json:"myName,omitempty"`
    
    // Field appears in JSON as key "Field" (the default), but
    // the field is skipped if empty.
    // Note the leading comma.
    Field int `json:",omitempty"`
    

    doc : http://golang.org/pkg/encoding/json/#Marshal

    0 讨论(0)
  • 2020-12-12 10:09

    Another way to do this is to have a struct of pointers with the ,omitempty tag. If the pointers are nil, the fields won't be Marshalled.

    This method will not require additional reflection or inefficient use of maps.

    Same example as jorelli using this method: http://play.golang.org/p/JJNa0m2_nw

    0 讨论(0)
  • 2020-12-12 10:09

    You can use tagging attribute "omitifempty" or make optional fields pointers and leave those you want skipped uninitialized.

    0 讨论(0)
  • 2020-12-12 10:14

    I created this function to convert struct to JSON string by ignoring some fields. Hope it will help.

    func GetJSONString(obj interface{}, ignoreFields ...string) (string, error) {
        toJson, err := json.Marshal(obj)
        if err != nil {
            return "", err
        }
    
        if len(ignoreFields) == 0 {
            return string(toJson), nil
        }
    
        toMap := map[string]interface{}{}
        json.Unmarshal([]byte(string(toJson)), &toMap)
    
        for _, field := range ignoreFields {
            delete(toMap, field)
        }
    
        toJson, err = json.Marshal(toMap)
        if err != nil {
            return "", err
        }
        return string(toJson), nil
    }
    

    Example: https://play.golang.org/p/nmq7MFF47Gp

    0 讨论(0)
  • 2020-12-12 10:18

    EDIT: I noticed a few downvotes and took another look at this Q&A. Most people seem to miss that the OP asked for fields to be dynamically selected based on the caller-provided list of fields. You can't do this with the statically-defined json struct tag.

    If what you want is to always skip a field to json-encode, then of course use json:"-" to ignore the field (also note that this is not required if your field is unexported - those fields are always ignored by the json encoder). But that is not the OP's question.

    To quote the comment on the json:"-" answer:

    This [the json:"-" answer] is the answer most people ending up here from searching would want, but it's not the answer to the question.


    I'd use a map[string]interface{} instead of a struct in this case. You can easily remove fields by calling the delete built-in on the map for the fields to remove.

    That is, if you can't query only for the requested fields in the first place.

    0 讨论(0)
  • 2020-12-12 10:21

    I also faced this problem, at first I just wanted to specialize the responses in my http handler. My first approach was creating a package that copies the information of a struct to another struct and then marshal that second struct. I did that package using reflection, so, never liked that approach and also I wasn't dynamically.

    So I decided to modify the encoding/json package to do this. The functions Marshal, MarshalIndent and (Encoder) Encode additionally receives a

    type F map[string]F

    I wanted to simulate a JSON of the fields that are needed to marshal, so it only marshals the fields that are in the map.

    https://github.com/JuanTorr/jsont

    package main
    
    import (
        "fmt"
        "log"
        "net/http"
    
        "github.com/JuanTorr/jsont"
    )
    
    type SearchResult struct {
        Date        string      `json:"date"`
        IdCompany   int         `json:"idCompany"`
        Company     string      `json:"company"`
        IdIndustry  interface{} `json:"idIndustry"`
        Industry    string      `json:"industry"`
        IdContinent interface{} `json:"idContinent"`
        Continent   string      `json:"continent"`
        IdCountry   interface{} `json:"idCountry"`
        Country     string      `json:"country"`
        IdState     interface{} `json:"idState"`
        State       string      `json:"state"`
        IdCity      interface{} `json:"idCity"`
        City        string      `json:"city"`
    } //SearchResult
    
    type SearchResults struct {
        NumberResults int            `json:"numberResults"`
        Results       []SearchResult `json:"results"`
    } //type SearchResults
    func main() {
        msg := SearchResults{
            NumberResults: 2,
            Results: []SearchResult{
                {
                    Date:        "12-12-12",
                    IdCompany:   1,
                    Company:     "alfa",
                    IdIndustry:  1,
                    Industry:    "IT",
                    IdContinent: 1,
                    Continent:   "america",
                    IdCountry:   1,
                    Country:     "México",
                    IdState:     1,
                    State:       "CDMX",
                    IdCity:      1,
                    City:        "Atz",
                },
                {
                    Date:        "12-12-12",
                    IdCompany:   2,
                    Company:     "beta",
                    IdIndustry:  1,
                    Industry:    "IT",
                    IdContinent: 1,
                    Continent:   "america",
                    IdCountry:   2,
                    Country:     "USA",
                    IdState:     2,
                    State:       "TX",
                    IdCity:      2,
                    City:        "XYZ",
                },
            },
        }
        fmt.Println(msg)
        http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    
            //{"numberResults":2,"results":[{"date":"12-12-12","idCompany":1,"idIndustry":1,"country":"México"},{"date":"12-12-12","idCompany":2,"idIndustry":1,"country":"USA"}]}
            err := jsont.NewEncoder(w).Encode(msg, jsont.F{
                "numberResults": nil,
                "results": jsont.F{
                    "date":       nil,
                    "idCompany":  nil,
                    "idIndustry": nil,
                    "country":    nil,
                },
            })
            if err != nil {
                log.Fatal(err)
            }
        })
    
        http.ListenAndServe(":3009", nil)
    }
    
    0 讨论(0)
提交回复
热议问题