Handling dynamically typed JSON field values

agolangf · · 523 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I recently encountered an API where the type of field value was not static (e.g. could be an int or an object, depending on the context). </p> <p>I wrote up a post about the way I handled this in Go. Hopefully someone will find it useful. </p> <p><a href="https://medium.com/@nate510/dynamic-json-umarshalling-in-go-88095561d6a0#.hatjdodcv">Dynamic JSON umarshalling in Go</a></p> <hr/>**评论:**<br/><br/>schumacherfm: <pre><p>Nice solution. There once have been posted here a &#34;similar&#34; solution:</p> <p><a href="https://play.golang.org/p/gf7TZmX6AV">https://play.golang.org/p/gf7TZmX6AV</a> </p> <p>This uses json.RawMessage</p></pre>scharty: <pre><p>Nice solution but it requires the type field.</p></pre>schumacherfm: <pre><p>Nope. with json.RawMessage you can do e.g. a bytes.Contain check if it contains further JSON or a number. As numbers fit into one byte you don&#39;t need a rune decode.</p></pre>i0way: <pre><p>Thank&#39;s for the contribution. But IMHO is VERY BAD idea. Of course some time&#39;s we have no choice, but dynamically cast &#34;mouse to elephant&#34; always cause the problems in the future. </p> <p>PS: Nothing personal, i&#39;m just old farter :{&#39;</p></pre>nate510: <pre><p>Yep. I mention that it&#39;s a bad idea more than once in the post. :)</p></pre>pyratzu: <pre><p>I made a data convertion package that I often use when unmarshal JSON</p> <p><a href="https://github.com/CossackPyra/pyraconv" rel="nofollow">https://github.com/CossackPyra/pyraconv</a></p></pre>oefig: <pre><p>I&#39;m having a hard time imagining a scenario where I would need to do something like this. Does the API <em>randomly</em> return an integer or an object?</p> <p>If there was an endpoint that returned &#34;expanded&#34; user data I would have a struct for that data, and another for the endpoint that returned an integer user ID. </p></pre>thockin: <pre><p>We did this in the Kubernetes API - ports identifiers that can be numeric or names. We use an IntOrString type.</p> <p>I sort of regret it. It is human friendly but machine hostile.</p></pre>nate510: <pre><p>In my real-world case, there were a lot of domain objects that could be nested inside each other in responses, sometimes recursively. And the documentation wasn&#39;t great (read: nonexistent) on when an ID would appear vs. an embedded object. </p> <p>So this solution made sense because I was dealing with a complex, poorly designed API with poor documentation. If you have a hard time imagining needing this, then consider yourself fortunate. :)</p></pre>XANi_: <pre><p>You can also <a href="https://play.golang.org/p/sLOBjawjhi" rel="nofollow">partially unmarshal JSON data</a>:</p> <pre><code>partial := make(map[string]json.RawMessage) err := json.Unmarshal([]byte(`{&#34;type&#34;:&#34;create&#34;,&#34;data&#34;:{&#34;rest&#34;:&#34;of&#34;,&#34;data&#34;:3}}`),&amp;partial) fmt.Printf(&#34;%s | %s | %s&#34;, partial[`type`], partial[`data`], err) </code></pre> <p>if your JSON message uses one of fields in first level to describe type of request</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

523 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传