<p>I have enjoyed tinkering with Go so I decided to try to write something non-trivial: bindings for the <a href="https://www.rememberthemilk.com/services/api/" rel="nofollow">Remember The Milk API</a>. Once I get this done, I have an idea for an app which will manage related tasks, but I'm not there yet.</p>
<p>I made great progress in a reasonable amount of time, and am able to log into the server and send echo pings. I started to notice some annoying repetition, though, and was hoping that you folks could help me simplify my code.</p>
<p>I have attached a few snippets of code below for examples. The whole thing (as far as I've gotten) is on the first-pass branch at <a href="https://github.com/mathuin/rtm/" rel="nofollow">https://github.com/mathuin/rtm/</a> if you would like to see more.</p>
<p>Here are two methods, which implement the API methods rtm.test.echo and rtm.test.login, respectively:</p>
<pre><code>// Echo should echo the sent values
func (c *Client) Echo(p string) (EchoResp, error) {
var m echoResp
r := Request{"method": "rtm.test.echo", "ping": p}
if err := c.doReqURL(c.url(c.urlBase(), r), &m); err != nil {
return EchoResp{}, err
}
return m.RSP, m.RSP.IsOK()
}
// Login reports what user if any is logged in.
func (s *Session) Login() (LoginResp, error) {
c := s.parent
var m loginResp
r := Request{"method": "rtm.test.login", "auth_token": s.Token}
if err := c.doReqURL(c.url(c.urlBase(), r), &m); err != nil {
return LoginResp{}, err
}
return m.RSP, m.RSP.IsOK()
}
</code></pre>
<p>Very similar! The second one requires authentication, so it's a session method. The first one has an argument. Other than that, they look very similar.</p>
<p>Here are the response structs and their parent structs:</p>
<pre><code>type errorResp struct {
Code string `json:"code"`
Message string `json:"msg"`
}
func (e *errorResp) Error() string {
return fmt.Sprintf("code %s, message %s\n", e.Code, e.Message)
}
type baseResp struct {
Status string `json:"stat"`
Error errorResp `json:"err"`
}
func (b *baseResp) IsOK() error {
if b.Status == "fail" {
return &b.Error
}
return nil
}
// EchoResp is the expected response from rtm.test.echo
type EchoResp struct {
baseResp
Ping string `json:"ping"`
}
type echoResp struct {
RSP EchoResp `json:"rsp"`
}
// LoginResp is the expected response from rtm.test.login
type LoginResp struct {
baseResp
User struct {
ID string `json:"id"`
Username string `json:"username"`
} `json:"user"`
}
type loginResp struct {
RSP LoginResp `json:"rsp"`
}
</code></pre>
<p>Also very similar, and very repetitive. </p>
<p>What I'm looking for from you folks are suggestions on how to reduce duplication in structs and methods, or confirmation that this is as good as it's going to get. Right now, either would be appreciated!</p>
<p>Thank you in advance for your help!</p>
<p>Jack.</p>
<hr/>**评论:**<br/><br/>EclecticMind: <pre><p>Why include error if there isn't one? Return an error if it exists, otherwise return the data being requested. Use status codes to help the client react accordingly. </p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传