Saturday, June 11, 2011

Web Programming with Go - first web Hello world

If you’ve already gone through some of the earlier tutorials in this series, you should be quite comfortable getting onto programming the web with Go. Let’s jump right to it and then we shall analyze the code. There is a chance that there might be people arriving here for the first time, so we shall also take some time to go over the basic concepts of both the Go programming language and about web programming.

Web services wait on the computer for users to connect and request information and processing. The way to reach the computer and the service is via a URL - a unique address on the web that identifies what needs to be done. For example, the sample URL
http://onebigbank.com:80/deposit
would indicate that there is probably a service called deposit waiting to serve on a machine called onebigbank.com at the port 80 and can be accessed via the protocol http. We could additionally give parameters and variables so that the service can work on the data.

Let’s do a basic Go web program and then analyze the code. In this program, we shall start a simple service on the local machine. We will have the program running on port 9999. When you access the local machine at http://localhost:9999 (which is the same as http://127.0.0.1:9999), it will print a text message on the screen.

Full program: webhello.go
package main

import (
    "net/http" //package for http based web programs
    "fmt"
)

func handler(w http.ResponseWriter, r *http.Request) { 
    fmt.Println("Inside handler")
    fmt.Fprintf(w, "Hello world from my Go program!")
}

func main() {
    http.HandleFunc("/", handler) // redirect all urls to the handler function
    http.ListenAndServe("localhost:9999", nil) // listen for connections at port 9999 on the local machine
}

Compiling the code: You can use a Makefile. You can read more about make files in Go at Compiling and Linking with Makefiles. The Makefile that I used is given below. You will have to set the environment variable GO_HOME to the directory where Go is installed.

Full code: Makefile
include ${GO_HOME}/go/src/Make.inc

TARG=webhello
GOFMT=gofmt
    
SRC=webhello.go

GOFILES=${SRC}
    
include ${GO_HOME}/go/src/Make.cmd

format:
    ${GOFMT} -w ${SRC}

Assuming you have got all of this setup, follow the steps below.
* At the command prompt compile and link the code you wrote by entering the command:
gomake.
* This should have produced an executable. Run this by typing at the command prompt:
./webhello

* Run the program with go run webhello.go
* Your web service is now running and waiting for connections.
* Go to http://localhost:9999 on your browser.
* You should see a page with this output: Hello world from my Go program!.

Hopefully all that has gone well for you. First you can bask a little in the personal glory of having written your first working Go program for the web. … Done? Ok, now let’s analyze what we’ve done in the code. If you have already done some web programming, you would have already figured out most of the code and flow, but if you haven’t, here are the details.

* like all Go programs that need to be executed, our program has a package main.
* to work with some printing functions, it imports the package fmt
* for web related http functionality, we import the package http. Any functions within that we refer as http.function_name
* within the main program, we redirect any incoming requests to the handler function. We do this by calling http.HandleFunc and passing it two parameters - the first one is a part of the incoming url, and the second is the method capable of handling it.
* we then make the program listen on the local machine’s port 9999 for users to connect by using http.ListenAndServe("localhost:9999", nil)
* when a user connects, the programs responds with a text that is sent back to the browser.
* all the parameters of a request can be received via the parameter http.Request in the handler. You can get the URL, the input values and other details.
* you send content back to the browser using the received pointer parameter http.ResponseWriter
* the code http.HandleFunc("/", handler) meant that all requests that had the url starting with what we gave in http.ListenAndServe, will be redirected to our handler function.

Let’s now expand that sample a little where we can ask different things of the web browser with different URLs. In the next version of the same program, we will have two handlers: one two print strings as it is given and another to capitalize it.

Full program
package main

import (
    "net/http"
    "fmt"
    "strings"
)

func helloHandler(w http.ResponseWriter, r *http.Request) {
    remPartOfURL := r.URL.Path[len("/hello/"):] //get everything after the /hello/ part of the URL
    fmt.Fprintf(w, "Hello %s!", remPartOfURL)
}

func shouthelloHandler(w http.ResponseWriter, r *http.Request) {
    remPartOfURL := r.URL.Path[len("/shouthello/"):] //get everything after the /shouthello/ part of the URL
    fmt.Fprintf(w, "Hello %s!", strings.ToUpper(remPartOfURL))
}

func main() {
    http.HandleFunc("/hello/", helloHandler)
    http.HandleFunc("/shouthello/", shouthelloHandler)
    http.ListenAndServe("localhost:9999", nil)
}

After you make and execute the program, go to the following links.

http://localhost:9999/hello/Mary
Hello Mary!

http://localhost:9999/shouthello/Mary
Hello MARY!

19 comments:

  1. Speaking as a neophyte coder who has been following along, this is the part in your tutorial where I shit my pants.

    ReplyDelete
  2. Nice Tutorial, but as it is for beginners you could mention that no one should have running something like this in an productive environment as it opens a big door for XSS-attacks. Actually if this runs under testplayground.fancydomain.com you compromise the whole *.fancydomain.com .

    ReplyDelete
  3. In go1, the 'import "http"' should be 'import "net/http"' instead.

    ReplyDelete
    Replies
    1. Thanks Zhe. Even if late, I've updated the code and tutorial now.

      Delete
  4. What do you mean "we then make the program listen on the local
    machine’s port 9999"? Is there a way to make our program listen on
    some other machine's ports? Or do you mean "we then make the program
    listen to port 9999 on the localhost interface"?

    ReplyDelete
  5. Hi,The site is very well designed, has a nice colors scheme in Web Design Cochin and it can be an example for how to design with end purpose in mind.Thanks.......

    ReplyDelete
  6. Web design Jaipur:-
    All websites need to be maintained in order to keep website content current. It includes revising, editing or other changes existing web pages to keep your website update.

    ReplyDelete
  7. Great post , How to pass parameters from URL to helloHandler method..etc

    ReplyDelete
  8. Great post , Actually if this runs under testplayground.fancydomain.com you compromise the whole *.fancydomain.com .
    SEO

    ReplyDelete
  9. An impressive and informative information, thanks for shared and enjoyed to reading this post.

    ReplyDelete
  10. In my opinion, great content is above all. So focusing on creating good quality of content is the solution.

    ReplyDelete
  11. Thanks for sharing this informative content which provided me the required information about the latest technology.
    Ethical Hacking Course in Chennai | Ethical Hacking Training in Chennai

    ReplyDelete

If you think others also will find these tutorials useful, kindly "+1" it above and mention the link in your own blogs, responses, and entries on the net so that others also may reach here. Thank you.

Note: Only a member of this blog may post a comment.