Importing controller in routes using alias

Hi everyone,

I’m working on an Iris Golang project and need help setting up route files with aliases for different controllers. Specifically, I’m trying to use user_controller with an alias in my route definitions, but I’m encountering issues with import paths and module configuration. Any advice or examples on how to correctly set this up would be greatly appreciated!

My project structure looks like this:

Project/
│
├── controllers/
│   └── user_controller.go
│
├── models/
│   └── user.go
│
├── routes/
│   └── user_routes.go
│
└── main.go

Currently my user_route.go code is this

package routes

import (
	"github.com/kataras/iris/v12"
	userController "github.com/my-github-username/cs-api/controllers/user_controller"
)

func UserRoutes(app *iris.Application) {
    app.Get("/users", userController.GetUsers)
    app.Post("/users", userController.CreateUser)
}

It throws this message in terminal

no required module provides package github.com/my-github-username/cs-api/controllers/user_controller; to add it:
        go get github.com/my-github-username/cs-api/controllers/user_controller

But I think it should not be the case

I think you need to create a .mod file, so:

go mod init github.com/my-github-username/cs-api

)

@Yamil_Bracho Thanks for replying. I forgot to mention that I have already created that mod file.

OIK, the just use

userController "controllers/user_controller"

From the docs:

Go programs are organized into packages. A package is a collection of source files in the same directory that are compiled together. Functions, types, variables, and constants defined in one source file are visible to all other source files within the same package.

So you can’t have multiple packages in a single directory (to my knowledge at least). And you can’t import a single .go file like you’re trying to do. And from effective go:

Another convention is that the package name is the base name of its source directory; the package in src/encoding/base64 is imported as "encoding/base64" but has name base64, not encoding_base64 and not encodingBase64.

So based on this, your package should be called controllers and your import should look like this:

import (
	someAlias "github.com/my-github-username/cs-api/controllers"
)

If you really want userController package, you could achieve it with something like this:

| project/
| - controllers/
| -- user/ 
| --- user.go

Then import it like this:

import (
	userController "github.com/my-github-username/cs-api/controllers/user"
)

But it’s usually best to keep it simple to start and this is not idiomatic. Let’s consider the following:

// userController.GetUsers? A bit redundant.
app.Get("/users", userController.GetUsers)
// If you simplify your package to controllers, you get this, which 
// makes more sense to me.
app.Get("/users", controllers.GetUsers)
// Similarly with something like "models" you wouldn't want this:
var user userModels.User
// ... you would want this:
var user models.User

This is supported by the go.dev blog post on package names:

Good package names are short and clear. They are lower case, with no under_scores or mixedCaps. They are often simple nouns, such as:

  • time (provides functionality for measuring and displaying time)
  • list (implements a doubly linked list)
  • http (provides HTTP client and server implementations)

The style of names typical of another language might not be idiomatic in a Go program. Here are two examples of names that might be good style in other languages but do not fit well in Go:

  • computeServiceClient
  • priority_queue

… as well as this section:

Avoid repetition. Since client code uses the package name as a prefix when referring to the package contents, the names for those contents need not repeat the package name. The HTTP server provided by the http package is called Server, not HTTPServer. Client code refers to this type as http.Server, so there is no ambiguity.

It might also benefit you to take a step back and read this if you haven’t already:

That effective go doc I linked is also excellent. In summary: in go it is idiomatic to think heavily about naming to come up with a clear, concise name and import path. Package names match the folder that contains them. Avoid repetition by thinking about package names as prefixes.

1 Like

Hey Thanks for the solution @Dean_Davidson. This worked like charm, really appreciated!