I have this structure:
├── app
│ ├── app.go
│ ├── handler
│ │ ├── common.go
│ │ └── users.go
│ ├── model
│ │ └── model.go
│ └── queries
│ └── queries.go
├── config
│ └── config.go
└── main.go
All my queries (SQL ones) are in queries.go
:
queries.go:
package queries
const (
QueryFindUser = `SELECT * FROM users WHERE id=$1` // <------ HERE
)
users.go:
package handler
import (
"GO_APP/app/model"
"GO_APP/app/queries"
"fmt"
"net/http"
"strconv"
"github.com/julienschmidt/httprouter"
_ "github.com/jinzhu/gorm/dialects/postgres"
"github.com/jmoiron/sqlx"
)
var db *sqlx.DB
// getUserOr404 gets a User instance if exists, or respond the 404 error otherwise
func getUserOr404(db *sqlx.DB, id int, w http.ResponseWriter, r *http.Request) (*model.User, error) {
user := model.User{}
err := db.Get(&user, queries.QueryFindUser, id) // <----- Here
return &user, err
}
If I use QueryFindUser
(capital first letter) then it will become exportable to all the other packages. But I don't want this to be accessible by say config/config.go
I want it to be restricted to handler
's modules only exlcluding the model/model.go
.
If I declare queryFindUser
this will be limited to the package queries
only and then I won't be able to use it anywhere.
How to solve this thing? Without making it exportable to every other package. I am quite new to golang/java and this issue will be same in java as well. So what to do in this case? If you can provide resources that will also be helpful to me.
CodePudding user response:
Access permission to identifiers is not so fine grained that you can specify who you're granting access. And there's no need. This would unnecessarily complicate both the uses (source code) and the implementation (compilation time, compiled package object and executable binary size).
If you want to give access to a specific package only, easiest is to merge the packages and make the identifiers unexported.
If you want to give access to multiple packages or the package would get unpleasantly big, you may use internal packages. Internal packages were introduced so you can break "big" packages into multiple, smaller ones, and still keep the implementation detail hidden and protected from the "outside" (from other packages).
Internal packages may define exported identifiers, but access to them is only allowed to the "internal group".
For example:
├── app
│ ├── app.go
│ ├── handler
│ │ ├── internal
│ │ │ ├── queries
│ │ │ │ └── queries.go
│ │ │ └── foo
│ │ │ └── foo.go
│ │ ├── users.go
│ │ ├── common.go
│ │ └── users.go
│ └── model
│ └── model.go
├── config
│ └── config.go
└── main.go
In this example the queries
package is accessible by the handler
package and by the foo
package, but is not accessible by the model
or config
packages.
In general, internal packages (packages that are inside a folder that has an internal
folder in their path) can only be imported from packages rooted at the parent of the internal
folder.
See related questions: