project-layout icon indicating copy to clipboard operation
project-layout copied to clipboard

Internal app/pkg Directory Clarification

Open rburmorrison opened this issue 6 years ago • 6 comments

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!

rburmorrison avatar Jul 15 '18 23:07 rburmorrison

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 avatar Aug 18 '18 18:08 kcq

@kcq Sounds good! Thanks for the clarification.

rburmorrison avatar Aug 26 '18 00:08 rburmorrison

I'll reopen it, so it's a bit easier to discover this discussion in case others have the same question :)

kcq avatar Aug 26 '18 06:08 kcq

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.

ComaVN avatar Apr 29 '19 11:04 ComaVN

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 :/

ezmicken avatar Nov 13 '19 20:11 ezmicken

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

colin404 avatar Jun 12 '20 08:06 colin404