GO Lang Web Application- Auto Compile and Reload [duplicate] - go

This question already has answers here:
Go Auto-Recompile and Reload Server on file change
(12 answers)
Closed 2 years ago.
Created basic web app and it is running on localhost:8080, I have to restart the server on each file change.
File changes take affect Ctrl +c (terminate program)and run again go program go run hello.go.
We do not want to terminate program of each file changes. If we do any changes and refresh browser new change take affect like PHP language
EX
First Program
package main
import (
"fmt"
"net/http"
)
func helloWorld(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World")
}
func main() {
http.HandleFunc("/", helloWorld)
http.ListenAndServe(":8080", nil)
}
Second Program
package main
import (
"fmt"
"net/http"
)
func helloWorld(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Happy Coding")
}
func main() {
http.HandleFunc("/", helloWorld)
http.ListenAndServe(":8080", nil)
}
Anyone have a solution to this?

You have to understand that Go & PHP are not the same at all. Go is a statically-typed, COMPILED language -- where PHP is a dynamically-typed, INTERPRETED language.
So using some special third party solution like the one mentioned in the comment above by #AyushGupta is probably your best bet. What you described in your question is the workflow when building services with Go. You compile a binary, run it & repeat when you make changes.

Related

Wrong time.Duration calculated

I have an HTTP server that returns the "uptime" value. The short version of the code:
package main
import (
"fmt"
"net/http"
"time"
)
var startup time.Time
func main() {
startup = time.Now()
http.HandleFunc("/", RootHandler)
http.ListenAndServe(":39000", nil)
}
func RootHandler(w http.ResponseWriter, r *http.Request) {
now := time.Now()
fmt.Fprintf(w, "startup: %s\nnow: %s\nuptime (.Since): %s\nuptime (.Sub): %s",
startup.Format("2006-01-02 15:04:05"),
now.Format("2006-01-02 15:04:05"),
time.Since(startup).Round(time.Second),
now.Sub(startup).Round(time.Second),
)
}
I started the server at 22:10:33 and after about 1h10m I put my computer to sleep. In the morning, after the computer awake, I got the next response:
startup: 2021-11-18 22:10:33
now: 2021-11-19 05:35:20
uptime (.Since): 1h13m14s
uptime (.Sub): 1h13m14s
I'm working on windows, but the code was executed from WSL v2. Can someone explain why is time calculated wrong?
P.S. If I'm running directly from windows - the response is fine (time difference calculated correctly).
Your code seems fine. From my understanding WSL v2 is it's own environment. In which case, it's getting the time from there. I would check the time on the system.
https://tomssl.com/fixing-clock-drift-in-wsl2-using-windows-terminal/

Serve static file from within a group with Gin

I want to server static file by mapping /fs to filesys in the disk. I can server static file like this:
r := gin.New()
r.Use(static.Serve("/fs", static.LocalFile("./filesys", false)))
// followed by other routes definition such as R.GET()
I also want to guard access by using a authentication middleware, without affecting other routes. I imagine it's something I need to do with Gin's group like this:
r := gin.New()
g := r.Group("/fs")
{ // what is the purpose of this parenthesis BTW?
g.Use(authMiddleWare)
g.Use(static.Serve("/fs", static.LocalFile(fileUploadDir, false)))
}
However, I can't get it to work. It is not routed in. If I do additional g.GET afterward, the path came out to be wrong.
How to go about this?
Hi I checked this issue has been open for 3 years on git with no solution for 3 years and the static package seems not being maintained anymore
This is an alternate solution that might help you
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
grp := r.Group("/static")
{
grp.StaticFS("", http.Dir("/your_directory"))
}
r.Run()
}

