packagemainimport("fmt""io/ioutil""net/http")// a simple http web service which is exposing /hello end point on port 7070.
funcmain(){http.HandleFunc("/hello",func(rwhttp.ResponseWriter,r*http.Request){fmt.Println("hello GO http web service")data,err:=ioutil.ReadAll(r.Body)// r.body - reads the request body
iferr!=nil{http.Error(rw,"error occurred",http.StatusInternalServerError)return}fmt.Fprintf(rw,"HELLO %s\n",data)})// http webservice will be listening on any ip address and on port 7070.
http.ListenAndServe(":7070",nil)}
I have written another web service example, where I have created a Handler and ServeMux and then registering handler to ServeMux.
GO REST API using standard go libraries. If you see the code of below product handler, you can see I have API with methods handling GET, POST and PUT.
The important point you would note here is, you will have to write a lot of code to parse URI params ( in this example) when you use go standard libraries.
Same way, there may be other scenarios when you have to keep writing code for basic boiler plate processing.
//handler is serving httpRequest. Returning product response JSON.
func(p*Product)ServeHTTP(rwhttp.ResponseWriter,r*http.Request){ifr.Method==http.MethodGet{p.l.Println("handling GET")p.getProducts(rw,r)return}ifr.Method==http.MethodPost{p.l.Println("handling POST")p.addProduct(rw,r)return}ifr.Method==http.MethodPut{p.l.Println("handling PUT")regex:=regexp.MustCompile(`/([0-9]+)`)g:=regex.FindAllStringSubmatch(r.URL.Path,-1)p.l.Printf("regex g group %q\n",g)// if true, means there are more than one id passed in the URI.
iflen(g)!=1{p.l.Println("invalid product id in the URI")http.Error(rw,"Invalid Request URI",http.StatusBadRequest)return}iflen(g[0])>2{http.Error(rw,"Invalid URI",http.StatusBadRequest)return}productID:=g[0][1]idString,err:=strconv.Atoi(productID)iferr!=nil{http.Error(rw,"Invalid id value in URI",http.StatusBadRequest)return}p.l.Println("updating product for ID ->",idString)p.updateProduct(idString,rw,r)return}// For any other methods, we are returning method not allowed
rw.WriteHeader(http.StatusMethodNotAllowed)}
GO - REST API using Gorilla Mux
Include Gorilla mux dependency to go.mod.
Go mod is like gradle or maven where we include dependencies.
1
2
3
require(github.com/gorilla/muxv1.8.0)
Include the package gorilla mux to your go file.
1
2
3
import("github.com/gorilla/mux")
And now we will just create our servMux from gorilla Mux and register our product handler with various endpoints for handling GET, POST, PUT, PATCH and DELETE.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
servMux:=mux.NewRouter()// registers product handler methods to serve request on api end points with specific http methods.
getHandler:=servMux.Methods(http.MethodGet).Subrouter()getHandler.HandleFunc("/products",productHandler.GetProducts)postHandler:=servMux.Methods(http.MethodPost).Subrouter()postHandler.HandleFunc("/products",productHandler.AddProduct)putHandler:=servMux.Methods(http.MethodPut).Subrouter()putHandler.HandleFunc("/products/{id:[0-9]+}",productHandler.UpdateProduct)patchHandler:=servMux.Methods(http.MethodPatch).Subrouter()patchHandler.HandleFunc("/products/{id:[0-9]+}",productHandler.UpdateProductAttribute)deleteHandler:=servMux.Methods(http.MethodDelete).Subrouter()deleteHandler.HandleFunc("/products/{id:[0-9]+}",productHandler.DeleteProduct)
If you see here, it becomes so easy to parse the UI params using gorilla mux lib
1
2
3
4
5
6
7
//UpdateProduct : updating a product
func(p*Product)UpdateProduct(rwhttp.ResponseWriter,r*http.Request){p.l.Println("handling UPDATE")uriParams:=mux.Vars(r)id,err:=strconv.Atoi(uriParams["id"])
Take a look at the repo for details about how api is working and you can simply clone it and run locally.