Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a simple custom HTTP server in Go?

Tags:

I am new to Go and trying to write a custom HTTP server. I'm getting a compilation error. How can I implement the ServeHTTP method in my code?

My Code:

package main  import (     "net/http"     "fmt"     "io"     "time" )   func myHandler(w http.ResponseWriter, req *http.Request) {     io.WriteString(w, "hello, world!\n") }   func main() {     // Custom http server     s := &http.Server{         Addr:           ":8080",         Handler:        myHandler,         ReadTimeout:    10 * time.Second,         WriteTimeout:   10 * time.Second,         MaxHeaderBytes: 1 << 20,     }      err := s.ListenAndServe()     if err != nil {         fmt.Printf("Server failed: ", err.Error())     } } 

Error while compiling:

.\hello.go:21: cannot use myHandler (type func(http.ResponseWriter, *http.Request)) as type http.Handler in field value:     func(http.ResponseWriter, *http.Request) does not implement http.Handler (missing ServeHTTP method) 
like image 687
AnkurS Avatar asked Aug 30 '14 13:08

AnkurS


People also ask

How do I create an HTTP server on go?

Once you've set up your handlers, call the http. ListenAndServe function to start the server and listen for requests. In this first chunk of code, you set up the package for your Go program, import the required packages for your program, and create two functions: the getRoot function and the getHello function.

Is Golang HTTP server production ready?

Short answer: YES.

Is Go HTTP server concurrent?

Go's built-in net/http package is convenient, solid and performant, making it easy to write production-grade web servers. To be performant, net/http automatically employs concurrency; while this is great for high loads, it can also lead to some gotchas.


2 Answers

You either use a struct and define ServeHTTP on it or simply wrap your function in a HandlerFunc

s := &http.Server{     Addr:           ":8080",     Handler:        http.HandlerFunc(myHandler),     ReadTimeout:    10 * time.Second,     WriteTimeout:   10 * time.Second,     MaxHeaderBytes: 1 << 20, } 
like image 148
OneOfOne Avatar answered Oct 08 '22 12:10

OneOfOne


in order to work properly, myHandler should be an object that satisfy the Handler Interface, in other words myHandler should have method called ServeHTTP.

For example, let's say that myHandler is custom handler for showing the current time. The code should be like this

package main  import (     "fmt"     "net/http"     "time" )  type timeHandler struct {     zone *time.Location }  func (th *timeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {     tm := time.Now().In(th.zone).Format(time.RFC1123)     w.Write([]byte("The time is: " + tm)) }  func newTimeHandler(name string) *timeHandler {     return &timeHandler{zone: time.FixedZone(name, 0)} }  func main() {      myHandler := newTimeHandler("EST")     //Custom http server     s := &http.Server{         Addr:           ":8080",         Handler:        myHandler,         ReadTimeout:    10 * time.Second,         WriteTimeout:   10 * time.Second,         MaxHeaderBytes: 1 << 20,     }      err := s.ListenAndServe()     if err != nil {         fmt.Printf("Server failed: ", err.Error())     } } 

run this code and access http://localhost:8080/ in your browser. you should see formatted text like this

The time is: Sat, 30 Aug 2014 18:19:46 EST 

(you should see different time.)

hope this help,

Further more reading

A Recap of Request Handling in Go

like image 30
pyk Avatar answered Oct 08 '22 10:10

pyk