How to define one static folder for all routes - go

I use github.com/gorilla/mux router and I need include my static files for all routes or notFound routes.
Now refreshing only page by / works but other urls doesn't.
package main
import (
"fmt"
"log"
"net/http"
"crudgo/backend/home"
"github.com/gorilla/mux"
)
func main() {
http.FileServer(http.Dir("./public/p/dist"))
log.Println("Listening...")
router := mux.NewRouter();
home.HomeRoute(router)
router.PathPrefix("/{_:.*}").Handler(http.FileServer(http.Dir("./public/p/dist")))
http.ListenAndServe("localhost:3000", router)
}

Related

go 1.16 embed - strip directory name

i was previously using statik to embed files into a Go application.
with Go 1.16 i can remove that deps
for example:
//go:embed static
var static embed.FS
fs := http.FileServer(http.FS(static))
http.Handle("/", fs)
this will serve the ./static/ directory from http://.../static/
Is there a way I can serve that directory from / root path, without /static?
Use fs.Sub:
Sub returns an FS corresponding to the subtree rooted at fsys's dir.
package main
import (
"embed"
"io/fs"
"log"
"net/http"
)
//go:embed static
var static embed.FS
func main() {
subFS, _ := fs.Sub(static, "static")
http.Handle("/", http.FileServer(http.FS(subFS)))
log.Fatal(http.ListenAndServe(":4000", nil))
}
fs.Sub is also useful in combination with http.StripPrefix to "rename" a directory. For instance, to "rename" the directory static to public, such that a request for /public/index.html serves static/index.html:
//go:embed static
var static embed.FS
subFS, _ := fs.Sub(static, "static")
http.Handle("/", http.StripPrefix("/public", http.FileServer(http.FS(subFS))))
Alternatively, create a .go file in the static directory and move the embed directive there (//go:embed *). That matches a little more closely what the statik tool does (it creates a whole new package), but is usually unnecessary thanks to fs.Sub.
// main.go
package main
import (
"my.module/static"
"log"
"net/http"
)
func main() {
http.Handle("/", http.FileServer(http.FS(static.FS)))
log.Fatal(http.ListenAndServe(":4000", nil))
}
// static/static.go
package static
import "embed"
//go:embed *
var FS embed.FS

How in Golang use struct in other package file?

I am new in Golang and need some help.
As you can see in the code below I am tring to create REST API in Golang. I use mux (Gorilla Mux) and pq (PostgreSQL driver) as third party libraries. Don't want to use ORM.
Inside application.go file I have InitializeRoutes function with a list of all aviable routes. GetFactors function process one of these routes. I am tring to define GetFactors function logic in other file called factors.go. Inside factors.go file I want to use Application struct which was defined in application.go. How to make it correctly? Right now as you can see they are in different packages. For thats why factors.go file don't see Application struct.
Project structure:
main.go
application.go
controllers
factors.go
main.go:
package main
func main() {
application := Application{}
application.Initialization()
application.Run("localhost:8000")
}
application.go:
package main
import (
"database/sql"
"github.com/gorilla/mux"
"log"
"net/http"
"rest-api/configurations"
)
type Application struct {
Router *mux.Router
Database *sql.DB
}
func (application *Application) Initialization() {
var err error
application.Database, err = configurations.DatabaseConnection()
if err != nil {
log.Fatal(err)
}
application.Router = mux.NewRouter()
application.Router.StrictSlash(true)
application.InitializeRoutes()
}
func (application *Application) Run(address string) {
log.Fatal(http.ListenAndServe(address, application.Router))
}
func (application *Application) InitializeRoutes() {
application.Router.HandleFunc("/api/factors", application.GetFactors).Methods("GET")
// other code
}
controllers/factors.go:
package controllers
import (
"net/http"
)
func (application *Application) GetFactors(rw http.ResponseWriter, request *http.Request) {
// code
}
Well, finally I decided to redesign the project structure.
main.go
routes
routes.go
controllers
factors.go
models
factors.go
main.go:
import (
"your_project_name/routes"
)
func main() {
// code
router := mux.NewRouter()
routes.Use(router)
// code
}
routes/routes.go:
package routes
import (
"github.com/gorilla/mux"
"your_application_name/controllers"
)
func Use(router *mux.Router) {
router.HandleFunc("/api/factors", controllers.GetFactors).Methods("GET")
}
controllers/factors.go:
package controllers
var GetFactors = func(res http.ResponseWriter, req *http.Request) {
// code
}

Serve static files with golang

I'm trying to develop a simple web application but I'mhaving problem with serving my static files.
The file structure is:
main
--main.go
-serve
--listenAndServe.go
--templates
---login.html
---assets
----css
----fonts
----js
my code is this:
import (
"log"
"net/http"
"time"
"github.com/gorilla/mux"
)
var (
router = mux.NewRouter()
)
func (c *Conn) ListenAndServe() {
fs := http.FileServer(http.Dir("./templates/assets"))
http.Handle("/assets/", http.StripPrefix("/assets/", fs))
router.HandleFunc("/", c.IndexPageHandler)
router.HandleFunc("/login.html", c.LoginPageHandler)
log.Println("Listening...")
http.Handle("/", router)
muxWithMiddlewares := http.TimeoutHandler(router, time.Minute*30,
"Timeout!")
http.ListenAndServe(":8080", muxWithMiddlewares)
}
But for some reason when I run it from main.go it serves the html but not the assets. I would really apreciate some tips. Thanks!
Try This:
mux.Handle("/static/", http.StripPrefix("/static", fileServer))
Note that static, in your case assets only has a single forward slash within the stripPreFix function.
Hope this helps.

Router Not Finding Controller Beego

I had a beego application that was working, and then my router stopped finding the controller, and I have no idea why. No matter what url I type, the router does not direct to the controller complaining nomatch
2016/07/26 17:24:50 [router.go:829][D] | GET | / | 478.352µs | notmatch |
app.conf
appname = exampleapp
httpport = 8080
runmode = dev
router.go
package routers
import (
"github.com/astaxie/beego"
"example/controllers"
)
func init() {
beego.Router("/", &controllers.MainController{})
}
default.go (controller)
package controllers
import (
"github.com/astaxie/beego"
)
type MainController struct {
beego.Controller
}
func (c *MainController) Get() {
c.Data["Website"] = "http://localhost:8080"
c.TplName = "index.tpl"
}
main.go
package main
import (
"fmt"
"github.com/astaxie/beego"
)
func main() {
fmt.Pritnln("Starting Beego App")
beego.Run()
fmt.Println("Finished Running Beego App")
}
I believe this is following the specifications of http://beego.me/docs/mvc/controller/router.md so I would like to understand why it does not find the controller.
You are not importing routers package. If you don't import routers in anywhere, the init function will never be executed. You can test it adding a simple fmt.Println('I'm initialized') in routers.init function.
func init() {
fmt.Println('I'm initialized')
beego.Router("/", &controllers.MainController{})
}
Ok, you must add a new import with _ to say that you won't use, but, the init function will be executed! Then you must write this in main package:
import (
"fmt"
"github.com/astaxie/beego"
_ "example/routers"
)
I hope that it is useful! :-)

