skip to Main Content

I am forced to use an API which has two different keys or identifiers for the same object, VAT – number. Depending on the call is GET or POST/PATCH

In GET I must use this struct for unmarshal / decode from json:

type SilverfinCompany struct {
    ID                     int    `json:"id"`
    Name                   string `json:"name"`
    Vat                    string `json:"vat"` // here
}

In POST and PATCH I can use this struct for marshal to json:

type SilverfinCompany struct {
    ID                     int    `json:"id"`
    Name                   string `json:"name"`
    Vat                    string `json:"vat_identifier"` // here
}

The obvious solution is to have two "different" structs with the same content, but slightly different JSON keys, and two conversion functions. Alternatively have two different fields in the struct: Vat and VatIndentifier.

The problem is that it will add a extra layer of complexity to an already complex code.

So I wonder:

Is there a way (reflection like) to alter the JSON key of the Vat-field in the struct depending on the situation?

2

Answers


  1. You can also have both fields within the same struct, and assign the same value to both of them. The target API can choose to use each and ignore the other.

    type SilverfinCompany struct {
        ID                     int    `json:"id"`
        Name                   string `json:"name"`
        Vat                    string `json:"vat"`
        VatIdent               string `json:"vat_identifier"`
    }
    
    Login or Signup to reply.
  2. You cannot modify a type definition, including struct tags, at runtime.

    As long as the field types and orders (i.e., the memory layouts) are identical, you don’t need any conversion functions at all, they’re directly convertible: https://go.dev/play/p/IhkVM-BMLiY

    func main() {
        foo := SilverfinCompanyFoo{
            ID:   1,
            Name: "Baz",
            Vat:  "Qux",
        }
    
        bar := SilverfinCompanyBar(foo)
        fmt.Println(bar)
    }
    
    type SilverfinCompanyFoo struct {
        ID   int    `json:"id"`
        Name string `json:"name"`
        Vat  string `json:"vat"` // here
    }
    
    type SilverfinCompanyBar struct {
        ID   int    `json:"id"`
        Name string `json:"name"`
        Vat  string `json:"vat_identifier"` // here
    }
    
    // {1 Baz Qux}
    

    This is a common solution to this type of scenario.

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