Web server in Go apparently is not creating new requests

Asked

Viewed 212 times

4

I am now starting to develop in Go, and I am currently studying Go for Web development, so through examples I started a simple server in Go:

package main

import (
  "fmt"
  "log"
  "net/http"
  "time"

  "github.com/gorilla/mux"
)

var Nome string

func SetNewName(w http.ResponseWriter, r *http.Request){
    fmt.Println("Old Name: "+Nome)
    Nome = r.PostFormValue("nome")
    fmt.Println("New Name: "+Nome+" \n")
    w.Write([]byte("OK"))
}

//Entry point of the program
func main() {
    r := mux.NewRouter()

    fs := http.FileServer(http.Dir("public"))
    r.Handle("/", fs)

    r.HandleFunc("/teste-post", SetNewName).Methods("POST")  

    srv := &http.Server{
        Handler:      r,
        Addr:         ":8000",
        WriteTimeout: 15 * time.Second,
        ReadTimeout:  15 * time.Second,
   }

   log.Fatal(srv.ListenAndServe())
}

In the folder public i have a simple index.html file where:

1) Request the jQuery
2) Has a form

  <form id="frm-post-teste">
        <input type="text" name="nome">
        <input type="submit" id="btn-send" value="Enviar">
  </form>

3) And this script:

$("#btn-send").click(function(e){
  e.preventDefault();

  $.ajax({
    type: "POST",
    url: window.location.origin+"/teste-post",
    data: $("#frm-post-teste").serialize(),
    dataType: "JSON"
  }).done(function(data){
    console.log(data)
  });

});

The problem I’ve been facing is: Even requests from different browsers, different devices and even requests made for this example hosted at Digitalocean, all show a strange behavior, it seems the application only creates a connection, because the variable Name has the value of the stored past request, even if different requests are made by different clients.

This behavior left me extremely confused, because the code is simple and I don’t know where the error is coming from.

2 answers

3


This occurs because of where the variable is set, when you set:

var Nome string

It becomes global, accessible to everything, so not just a connection.


Making:

curl -X POST -d "nome=inkeliz" 127.0.0.1:8000/teste-post

Returns:

Old Name:
New Name: inkeliz

Afterward:

curl -X POST -d "nome=x" 127.0.0.1:8000/teste-post

Returns:

Old Name: inkeliz
New Name: x

The way around this is defined the local variable, in this case could do:

func SetNewName(w http.ResponseWriter, r *http.Request){
    var nome string
    //...

This will make it work:

Old Name:
New Name: inkeliz

Old Name:
New Name: x

Another option would be to simply use the :=, as in:

func SetNewName(w http.ResponseWriter, r *http.Request){

    nome := r.PostFormValue("nome")

    fmt.Println("New Name: "+nome+" \n")
    w.Write([]byte("OK"))

}
  • It was a conceptual mistake, I come from PHP, so I’m used to a different view of things. In PHP roughly a web server receives the request, invokes the PHP interpreter, the interpreter then interprets the scripts in question (generates a new instance), performed the output that instance of interpretation ceases to exist. Already in Golang you build the application, runs and this execution instance will receive all the connections, so when developing the application you should develop it with this unique instance mentality receiving all the requests. Thank you for your attention.

0

Is that you declared the variable Name in global context:

var Nome string

If you want to have different contexts, you need to do some session control.

Looks like Gorilla can help with that:

https://github.com/gorilla/sessions

  • If you need to pass variables from one method to another, don’t forget to use Context.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.