Use functions of other files is other directories Golang [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I want to use a method that is in a folder called "controllers" inside my main method, but it turns out that when I start the program it says that the function is not found or defined, I tried following the package guide in the Golang documentation but with the Go build and Go install this did not work, I would like to know only how to use files that are inside other folders to be able to have more order, here the codes and my file tree, first: UserController.go, here is the funcionLoadRecordsFromFile()... (Repeat... i tried using the go build and go install from the documentation but dont work...)
package main
import (
"net/http"
"log"
)
func LoadRecordsFromFile(w http.ResponseWriter, r *http.Request) {
// Maximum upload of 10 MB files
r.ParseMultipartForm(10 << 20)
}
Here is my main.Go were i want to use the function LoadRecordsFromFile() from UserController.go
package main
import (
"net/http"
"github.com/go-chi/chi"
"log"
)
func main() {
r := chi.NewRouter()
r.Post("/loadUsers", func(w http.ResponseWriter, r *http.Request) {
LoadRecordsFromFile(w,r)
})
log.Print("Server started in port 3000")
http.ListenAndServe(":3000", r)
}
The archives are...
-GolangProject
-Main.go
-controllers
--UserController.go
You need to make some changes in your code.
At first, you need to change your package name in your UserController.go. Lets just use controllers as package.
package controllers
import (
"net/http"
"log"
)
func LoadRecordsFromFile(w http.ResponseWriter, r *http.Request) {
// Maximum upload of 10 MB files
r.ParseMultipartForm(10 << 20)
}
Then your Main.go needs some changes.
package main
import (
"net/http"
"github.com/go-chi/chi"
"log"
"github.com/Giovanni2414/Truora/controllers"
)
func main() {
r := chi.NewRouter()
r.Post("/loadUsers", func(w http.ResponseWriter, r *http.Request) {
controllers.LoadRecordsFromFile(w,r)
})
log.Print("Server started in port 3000")
http.ListenAndServe(":3000", r)
}
These changes are enough I think.
Some notes:
Only your main file should have package main.
Normally we define package name after our current folder (but it can be different). All the files under same folder must have same package name.
When you use a function that is under a different package, you should import the desired package before you can use that function.
Your imported path should be like this: <project-module-name>/<folder1>/<folder2>/../<final-folder>.
Finally, you should call that function like the following:
package_name.MyFunction()

Why does code inside unused method run?

The code below comes from Todd Mcleod's Golang web-dev course. What I fail to understand - even watching his video's over and over and googling everything about methods- is the following: The method ServeHTTP is attached to type hotdog, but is never ran. Still the code inside the method (in this case Fprintln(...) is executed. (When you run this code and go to localhost:8080, it diesplays "Any code you want in this func".) Could anyone explain me why this is?
Thanks a lot!
package main
import (
"fmt"
"net/http"
)
type hotdog int
func (m hotdog) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Any code you want in this func")
}
func main() {
var d hotdog
http.ListenAndServe(":8080", d)
}
It is run. ListenAndServe calls it for every request made to your server.
this function is run when the type hotdog is used
func (m hotdog) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Any code you want in this func")
}
in the main you create variable d with the type hotdog,
then in the ListenAndServe and you tell your code to use variable d every time someone connects to your server and because d is of type hotdog your first function is run everytime someone connects
func main() {
var d hotdog
http.ListenAndServe(":8080", d)
}
Since you passed hotdog, which implements ServeHTTP, as a handler, every request received will be sent to hotdog's ServeHTTP.

Go: embed static files in binary

This might be a very amateur question. I'm trying to embed static files into binary, ie. html. How do I do that with https://github.com/jteeuwen/go-bindata?
So I can access an asset with this https://github.com/jteeuwen/go-bindata#accessing-an-asset, but what do I do with "data", and how to do I parse files, execute template, and serve them in the directory?
I couldn't find any examples online, and will appreciate some help!
5/6 years later, this should be easier with Go 1.16 (Q1 2021), which adds support for embedded files (issue/proposal 41191 )
It will be permitted to use //go:embed naming a single file to initialize a plain string or []byte variable:
//go:embed gopher.png
var gopherPNG []byte
The import is required to flag the file as containing //go:embed lines and needing processing.
Goimports (and gopls etc) can be taught this rule and automatically add the import in any file with a //go:embed as needed.
That sparked a debate on issue 42328 about how to avoid surprising inclusion of "hidden" files when using //go:embed
This as resolved in CL 275092 and commit 37588ff
Decision to exclude files matching .* and _* from embedded directory results when embedding an entire directory tree.
See src/embed/internal/embedtest/embed_test.go
//go:embed testdata/k*.txt
var local embed.FS
testFiles(t, local, "testdata/ken.txt", "If a program is too slow, it must have a loop.\n")
//go:embed testdata/k*.txt
var s string
testString(t, s, "local variable s", "If a program is too slow, it must have a loop.\n")
//go:embed testdata/h*.txt
var b []byte
testString(t, string(b), "local variable b", "hello, world\n")
Note: with CL 281492, cmd/go passes embedcfg to gccgo if supported.
See also (Jan. 2021) issue 43854 "opt-in for //go:embed to not ignore files and empty dirs".
Given a directory structure like so:
example/
main.go
data/hi.html
example/main.go
package main
import (
"html/template"
"log"
"net/http"
"os"
)
var tmpl *template.Template
func init() {
data, err := Asset("data/hi.html")
if err != nil {
log.Fatal(err)
}
tmpl = template.Must(template.New("tmpl").Parse(string(data)))
}
func main() {
// print to stdout
tmpl.Execute(os.Stdout, map[string]string{"Name": "James"})
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
tmpl.Execute(w, map[string]string{"Name": "James"})
})
log.Fatal(http.ListenAndServe(":8000", nil))
}
example/data/hi.html
<h1>Hi, {{.Name}}</h1>
run like so:
go-bindata data && go build && ./example
Console Output:
<h1>Hi, James</h1>
HTTP output:
Hi, James

Resources