title: Generic REST API Golang
body: <p>Searching SO for <strong>Generic REST API Golang</strong> gives 0 results. Searching Google gives 2 results. So this question is maybe not correctly formulated or it is impossible to achieve in Golang.</p>
  
  <p>My goal is to avoid repeating similar code over and over again. So I am trying to make the code in Golang as generic as possible. Write once, use many.</p>
  
  <p>This is my first attempt to create a generic REST API for select in Golang. The code below gives almost what I want: </p>
  
  <p>But the result is presented in the Terminal. I have no idea how to redirect the result to the browser.</p>
  
  <pre><code>package main
  
  import (
      "fmt"
      "log"
      "net/http"
      "database/sql"
      "time"
      _ "github.com/lib/pq"
  )
  
  var db *sql.DB
  
  func main() {
     Connect()
     http.HandleFunc("/", Query)
     log.Fatal(http.ListenAndServe(":8080", nil))
  }
  
  func Connect() {
     const (
     host = "127.0.0.1"
     port = 5432
     user = "test"
     password = "test"
     dbname  = "Test")
  
  login := fmt.Sprintf("host=%s port=%d user=%s "+"password=%s dbname=%s sslmode=require", host, port, user, password, dbname)
  var err error
    db, err = sql.Open("postgres", login)
  if err != nil {
      log.Fatalln(err)
  }
  err = db.Ping()
    if err != nil {
    panic(err)
  }
  
  func Query(w http.ResponseWriter, r *http.Request) {
  
     var query string
     switch r.URL.String() {
     case "/getuser":
        query = "select * from getuser()"
     case "/getco":
        query = "select * from getco()"
     case "/etc"
        query = "select * from etc"
     default:
        query = ""
     }
  
    var err error
    var rows *sql.Rows
  
    rows, err = db.Query(query)
    if err != nil {
        http.Error(w, http.StatusText(500), 500)
        return
     }
    defer rows.Close()
  
    cols, err := rows.Columns()
    vals := make([]interface{}, len(cols))
    for i := 0; i &lt; len(cols); i++ {
        vals[i] = new(interface{})
        if i != 0 {
          fmt.Print("\t")
        }
        fmt.Print(cols[i])
     }
  fmt.Println()
  
  for rows.Next() {
      err = rows.Scan(vals...)
      if err != nil {
          fmt.Println(err)
          continue
      }
      for i := 0; i &lt; len(vals); i++ {
          if i != 0 {
              fmt.Print("\t")
          }
          printValue(vals[i].(*interface{}))
      }
      fmt.Println()
  }
  
  
  func printValue(pval *interface{}) {
      switch v := (*pval).(type) {
      case nil:
          fmt.Print("NULL")
      case bool:
          if v {
             fmt.Print("1")
          } else {
             fmt.Print("0")
          }
      case []byte:
          fmt.Print(string(v))
      case time.Time:
          fmt.Print(v.Format("2006-01-02"))
      default:
          fmt.Print(v)
      }
   }
  </code></pre>
  
  <p>Every attempt to write to the browser gives various type of errors:</p>
  
  <pre><code>fmt.Printf("%s\n", vals...)
  </code></pre>
  
  <p>My questions are</p>
  
  <ol>
  <li>How do I redirect the result to the browser?</li>
  <li>Is there any better way to achieve this? (reuse generic code)</li>
  </ol>