Golang routing in different controllers

I am new to Golang and I am trying to learn how to do efficient routing. For instance I have a controller folder/directory and inside that controller I want to have different Func/methods with their own unique routes but I do not know how to do that. I have downloaded the github.com/gorilla/mux package and my application looks like this
The main section of my application looks like this and it is working perfectly: tim.go
package main
import(
"net/http"
"fmt"
"github.com/gorilla/mux"
)
func HomeHandler(writer http.ResponseWriter, req *http.Request) {
writer.WriteHeader(200)
fmt.Fprintf(writer, "Home!!!\n")
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/home", HomeHandler).Name("bob")
http.Handle("/",r)
http.ListenAndServe(":8000", nil)
}
The issue is how can I get the func/methods inside my Controller file(s) to also display on the browser. My sample.go file does not show in the browser when I go to that URL
package Controllers
import(
"net/http"
"fmt"
"github.com/gorilla/mux"
)
func HomeHandler(writer http.ResponseWriter, req *http.Request) {
writer.WriteHeader(200)
fmt.Fprintf(writer, "New Home")
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/new", HomeHandler).Name("bob")
http.Handle("/",r)
http.ListenAndServe(":8000/new", nil)
}
When I go into my browser and type localhost:8000/new it says file not found. Any suggestions would be great
I suppose you run the tim.go file to start the server.
If so, the problem is you don't have the route you're calling /new, you should have an answer with /home.
To do it, you should move your HomeHandler function to Controllers package and then import this package in your main ad instantiate the routes you need.
Hope this helps.

Resources