medium-com-efpmux.txt (14373B)
1 [1]Open in app 2 3 Sign up 4 5 [3]Sign in 6 7 [4] 8 [5][ ] 9 [6] 10 Write 11 [7] 12 13 Sign up 14 15 [9]Sign in 16 17 [1] 18 19 Go Project Layout 20 21 [11] 22 Kyle C. Quest (Q) 23 [12] 24 golang-learn 25 26 [13]Kyle C. Quest (Q) 27 28 · 29 30 [14]Follow 31 32 Published in 33 [15] 34 35 golang-learn 36 37 · 38 5 min read 39 · 40 Sep 11, 2017 41 42 -- 43 44 11 45 46 Listen 47 48 Share 49 50 You went through the ‘[19]Tour of Go’, played with [20]https://play.golang.org/ 51 and you feel you are ready to write some code. Great! However, you are not sure 52 how to structure your projects. Can you put your code anywhere you want? Is 53 there a standard way to organize your code? What if you need to have multiple 54 application binaries? What does it mean to be ‘go gettable’? These are some of 55 the questions you’ll be asking yourself. 56 57 First, you have to understand Go workspaces. ‘[21]How to Write Go Code’ is a 58 good place to start. By default, Go keeps and expects all code in a single 59 workspace. This place is identified by the GOPATH environment variable. What 60 does it mean for you? It means you have to put your code in the default 61 workspace or you have to change the GOPATH variable to point to your own 62 location. Either way the actual source code for your project needs to be placed 63 in the src subdirectory (e.g., $GOPATH/src/your_project or $GOPATH/src/ 64 github.com/your_github_username/your_project). Technically your project doesn’t 65 have to be in a workspace if you don’t import external packages and you use 66 relative imports for your own code, but it’s not recommended. It’s fine for a 67 toy project or a PoC though. Go v1.11 does introduce the concept of [22]modules 68 that allows you to have your project code outside of your GOPATHwithout the 69 import restrictions mentioned above, but it’s still an experimental feature at 70 this point in time. 71 72 You have your project directory in the right place. What’s next? 73 74 For a PoC or a very small project where you are the only one writing the code 75 using a single main.go file in the root directory for your project is enough. 76 If you know your project will be large enough or it’ll go into production and 77 others will be contributing to it you should consider adopting, at least, some 78 of the project layout patterns outlined here. 79 80 There are a number of project layout patterns emerging in the Go ecosystem. The 81 two most common patterns are the cmd and pkg directories. You should adopt 82 these patterns unless you have a tiny project. 83 84 The cmd layout pattern is very useful when you need to have more than one 85 application binary. Each binary gets a subdirectory (e.g., your_project/cmd/ 86 your_app). This patterns also helps you keep your project/package ‘go 87 gettable’. What does it mean? It means you can use the go get command to fetch 88 (and install) your project, its applications and its libraries (e.g., go get 89 github.com/your_github_username/your_project/cmd/appxg). You don’t have to 90 separate the application files. You’ll be able to build each application with 91 the right set of go build flags, but go get will no longer work because it will 92 not know which application code to build. The official [23]Go tools is one 93 example of the cmd layout patter. A number of other well known projects use the 94 same pattern: [24]Kubernetes, [25]Docker, [26]Prometheus, [27]Influxdb. 95 96 The pkg layout pattern is also pretty popular. For new Go developers it’s one 97 of the most confusing package structure concepts because Go workspaces have a 98 directory with the same name and that directory has a different purpose (it’s 99 used to store object files for the packages the Go compiler builds). The pkg 100 directory is where you put your public libraries. They can be used internally 101 by your application. They can also be used by external projects. This is an 102 informal contract between you and other external users of your code. Other 103 projects will import these libraries expecting them to work, so think twice 104 before you put something here. Many well known projects use this pattern: [28] 105 Kubernetes, [29]Docker, [30]Grafana, [31]Influxdb, [32]Etcd. 106 107 Some of the libraries in the pkg directory are not always for public use. Why 108 is that? It happens because many existing Go projects predate the ability to 109 hide internal packages. Some projects put those internal libraries in the pkg 110 directory to be consistent with the rest of their code structure. Other 111 projects put their internal libraries into separate directories outside of the 112 pkg directory. [33]Go 1.4 introduce an ability to hide code using internal 113 directories. What does it mean? If you put your code in an ‘internal’ directory 114 no external project will be able to import that code. Even other code in your 115 project won’t be able to access this internal code if it lives outside of its 116 parent directory. This feature is not widely used yet because it’s relatively 117 new; however, it’s extremely valuable as an additional layer of control (in 118 addition to the lowercase and uppercase function visibility rules in Go). A 119 number of new and well known projects use this pattern: [34]Dep, [35]Docker, 120 [36]Nsq, [37]Go Ethereal, [38]Contour. 121 122 The internal directory is the place to put your private packages. You can 123 optionally add additional structure by separating your internally shared 124 libraries (e.g., your_project/internal/pkg/your_private_lib) and the 125 application code you don’t want others to import (e.g., your_project/internal/ 126 app/your_app). When you put all of you private code in the ‘internal’ directory 127 the application code in the cmd directory will be limited to small files that 128 define the ‘main’ function for the corresponding application binaries. 129 Everything else will be imported from the internal or pkg directories ([39]ark, 130 from Heptio, and [40]loki, from Grafana, are good examples of this tiny main 131 package pattern). 132 133 What if you forked and modified a piece of an external project? Some projects 134 put that code in the pkg directory, but it’s better to put it in the 135 third_party top level directory to keep your code separate from the code you 136 borrowed from others. 137 138 What about the external packages you import in your projects? Where do they go? 139 You have several options. You can keep them outside of your project. The 140 packages you install with go get will be saved in your Go workspace. It works 141 most of the times, but depending on the package it might be brittle and 142 unpredictable because when somebody else tries to build your project they might 143 get a backward incompatible version of that package. The solution is 144 ‘vendoring’. With ‘vendoring’ you freeze your dependencies by committing them 145 with your project. [41]Go 1.6 introduced a standard way to ‘vendor’ external 146 packages (it was an experimental feature in Go 1.5). Put your external package 147 in the vendor directory. How is this different from the third_party directory? 148 If you import and use external code as-is then it should go into the vendor 149 directory. If you are using a modified version of an external project then put 150 it in the third_party directory. 151 152 If you want to learn more about the project structure used by other Go projects 153 read the ‘[42]Analysis of the Top 1000 Go Repositories’. It’s a little dated, 154 but it’s still useful. 155 156 A real project will have additional directories too. You can use this layout 157 template as a starting point for your Go projects: [43]https://github.com/ 158 golang-standards/project-layout. It covers the Go project layout patterns 159 described in this blog post and it includes a number of supporting directories 160 you’ll need to have. 161 162 Now it’s time to write some code! If you don’t have Go installed take a look at 163 this [44]quick setup guide for Mac OS X (setup on other platforms is similar). 164 Go through the ‘[45]Tour of Go’ if you haven’t done it yet and then read ’[46] 165 50 Shades of Go’ to learn about the most common gotchas in Go, which will save 166 you quite a bit of time when you start writing and debugging code. 167 168 [47] 169 Golang 170 [48] 171 Go 172 [49] 173 Standards 174 [50] 175 Project Structure 176 177 -- 178 179 -- 180 181 11 182 183 [53] 184 Kyle C. Quest (Q) 185 [54] 186 golang-learn 187 Follow 188 [56] 189 [58] 190 191 Written by Kyle C. Quest (Q) 192 193 [59]358 Followers 194 ·Editor for 195 [60] 196 197 golang-learn 198 199 CTO / Redefining DevOps * Hacker @DockerSlim * @Golang50Shades * Cloud Native * 200 Data * Security 201 202 Follow 203 [62] 204 [64] 205 206 Help 207 208 [65] 209 210 Status 211 212 [66] 213 214 About 215 216 [67] 217 218 Careers 219 220 [68] 221 222 Blog 223 224 [69] 225 226 Privacy 227 228 [70] 229 230 Terms 231 232 [71] 233 234 Text to speech 235 236 [72] 237 238 Teams 239 240 241 References: 242 243 [1] https://rsci.app.link/?%24canonical_url=https%3A%2F%2Fmedium.com%2Fp%2Fe5213cdcfaa2&%7Efeature=LoOpenInAppButton&%7Echannel=ShowPostUnderCollection&source=---two_column_layout_nav---------------------------------- 244 [3] https://medium.com/m/signin?operation=login&redirect=https%3A%2F%2Fmedium.com%2Fgolang-learn%2Fgo-project-layout-e5213cdcfaa2&source=post_page---two_column_layout_nav-----------------------global_nav----------- 245 [4] https://medium.com/?source=---two_column_layout_nav---------------------------------- 246 [6] https://medium.com/m/signin?operation=register&redirect=https%3A%2F%2Fmedium.com%2Fnew-story&source=---two_column_layout_nav-----------------------new_post_topnav----------- 247 [7] https://medium.com/search?source=---two_column_layout_nav---------------------------------- 248 [9] https://medium.com/m/signin?operation=login&redirect=https%3A%2F%2Fmedium.com%2Fgolang-learn%2Fgo-project-layout-e5213cdcfaa2&source=post_page---two_column_layout_nav-----------------------global_nav----------- 249 [11] https://medium.com/@kcq?source=post_page-----e5213cdcfaa2-------------------------------- 250 [12] https://medium.com/golang-learn?source=post_page-----e5213cdcfaa2-------------------------------- 251 [13] https://medium.com/@kcq?source=post_page-----e5213cdcfaa2-------------------------------- 252 [14] https://medium.com/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fsubscribe%2Fuser%2F6aac7a58837&operation=register&redirect=https%3A%2F%2Fmedium.com%2Fgolang-learn%2Fgo-project-layout-e5213cdcfaa2&user=Kyle+C.+Quest+%28Q%29&userId=6aac7a58837&source=post_page-6aac7a58837----e5213cdcfaa2---------------------post_header----------- 253 [15] https://medium.com/golang-learn?source=post_page-----e5213cdcfaa2-------------------------------- 254 [19] https://tour.golang.org/ 255 [20] https://play.golang.org/ 256 [21] https://golang.org/doc/code.html 257 [22] https://github.com/golang/go/wiki/Modules 258 [23] https://github.com/golang/tools/tree/master/cmd 259 [24] https://github.com/kubernetes/kubernetes/tree/master/cmd 260 [25] https://github.com/moby/moby/tree/master/cmd 261 [26] https://github.com/prometheus/prometheus/tree/master/cmd 262 [27] https://github.com/influxdata/influxdb/tree/master/cmd 263 [28] https://github.com/kubernetes/kubernetes/tree/master/pkg 264 [29] https://github.com/moby/moby/tree/master/pkg 265 [30] https://github.com/grafana/grafana/tree/master/pkg 266 [31] https://github.com/influxdata/influxdb/tree/master/pkg 267 [32] https://github.com/coreos/etcd/tree/master/pkg 268 [33] https://golang.org/doc/go1.4#internalpackages 269 [34] https://github.com/golang/dep/tree/master/internal 270 [35] https://github.com/moby/moby/tree/master/internal 271 [36] https://github.com/nsqio/nsq/tree/master/internal 272 [37] https://github.com/ethereum/go-ethereum/tree/master/internal 273 [38] https://github.com/heptio/contour/tree/master/internal 274 [39] https://github.com/heptio/ark/blob/master/cmd/ark/main.go 275 [40] https://github.com/grafana/loki/blob/master/cmd/loki/main.go 276 [41] https://golang.org/doc/go1.6#go_command 277 [42] http://blog.sgmansfield.com/2016/01/an-analysis-of-the-top-1000-go-repositories/ 278 [43] https://github.com/golang-standards/project-layout 279 [44] https://medium.com/golang-learn/quick-go-setup-guide-on-mac-os-x-956b327222b8 280 [45] https://tour.golang.org/ 281 [46] http://devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang/ 282 [47] https://medium.com/tag/golang?source=post_page-----e5213cdcfaa2---------------golang----------------- 283 [48] https://medium.com/tag/go?source=post_page-----e5213cdcfaa2---------------go----------------- 284 [49] https://medium.com/tag/standards?source=post_page-----e5213cdcfaa2---------------standards----------------- 285 [50] https://medium.com/tag/project-structure?source=post_page-----e5213cdcfaa2---------------project_structure----------------- 286 [53] https://medium.com/@kcq?source=post_page-----e5213cdcfaa2-------------------------------- 287 [54] https://medium.com/golang-learn?source=post_page-----e5213cdcfaa2-------------------------------- 288 [56] https://medium.com/m/signin?actionUrl=%2F_%2Fapi%2Fsubscriptions%2Fnewsletters%2F997b4efe98f9&operation=register&redirect=https%3A%2F%2Fmedium.com%2Fgolang-learn%2Fgo-project-layout-e5213cdcfaa2&newsletterV3=6aac7a58837&newsletterV3Id=997b4efe98f9&user=Kyle+C.+Quest+%28Q%29&userId=6aac7a58837&source=-----e5213cdcfaa2---------------------subscribe_user----------- 289 [58] https://medium.com/@kcq?source=post_page-----e5213cdcfaa2-------------------------------- 290 [59] https://medium.com/@kcq/followers?source=post_page-----e5213cdcfaa2-------------------------------- 291 [60] https://medium.com/golang-learn?source=post_page-----e5213cdcfaa2-------------------------------- 292 [62] https://medium.com/m/signin?actionUrl=%2F_%2Fapi%2Fsubscriptions%2Fnewsletters%2F997b4efe98f9&operation=register&redirect=https%3A%2F%2Fmedium.com%2Fgolang-learn%2Fgo-project-layout-e5213cdcfaa2&newsletterV3=6aac7a58837&newsletterV3Id=997b4efe98f9&user=Kyle+C.+Quest+%28Q%29&userId=6aac7a58837&source=-----e5213cdcfaa2---------------------subscribe_user----------- 293 [64] https://help.medium.com/hc/en-us?source=post_page-----e5213cdcfaa2-------------------------------- 294 [65] https://medium.statuspage.io/?source=post_page-----e5213cdcfaa2-------------------------------- 295 [66] https://medium.com/about?autoplay=1&source=post_page-----e5213cdcfaa2-------------------------------- 296 [67] https://medium.com/jobs-at-medium/work-at-medium-959d1a85284e?source=post_page-----e5213cdcfaa2-------------------------------- 297 [68] https://blog.medium.com/?source=post_page-----e5213cdcfaa2-------------------------------- 298 [69] https://policy.medium.com/medium-privacy-policy-f03bf92035c9?source=post_page-----e5213cdcfaa2-------------------------------- 299 [70] https://policy.medium.com/medium-terms-of-service-9db0094a1e0f?source=post_page-----e5213cdcfaa2-------------------------------- 300 [71] https://speechify.com/medium?source=post_page-----e5213cdcfaa2-------------------------------- 301 [72] https://medium.com/business?source=post_page-----e5213cdcfaa2--------------------------------