<p>Hello!</p>
<p>My colleagues and I are planning to build an image sharing service (for educational purposes). I've built something similar with NodeJS already and really don't want to go back to callback hell and that's why I wanted to try Go this time (and because it seems more structured to me).
Some questions came up during the past 4-5 days while we were planning and I thought I could ask you :)</p>
<ol>
<li><p>Is Go suitable for writing a web server for serving webpages, images, etc.?</p></li>
<li><p>I used a method in NodeJS, where I would fetch all user related data when a user wanted to see his profile, and then put all the data into a json called "user". In HTML/Jade I then included this data like #{user.name} (you can find it <a href="https://gist.github.com/mkocs/c44f33177357f8d01946">here</a>) and then the correct username would show up. Could I achieve something similar in Go or would I have to take a different approach? And if so, what would that approach be?</p></li>
<li><p>Are there any databases that work especially well with Go? I read a post about the first stable version of the RethinkDB driver. Is RethinkDB worth a try? I also thought about using PostgreSQL or something similar.</p></li>
</ol>
<p>Thanks in advance for answering my questions :)</p>
<p>edit: All my questions have been answered. Thank you very much :)</p>
<hr/>**评论:**<br/><br/>roveboat: <pre><blockquote>
<p>Is Go suitable for writing a web server for serving webpages, images, etc.?</p>
</blockquote>
<p>Yes. Go is pretty much designed to write servers.</p>
<blockquote>
<p>I used a method in NodeJS, where I would fetch all user related data when a user wanted to see his profile, and then put all the data into a json called "user". In HTML/Jade I then included this data like #{user.name} (you can find it here) and then the correct username would show up. Could I achieve something similar in Go or would I have to take a different approach? And if so, what would that approach be?</p>
</blockquote>
<p>This is called templating and Go has a <a href="http://golang.org/pkg/text/template/">built-in</a> templating library (there's also one that handles all the HTML quirks for you). So, yes. You might want to take a look at the various web frameworks, though, to make it a bit easier. I'm digging <a href="https://github.com/gin-gonic/gin">gin</a> at the moment, but <a href="http://www.gorillatoolkit.org/">gorilla</a> is pretty popular too.</p>
<blockquote>
<p>Are there any databases that work especially well with Go? I read a post about the first stable version of the RethinkDB driver. Is RethinkDB worth a try? I also thought about using PostgreSQL or something similar.</p>
</blockquote>
<p>This depends on your use case. If you need ACID, Postgres is good. If you need horizontal scaling, RethinkDB could be worth a shot. Some of the db libraries are a bit quirky due to Go's own quirks (hello casting to interface{}), but quite workable in my experience.</p></pre>mko31: <pre><p>Thank you very much! I found the templating library only a few minutes after posting this.
Gin looks quite promising. I just found out how to use Go workspace (GOPATH, etc.) and will try some things :)</p></pre>roveboat: <pre><p>As a tip for GOPATH, I'd recommend doing it <em>exactly</em> like they suggest - one directory (your GOPATH), under which there is the src/ directory containing all your different projects.</p></pre>ZenSwordArts: <pre><ol>
<li>I'd say Go is pretty much made for purposes like this. So go ahead :)</li>
<li>If you mean if Go has html templating then yes it has.. look <a href="http://astaxie.gitbooks.io/build-web-application-with-golang/content/en/07.4.html" rel="nofollow">here</a>. There are also 3rd party templating libraries just a quick googling away.</li>
<li>Which database to choose depends on your requirements and your knowledge of the various implementations. The major ones (mysql, postgres...) are all supported sufficiently in go. </li>
</ol></pre>mko31: <pre><p>Thanks a lot for taking the time to answer my questions :)</p></pre>nindalf: <pre><p>Hello! Go is a great language to write web servers thanks to the excellent <a href="http://golang.org/pkg/net/http/" rel="nofollow"><code>net/http</code></a> package in the standard library.</p>
<ol>
<li>The <a href="http://golang.org/pkg/net/http/#ServeFile" rel="nofollow">ServeFile</a> and <a href="http://golang.org/pkg/net/http/#FileServer" rel="nofollow">FileServer</a> are probably the methods you're searching for. I used both to make a Go version of woof - <a href="https://github.com/nindalf/goof/" rel="nofollow">goof</a> in a couple of hundred lines. (Code is messy at the moment, sorry).</li>
<li>As others have mentioned, there is <a href="http://golang.org/pkg/html/template/" rel="nofollow"><code>html/template</code></a>, though I think the general pattern is to create an API in Go and write the client in a JS framework.</li>
<li>There are good drivers for all the major databases. If you want to keep it simple you could go with a file-based KV store like <a href="https://github.com/boltdb/bolt" rel="nofollow">bolt</a>.</li>
</ol>
<p>Apart from these questions I'd like to add that Go is really simple to learn. Most of the people who try the language report that they're productive in a week. I think it takes a little longer to learn to write idiomatic Go code, but it'll come with time. If there's anything else you'd like to ask, be it about conventions, or the preferred text editors/plugins or example projects, I'd be happy to help :)</p></pre>mko31: <pre><p>Thank you for answering :)</p>
<p>I've been playing around with Go yesterday and today and just found out how to work with the Go workspace and now this seems quite easy...I guess. But creating a simple HTTP server with routes at least takes less lines of code than in Node.
Also thank you for offering your help :)</p></pre>nindalf: <pre><p>Since you're starting out with http in Go, allow me to offer a couple of points</p>
<ul>
<li>Stick to the standard library. A lot of libraries offer a lot of features, but they break the simple and effective <a href="http://golang.org/pkg/net/http/#HandlerFunc" rel="nofollow"><code>http.HandlerFunc</code></a> interface. Its best to stick to this, IMO.</li>
<li>If you're looking for more features in your router, look at the <a href="http://www.gorillatoolkit.org/pkg/mux" rel="nofollow"><code>gorilla/mux</code></a> library.</li>
<li>I think its a good idea to have some bits of middleware. If you've used Express.js you'd be familiar with this concept. Its easy to implement with the <code>http.HandlerFunc</code> interface. I did it in a recent project <a href="https://github.com/nindalf/linkto/blob/master/middleware.go" rel="nofollow">here</a></li>
</ul>
<p>I hope this helps. If you don't mind my asking, which text editor are you using?</p></pre>AnimalMachine: <pre><p>Bolt looks pretty cool. I was thinking of using sqlite for something I'm working on, but I might just use that instead. Thanks!</p></pre>AnimalMachine: <pre><p>Setting up a web server is super easy in Go. What I've done for my blog is use html/template for generating pages that get cached. Then I use nginx to serve static content and pull requests from the go server for blog content as necessary. Pretty easy to do.</p>
<p>Here's a snippit from a test project I was doing to serve customized fBm perlin/opensimplex noise as images to a leafleft js map. </p>
<pre><code> import (
"fmt"
"time"
"net/http"
)
// ... now in a main function ...
// register the handlers
http.HandleFunc("/api/map/tile", mapTileHandler)
http.HandleFunc("/api/noise/setJSON", noiseSetJSONHandler)
http.HandleFunc("/", mainPageHandler)
// start the serve loop
go func() {
for {
fmt.Printf("Starting web server at %s.", serveAddress)
s := &http.Server{
Addr: serveAddress,
Handler: nil,
ReadTimeout: 120 * time.Second,
WriteTimeout: 120 * time.Second,
MaxHeaderBytes: 1 << 20,
}
err := s.ListenAndServe()
if err != nil {
fmt.Printf("Web server failed with an error; will restart. %v", err)
}
}
}()
</code></pre>
<p>An example of a handler is the main page handler that serves static content:</p>
<pre><code>func mainPageHandler(w http.ResponseWriter, req *http.Request) {
resourcePath := WebRoot + req.URL.Path
if req.URL.Path == "/" {
resourcePath = WebRoot + mainHTMLPage
}
fmt.Printf("serving static file => %s\n", resourcePath)
http.ServeFile(w, req, resourcePath)
}
</code></pre>
<p>Real easy. You'll find a ton of tutorials on it. So that should give you an idea for question #1.</p>
<p>As for JSON, that's also easily done. You can serialize/deserialze structs super easy:</p>
<pre><code>import (
"encoding/json"
)
type APIResponse struct {
Success bool
}
// ... now in a handler function with w as a http.ResponseWriter ...
output := APIResponse{Success: true}
outputStr, _ := json.Marshal(output)
w.Write(outputStr)
</code></pre>
<p>Deserializing is pretty much just as easy.</p>
<p>So for question #2, I would build a struct for your user data, populate it in normal Go code, then just marshal it out to JSON per above. Look at <a href="http://golang.org/pkg/encoding/json/#Marshal" rel="nofollow">encoding/json</a> docs for further details.</p>
<p>Sadly, I don't have enough experience to answer #3 for you.</p></pre>mko31: <pre><p>Thank you for the little guide :)
I just used it to play around a little and this works quite well, but I think I'll certainly face some problems in the near future, trying to figure things and features out, etc.</p>
<p><a href="https://github.com/mkocs/imgcat" rel="nofollow">Github</a></p></pre>drvd: <pre><ol>
<li><p>This is not a serious question. Or is it?</p></li>
<li><p>Totally the same. Use package html/template</p></li>
<li><p>Doesn't matter, all are good. Postgres, MySQL, MongoDB, whatever.</p></li>
</ol></pre>mko31: <pre><blockquote>
<ol>
<li>This is not a serious question. Or is it?
It was. But I already supposed it was made for web servers, etc. Thank you for answering :)</li>
</ol>
</blockquote></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传