I am learning GO and wanted to make a simple rest API.
What I want to do is fire off a goroutine after handling the api request and do the work asynchronously in the background.
Here's my implementation so far:
package main
import (
"encoding/json"
"log"
"net/http"
"github.com/julienschmidt/httprouter"
)
// APIResponse represents common structure of every api call response
type APIResponse struct {
Status string `json:"status"`
Error string `json:"error,omitempty"`
Data string `json:"data,omitempty"`
}
// Action represents what could be passed to the goroutine
type Action = func()
// ActionQueue represents a buffered channel
type ActionQueue = chan Action
func main() {
r := httprouter.New()
r.GET("/test", test)
var apiServerPort = ":80"
err := http.ListenAndServe(apiServerPort, r)
if err != nil {
log.Fatal("ListenAndServe:", err)
} else {
log.Printf("Started server on port %s", apiServerPort)
}
var queueSize = 10
queue := make(ActionQueue, queueSize)
for i := 0; i < queueSize; i++ {
go worker(queue)
}
log.Printf("Started %d queue workers", queueSize)
}
func test(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
successResponse(w, http.StatusOK, "Hello World")
queue <- func() {
log.Println("Hello from queue worker, initiated by api call")
}
}
func successResponse(w http.ResponseWriter, statusCode int, successData string) {
sendResponse(w, statusCode, "", successData)
}
func errorResponse(w http.ResponseWriter, statusCode int, errorData string) {
sendResponse(w, statusCode, errorData, "")
}
func sendResponse(w http.ResponseWriter, statusCode int, errorData string, responseData string) {
w.WriteHeader(statusCode)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(&APIResponse{Status: http.StatusText(statusCode), Error: errorData, Data: responseData})
}
func worker(queue ActionQueue) {
for action := range queue {
action()
}
}
When I try to run this code, I am getting the following error (on this line queue <- func() { ... }
):
./main.go:46:2: undefined: queue
How can I make the queue
channel available to my request handler (i.e. httprouter GET request handler func)?
Secondly, I cannot see the output from my log.Printf()
calls in the console output (stdout), e.g. server status message when the app runs. Any ideas why?