Unmarshaling a JSON decimal optionally represented as a string

Hi forum,
I’m writing a client for an API that is somewhat broken.
It would sometimes return decimal numbers and other times return the numbers represented as strings from the same endpoints. Since I can’t get the api owners to fix it (I wonder how their own client works…), I’ve fixed the problem in the following way:

http://play.golang.org/p/_oOmvlZQhL

I don’t think it’s the correct way, since I would have to write an UnmarshalJSON method for every endpoint. It seems to me there must be a better way? I was thinking of writing a custom struct tag like the json:",string" called “stringoptional”, but I have no idea where to start and if it’s the correct place to solve my problem.

Any ideas?

I think the most usual option would be to use an empty interface and reflection… unless I’m missing something and that doesn’t address your particular problem.

json.Number may solve this for you almost automatically:

1 Like

Ok, json.Number eliminates the custom type and my inefficient unmarshaling in there, so it’s better. Thank you!
I would still have to write UnmarshalJSON methods for all structs (code that uses this client should not know anything about json.) and it’s a lot of structs. If there’s nothing else I can improve maybe go generate can help with that.

Thanks for the reply. Using an empty interface and type checking the value inside every struct.UnmarshalJSON() might be more efficient than my custom type, but I still think that is not the right place to solve this problem. If I have to go that route I will use @calmh 's suggestion and code generate, but I hope there’s another way.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.