33

My application uses json configuration files and other resources. Where should I place them in my project hierarchy? I could not find the answer in http://golang.org/doc/code.html (How to Write Go Code)

Upd: The question is not about automatic distribution of resources with application but much simpler: Where should I keep my resources in project hierarchy? Is there some standard place anyone expects them to be?

Alexander Ponomarev
  • 2,598
  • 3
  • 24
  • 31
  • 3
    Wherever you like? As Go produces (almost) standalone binaries it is basically an unanswerable question. The binary must find the resources, so provide a command line flag (or environment variable, or a convention, or whatever) which points the binary to you resources. – Volker Oct 25 '13 at 10:11
  • 2
    @Volker all he wants is an assets management solutions (which most decent languages already have). There is no such thing as of now but there is a request for it https://code.google.com/p/go/issues/detail?id=3035 – Mateusz Dymczyk Oct 25 '13 at 10:14
  • 1
    @MateuszDymczyk Most "decent" languages don't include any kind of asset packaging tools in their standard library whatsoever. There is no "one" way to do this. If you want to deliver configuration files along with your binary, include them in the tarball/zip and perhaps write a Makefile or small install script that puts everything in place/allow the user to specify with a flag. – elithrar Oct 25 '13 at 10:20
  • @Mateusz I know, but I doubt this will happen somewhen early. You name decent languages: How does C or C++ handle this? If the solution would be easy it should be simple to copy the approach C takes on this problem. – Volker Oct 25 '13 at 10:21
  • @volker There is no language-standard way for neither C nor C++ to handle assets. There are some programming environments that do have standards, but they are not universal. – Vatine Oct 25 '13 at 10:25
  • @MateuszDymczyk Actually the question is not about assets management, I understand that I should copy my resource by my own. I meant is there some standard place where resources should be kept in project. Where anyone expects the resources should be. – Alexander Ponomarev Oct 25 '13 at 10:44
  • Oh then sorry. In that case well I don't think there's a well established standard for that but please do correct me if I'm wrong :-) – Mateusz Dymczyk Oct 25 '13 at 15:22
  • I would but it beside the code in a data/ directory. Just make sure to specify the param file by an environment environment. – user983716 Oct 25 '13 at 15:30
  • 1
    @AlexanderPonomarev in java there is the concept of classpath so all resources inside this classpath can be reached via the api. or prog often considers the current path as base to load resources. – taharqa Oct 25 '13 at 16:25
  • 3
    @AlexanderPonomarev - Did you ever find a decent answer to this question, either through other sources or your own personal experience? I have the same question that you asked, but it seems like NO ONE here really understands what you were asking. They're all talking about how to load files at runtime, or bundle them within a static executable. I just want to know where to put them **in source control**, and how best to copy them to the `/bin` folder when building (e.g. `go` tool, `make`?). Basically, does Go have any concept similar to `src/main/resources` in a Maven-like Java project? – Steve Perkins Dec 30 '15 at 23:00
  • 1
    @steve-perkins, no :) it seems to me that there is really no specific place for resources. – Alexander Ponomarev Jan 02 '16 at 12:31

2 Answers2

13

There is no single correct answer, nor are there any strong conventions assumed or enforced by any Go tooling at this time.

Typically I start by assuming that the files I need are located in the same directory from where the program will be run. For instance, suppose I need conf.json for myprog.go; then both of those files live together in the same directory and it works to just run something like

go build -o myprog && ./myprog

When I deploy the code, the myprog binary and conf.json live together on the server. The run/supervisor script needs to cd to that directory and then run the program.

This also works when you have a lot of resources; for instance, if you have a webserver with JS, CSS, and images, you just assume they're relative to cwd in the code and deploy the resource directories along with the server binary.

Another alternative to assuming a cwd is to have a -conf flag which the user can use to specify a configuration file. I typically use this for distributing command-line tools and open-source server applications that require a single configuration file. You could even use an -assets flag or something to point to a whole tree of resource files, if you wanted.

Finally, one more approach is to not have any resource files. go-bindata is a useful tool that I've used for this purpose -- it just encodes some data as bytes into a Go source file. That way it's all baked into your binary. I think this method is most useful when the resource data will rarely or never change, and is pretty small. (Otherwise you're going to be shipping around huge binaries.) One (kind of silly) example of when I've used go-bindata in the past was for baking a favicon into a really simple server which didn't otherwise require any extra files besides the server binary.

Caleb Spare
  • 497
  • 2
  • 11
1

For static resource it might be the most convenient solution to include them in the binary similar to resources in Java. Newer Go version, at least 1.18 are providing the //go:embed directive to include content:

import (
    _ "embed"
)

//go:embed myfile.txt
var myfile string

You can now use myfile in your code. E.g. IntelliJ provides also support for this.

There are also other options to include the content, e.g. as binary or dynamically, see the link.

k_o_
  • 5,143
  • 1
  • 34
  • 43