So I just started learning Go yesterday and I have been following a fairly simple tutorial on creating a restful api. I can run the tests and everything but when I try to run the app and have it listen on a part it gives me undefined: App
.
I cannot seem to find the error in this as Initialize and run should be sufficient enough to start the server. The tutorial also has it exactly like this and I followed it carefully.
As clarification I attempt to run the program with go run main.go
and that's what prompts the error.
I also attempted to follow the advice of an answer and ran go run main.go app.go
and I get undefined: getUsers
and it points to the line where it says users, err := getUsers(a.DB, start, count)
. I have added them to my app.go code below.
package main
func main() {
a := App{}
a.Initialize("root", "password", "user")
a.Run(":8080")
}
package main
import (
"fmt"
"log"
"strconv"
"encoding/json"
"net/http"
"github.com/gorilla/mux"
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
type App struct {
Router *mux.Router
DB *sql.DB
}
func (a *App) Initialize(user, password, dbname string) {
connectionString := fmt.Sprintf("%s:%s@/%s", user, password, dbname)
var err error
a.DB, err = sql.Open("mysql", connectionString)
if err != nil {
log.Fatal(err)
}
a.Router = mux.NewRouter()
a.initializeRoutes()
}
func (a *App) initializeRoutes() {
a.Router.HandleFunc("/users", a.getUsers).Methods("GET")
}
func (a *App) Run(addr string) {
log.Fatal(http.ListenAndServe(addr, a.Router))
}
func (a *App) getUsers(w http.ResponseWriter, r *http.Request) {
count, _ := strconv.Atoi(r.FormValue("count"))
start, _ := strconv.Atoi(r.FormValue("start"))
if count > 10 || count < 1 {
count = 10
}
if start < 0 {
start = 0
}
users, err := getUsers(a.DB, start, count)
if err != nil {
respondWithError(w, http.StatusInternalServerError, err.Error())
return
}
respondWithJSON(w, http.StatusOK, users);
}
How do you run it? If with go run
try to pass it all the files:
go run main.go app.go
Or even with asterisk to catch them all:
go run *.go
Another option: build application then run it:
go build -o app && ./app
Just to add to @Eugene Lisitsky's answer.
If *.go
doesn't work for you for some reason you'll have to manually list all files on which your program depends.
That means that besides main.go
and app.go
you also need to list files that define the getUsers
, respondWithError
and respondWithJSON
functions, and if the files in which you define these functions reference some other identifiers that are defined in yet other files you'll also need to include those and so on.
And as you can see this can get pretty annoying pretty quickly so it might be a good idea to put all of your app code, and all other code that's outside of the main.go file into separate packages, then have main.go import those packages, and with that you should be able to run your app with go run main.go
.
I have this problem too. Maybe we follow the same tutorial. try this:
go build . // create a file end with ".exe", my file name is "golang.exe"
./golang.exe
then it's ok!