project-layout
project-layout copied to clipboard
Internal app/pkg Directory Clarification
I was wondering what the internal/app
directory was for, exactly. The README.md says:
Put your actual application code in the
/internal/app
directory
What does it mean by your "actual application code"? I thought that application code goes in the /cmd/<app_name>/
directory. And if it's not part of the main package, shouldn't it then, by definition, be a package that belongs in either /pkg/
or /internal/pkg/
?
I've been placing internal packages directly in the /internal/
directory, and it's been working out well. I know this repo is simply a suggestion, and I might continue to do what I've been doing, but it would be awesome if you could explain to me why you chose the way that the docs suggest, as it might be better than my way for reasons I don't yet know. Thanks!
Keep doing what works for you. This is a set of layout patterns that you are free to use or not to use :-) Using /internal/pkg
is about consistency if you use the /pkg
pattern. The public shared code goes in '/pkg' and the private shared code goes in /internal/pkg
.
With the app code you can put it all in /cmd/<app_name>
, but then all of your app code will be importable. It might be ok for you. A number of Go repos use a very slim main.go in their /cmd/<app_Name>
directory importing everything they need from other places. Here's an example: https://github.com/heptio/ark/blob/master/cmd/ark/main.go There their app imports are all public packages (coming from their repo's /pkg
directory). If you have non-public packages you'd import them from your /internal/pkg
. You can also import code from /internal/app
.
So what's the difference between /internal/app
and /internal/pkg
? The /internal/pkg
code represents private packages you use across multiple apps in your repo. If you have only one app/cmd then you don't have to worry about it :-)
`/internal/app' -> your private / non-importable application code you don't share across multiple apps in your repo.
/internal/pkg
-> your private / non-importable packages you share across multiple apps in your repo.
Lets say you have two apps, you might have something like this then:
-
/cmd/app_one
(main.go
imports your app package from/internal/app/app_one
) -
/cmd/app_two
(main.go
imports your app package from/internal/app/app_two
) -
/internal/app/app_one
-
/internal/app_/app_two
-
/internal/pkg/shared_package
(might be used in/internal/app/app_one
and/internal/app/app_two
or directly in/cmd/app_one
and/cmd/app_two
)
If you have a simple project and you don't care about controlling visibility in your code at that level don't worry about any of that :-) Keep it simple. Don't add the complexity you don't need.
@kcq Sounds good! Thanks for the clarification.
I'll reopen it, so it's a bit easier to discover this discussion in case others have the same question :)
I'm kind of struggling with the same thing, and what I read here confirms at least that the intent of the internal
directory is what I'd expected it to be. However I don't understand how to import the internal packages in my cmd
app
See also https://stackoverflow.com/questions/55898667/how-should-i-import-my-own-internal-packages-in-go , which somehow only seems to attract "you're doing it wrong, stop resisting", without actually any helpful answers.
I don't understand the toxicity either... It's really hard to grasp for people coming from other package managers. I'm still not sure I understand :( I ended up putting my whole project under $GOPATH and importing the internals this way projectName/internal/app/internalPkg
I guess if you want to organize this project with your other git projects you've got to fiddle with your paths :/
why not put internal/pkg/* to internal director to short the import path. in the current suggested layout, only two directory locate in internal/, this shoud be confuse