mirror of
https://github.com/golang/go
synced 2024-11-25 01:57:56 -07:00
doc: add JSON-RPC: a tale of interfaces article
Originally published on The Go Programming Language Blog, Abril 27, 2010. http://blog.golang.org/2010/04/json-rpc-tale-of-interfaces.html R=adg, r CC=golang-dev https://golang.org/cl/5920044
This commit is contained in:
parent
308cc100e6
commit
a786fe8e13
@ -12,6 +12,7 @@ RAWHTML=\
|
|||||||
articles/godoc_documenting_go_code.rawhtml\
|
articles/godoc_documenting_go_code.rawhtml\
|
||||||
articles/gobs_of_data.rawhtml\
|
articles/gobs_of_data.rawhtml\
|
||||||
articles/json_and_go.rawhtml\
|
articles/json_and_go.rawhtml\
|
||||||
|
articles/json_rpc_tale_of_interfaces.rawhtml\
|
||||||
articles/image_draw.rawhtml\
|
articles/image_draw.rawhtml\
|
||||||
effective_go.rawhtml\
|
effective_go.rawhtml\
|
||||||
go1.rawhtml\
|
go1.rawhtml\
|
||||||
|
78
doc/articles/json_rpc_tale_of_interfaces.html
Normal file
78
doc/articles/json_rpc_tale_of_interfaces.html
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
<!--{
|
||||||
|
"Title": "JSON-RPC: a tale of interfaces"
|
||||||
|
}-->
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Here we present an example where Go's
|
||||||
|
<a href="/doc/effective_go.html#interfaces_and_types">interfaces</a> made it
|
||||||
|
easy to refactor some existing code to make it more flexible and extensible.
|
||||||
|
Originally, the standard library's <a href="/pkg/net/rpc/">RPC package</a> used
|
||||||
|
a custom wire format called <a href="/pkg/encoding/gob/">gob</a>. For a
|
||||||
|
particular application, we wanted to use <a href="/pkg/encoding/json/">JSON</a>
|
||||||
|
as an alternate wire format.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
We first defined a pair of interfaces to describe the functionality of the
|
||||||
|
existing wire format, one for the client, and one for the server (depicted
|
||||||
|
below).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
type ServerCodec interface {
|
||||||
|
ReadRequestHeader(*Request) error
|
||||||
|
ReadRequestBody(interface{}) error
|
||||||
|
WriteResponse(*Response, interface{}) error
|
||||||
|
Close() error
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
On the server side, we then changed two internal function signatures to accept
|
||||||
|
the <code>ServerCodec</code> interface instead of our existing
|
||||||
|
<code>gob.Encoder</code>. Here's one of them:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
func sendResponse(sending *sync.Mutex, req *Request,
|
||||||
|
reply interface{}, enc *gob.Encoder, errmsg string)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
became
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
func sendResponse(sending *sync.Mutex, req *Request,
|
||||||
|
reply interface{}, enc ServerCodec, errmsg string)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
We then wrote a trivial <code>gobServerCodec</code> wrapper to reproduce the
|
||||||
|
original functionality. From there it is simple to build a
|
||||||
|
<code>jsonServerCodec</code>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
After some similar changes to the client side, this was the full extent of the
|
||||||
|
work we needed to do on the RPC package. This whole exercise took about 20
|
||||||
|
minutes! After tidying up and testing the new code, the
|
||||||
|
<a href="http://code.google.com/p/go/source/diff?spec=svn9daf796ebf1cae97b2fcf760a4ab682f1f063f29&r=9daf796ebf1cae97b2fcf760a4ab682f1f063f29&format=side&path=/src/pkg/rpc/server.go">final changeset</a>
|
||||||
|
was submitted.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
In an inheritance-oriented language like Java or C++, the obvious path would be
|
||||||
|
to generalize the RPC class, and create JsonRPC and GobRPC subclasses. However,
|
||||||
|
this approach becomes tricky if you want to make a further generalization
|
||||||
|
orthogonal to that hierarchy. (For example, if you were to implement an
|
||||||
|
alternate RPC standard). In our Go package, we took a route that is both
|
||||||
|
conceptually simpler and requires less code be written or changed.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
A vital quality for any codebase is maintainability. As needs change, it is
|
||||||
|
essential to adapt your code easily and cleanly, lest it become unwieldy to work
|
||||||
|
with. We believe Go's lightweight, composition-oriented type system provides a
|
||||||
|
means of structuring code that scales.
|
||||||
|
</p>
|
@ -102,7 +102,7 @@ Guided tours of Go programs.
|
|||||||
|
|
||||||
<h4>Language</h4>
|
<h4>Language</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="http://blog.golang.org/2010/04/json-rpc-tale-of-interfaces.html">JSON-RPC: a tale of interfaces</a></li>
|
<li><a href="/doc/articles/json_rpc_tale_of_interfaces.html">JSON-RPC: a tale of interfaces</a></li>
|
||||||
<li><a href="/doc/articles/gos_declaration_syntax.html">Go's Declaration Syntax</a></li>
|
<li><a href="/doc/articles/gos_declaration_syntax.html">Go's Declaration Syntax</a></li>
|
||||||
<li><a href="/doc/articles/defer_panic_recover.html">Defer, Panic, and Recover</a></li>
|
<li><a href="/doc/articles/defer_panic_recover.html">Defer, Panic, and Recover</a></li>
|
||||||
<li><a href="/doc/articles/concurrency_patterns.html">Go Concurrency Patterns: Timing out, moving on</a></li>
|
<li><a href="/doc/articles/concurrency_patterns.html">Go Concurrency Patterns: Timing out, moving on</a></li>
|
||||||
|
Loading…
Reference in New Issue
Block a user