Need idiomatic json help!

agolangf · · 256 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Hello gophers, it is fairly common to come across an api that has a json wrapper class, so requests look something like this,</p> <pre><code>{ &#34;status&#34;: &#34;ok&#34;, &#34;type&#34;: &#34;type1&#34;, &#34;body&#34;: { &#34;var1&#34;: &#34;key1&#34;, &#34;var2&#34;: &#34;key2&#34; } } { &#34;status&#34;: &#34;ok&#34;, &#34;type&#34;: &#34;type2&#34;, &#34;body&#34;: { &#34;var3&#34;: &#34;key3&#34;, &#34;var4&#34;: &#34;key4&#34; } } </code></pre> <p>in languages like java/c# I usually use a generic JsonObject to represent the body then cast to my concrete class after a switch.</p> <p>Do you know of a good idiomatic way of doing this? </p> <p>Preferably w.o having to unmarshal twice.</p> <p>Thanks</p> <p>Edit: Looks like you do have to unmarshal twice.. but this works well <a href="https://play.golang.org/p/gf7TZmX6AV">https://play.golang.org/p/gf7TZmX6AV</a></p> <hr/>**评论:**<br/><br/>jerf: <pre><p>A lot of languages that make it look like they aren&#39;t unmarshalling twice still kind of are behind the hood. They parse the JSON into a generic representation, like the one <code>encoding/json</code> gives for <code>map[string]interface{}</code>, and then marshal that into the final target object. While probably still better than the double-parse Go does, it&#39;s less advantageous over Go than it may initially seem. By contrast, if you do know the type you&#39;re going into, Go does marshal directly into the correct objects. (<code>encoding/json</code> then loses a bit again due to being reflection based. If that&#39;s a problem there are some packages that will generate code for you instead of using reflection.)</p> <p>I&#39;ve used this approach for some fairly wide cross-language communication and I can&#39;t say any language is really <em>good</em> at this. The problem is fundamental to JSON; you have no control over the order of the incoming keys, and there is nothing you can do about the possibility that the &#34;type&#34; key will come last, after megabytes or gigabytes of other stuff, all of which you need to hold in some sort of holding pattern until then.</p> <p>If that&#39;s a real problem, then you just determined that you can&#39;t use JSON to solve your problem. Of course it often isn&#39;t a real problem, but if it is, you&#39;ll have to leave JSON behind. It&#39;s a nifty little default and great for cross-language support, but it&#39;s definitely a lowest-common-denominator sort of serialization format, not really the best at anything except being cross-platform.</p></pre>twek: <pre><blockquote> <p>used this approach for some fairly wide cross-language communication and I can&#39;t say any language is really good at this. The problem is fundamental to JSON; you have no control over the order of the incoming keys, and there is nothing you can do about the possibility that the &#34;type&#34; key will come last, after megabytes or gigabytes of other stuff, all of which you need to hold in some sort of holding pattern until then.</p> </blockquote> <p>Thanks for taking the time to write this, I am happy enough with the RawMessage approach as the messages I am dealing with are small, </p> <p>thanks!</p></pre>pierrrre: <pre><p><a href="https://golang.org/pkg/encoding/json/#RawMessage">https://golang.org/pkg/encoding/json/#RawMessage</a> ? Use it to decode your embedded object later, with the right type.</p></pre>twek: <pre><p>Like this? <a href="https://play.golang.org/p/gf7TZmX6AV" rel="nofollow">https://play.golang.org/p/gf7TZmX6AV</a></p></pre>pierrrre: <pre><p>Yes!</p></pre>demitriousk: <pre><p>in cases like this you&#39;d want to use json.RawMessage for the body part of your struct... Then you would unmarshal body into a seperate and appropriate struct for your needs based on the contents of status and type.</p></pre>twek: <pre><p>Like this? <a href="https://play.golang.org/p/gf7TZmX6AV" rel="nofollow">https://play.golang.org/p/gf7TZmX6AV</a></p></pre>
256 次点击  
加入收藏 微博
0 回复
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传