<p>Good evening,</p>
<p>I'm starting to learn go and wrote a small forum api together with a friend: <a href="https://github.com/dhenkes/forum" rel="nofollow">https://github.com/dhenkes/forum</a></p>
<p>It does not have authentication or validation yet and basically just executes some queries.</p>
<p>We're both inexperienced, never wrote a Go program so the code is quite messy.</p>
<p>How can we improve structure, functions, parameters, etc.?</p>
<p>Every suggestion is welcome.</p>
<p><strong>Update 29.01.2017</strong>: I updated the code (100% on goreportcard) but I'm still open for suggestions.</p>
<hr/>**评论:**<br/><br/>jiimiji: <pre><p><a href="https://goreportcard.com/report/github.com/dhenkes/forum" rel="nofollow">https://goreportcard.com/report/github.com/dhenkes/forum</a></p></pre>dhenkes: <pre><p>Thank you for that site, I didn't even know it existed. I updated the master from dev (master had outdated code) and now it shows 100% everywhere except on the golint (no comments on functions and the mysql driver is imported as blank) and on the license.</p>
<p>I'm still not happy with the structure, so I'm hoping someone has suggestions there.</p></pre>kemitche: <pre><p>So I noticed from the other comment that you saw the <code>golint</code> notice around mysql driver imported as blank.</p>
<p>When I went to look at your code, I saw this <a href="https://github.com/dhenkes/forum/blob/dev/mysql/boards/get.go#L18" rel="nofollow">https://github.com/dhenkes/forum/blob/dev/mysql/boards/get.go#L18</a></p>
<p>That had me do a bit of digging into your sql layer, and I have some suggestions, in no particular order:</p>
<ul>
<li>Get rid of <code>mysql/config.go</code>. It's generally not good practice to store usernames/passwords in source control; usually you want to pass those in at runtime via environment variables, command line arguments, or a config file (json, yaml, toml, or other format) that you read in. (It <em>can</em> be ok to have a <code>config.go</code> with very generic defaults, for dev/testing, but you'll want to be able to override those when you go to some form of productionized environment).</li>
<li>You're creating a <code>*sql.DB</code> object on every db request; that's not generally how you'll want to do it, since establishing the connection is expensive. The golang <code>sql</code> drivers usually know how to do connection pooling, wherein a <em>single</em> <code>*sql.DB</code> will open some number of connections to your DB, then your handlers will use those as needed to make requests. So what you want to do is something like add <code>*sql.DB</code> to your <code>server</code> struct, then have your handlers pass it into your DB functions when they want to make a query. (Doing this also means you only have to run <code>CheckTables()</code> <em>once</em> on startup!)</li>
<li>Once you do the previous, you'll notice that you resolve the "mysql driver imported as blank", since you'll be able to move that to your <code>package main</code>, where you'll be creating your shared <code>*sql.DB</code>. As <code>golint</code> noted, doing the <code>_</code> import in main isn't a major problem.</li>
<li>You also shouldn't really need to do <code>db.Ping()</code> that often; just make the query. <code>db.Ping()</code> is mostly useful to run right after you've constructed your single <code>*sql.DB</code>, as a way to verify your connection info was correct.</li>
<li>If you get bored of building sql commands by hand, look into the <a href="https://github.com/Masterminds/squirrel" rel="nofollow"><code>sqrl</code></a> package; it's really flexible at constructing SQL queries in a way that looks more like <code>go</code>.</li>
</ul>
<p>Also, you can probably drop your <code>utils</code> pkg; the functions there aren't really doing anything - you should be able to call the <code>brcrypt</code> functions directly from your other code.</p>
<p>Finally, <strong>DO NOT RETURN PASSWORDS</strong> (even if it's bcrypted) in the User json. That data should never leave your server/database.</p></pre>dhenkes: <pre><p>Thank you for the suggestions, I will start implementing them as soon as I can.</p>
<p>Is the folder structure ok? I'm still not quite happy with it but we wanted to build it as modular as possible so we could swap out MySQL for MongoDB or Couchbase later down the road if we wanted to.</p></pre>kemitche: <pre><p>Having the handlers split from the mysql / database pkg is a great start.</p>
<p>Swapping down the road will always be some amount of work - there are things you could do now to help (using interfaces instead of concrete structs in your http handlers, for example) but you won't lose much by putting off that sort of switch - it's the same amount of work now vs later, more or less.</p></pre>dhenkes: <pre><p>I already implemented some of your suggestions, the rest will follow tomorrow.</p>
<p>Again thanks for looking over the code.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传