This could probably have been a blog post but I figured that I might try posting it here this time.
There was a thread recently that discussed examples of web applications. As far as I know, there is no preferred way of structuring your web application, although some variants might be more idiomatic than others. A couple of examples came up and I started checking them out to look for similarities. I believe that one of the strengths of Go is that you can choose whatever way that solves the particular problem you are having. Still though, it might be fun to see what people tend to go with
Starting out from scratch, your service will most likely fit into the
main.go. Handlers, middleware and all.
As your application starts exposing multiple endpoints, you might at some point want to extract your endpoints to separate *.go-files. Either you create a single
handlers.go or you have one file for each resource:
groups.go main.go users.go
Note that this will make
go run main.go fail and you might instead use the
go build && ./app approach.
Now, many (if not all) projects I have looked at prefer to move the resource files into a
main.go server/ groups.go users.go
At this point, I would like to point out some things that are common enough to consider general practice.
At this point you might want to start persisting your posts, users or what you may have. Almost every application I have looked at will create a root-level package that contains your storage implementation.
Applications that need additional configuration will have a root-level directory containing json, yaml, xml or even *.go files containing structs that are initialized from environment variables in the package
Templates will also be located at root-level in its own package.
Things that are common enough to be mentioned are:
utility seems to be popular as it exists in many of the popular applications I have looked at.
Some of the apps will also have the
model package containing their domain objects.
So let’s say we need a database, configuration as well as templates, our project will look something like this:
configuration/ database/ main.go server/ groups.go users.go templates/
Now, some of the applications provide a command-line interface or similar applications. Let’s create a
cli package at root-level.
cli/ main.go configuration/ database/ main.go server/ templates/
By keeping a
main.go in the root-level, to me this signals that there is a notion of a primary application. Is it our cli or the server? Some projects move the root-level
server while others create a
cmd/ directory containing the supporting applications.
cmd/ cli/ main.go configuration/ database/ server/ main.go templates/
cli/ main.go configuration/ database/ server/ main.go templates/
If we look closer at the
server package, several of the applications create a
router.go to extract functionality from
main.go. You might even find apps that create separate packages within
cli/ main.go configuration/ database/ server/ middleware/ router.go main.go templates/
Obviously, not all web applications I have looked at look the same but by normalizing package names and squinting a bit, there seems to be some common ways to structure web applications in Go.
If you would like to check out the web applications for yourself, these are some of the examples I have used when doing this post. Note that some of these are other permutations of the ones I have listed above.
These are the ones I managed to find (as well as a few smaller applications that fit into some of these “archetypes”.
Do you agree with my findings? Do you know of any other applications that won’t fit into any of these examples? I would be happy to update this post based on your observations.