Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How I built My First Web App in Go

AudreyLim
September 16, 2014

How I built My First Web App in Go

I'm a lawyer by profession. I learned to code in Go as my first backend programming language in 5 weeks. I've built 2 apps in Go.

AudreyLim

September 16, 2014
Tweet

Other Decks in Programming

Transcript

  1. How  I  built  my  first  web   app  in  Go

      16  Sep  2014   Audrey  Lim   [email protected]   TwiDer:  @AudreyLim77  
  2. About  Me   Lawyer  (1-­‐2  yrs)     Learning  Journey

         May  –  Jul  2014:    HTML,  CSS,  JS        
  3. About  Me   Lawyer  (1-­‐2  yrs)     Learning  Journey

         May  –  Jul  2014:    HTML,  CSS,  JS         (codeacademy,  books,   websites)  
  4. About  Me   Lawyer  (1-­‐2  yrs)     Learning  Journey

         May  –  Jul  2014:    HTML,  CSS,  JS      mid-­‐Jul  2014:      Go  (1st  backend)         (codeacademy,  books,   websites)  
  5. About  Me   Lawyer  (1-­‐2  yrs)     Learning  Journey

         May  –  Jul  2014:    HTML,  CSS,  JS      mid-­‐Jul  2014:      Go  (1st  backend)         (codeacademy,  books,   websites)   (everywhere)  
  6. About  Me   Lawyer  (1-­‐2  yrs)     Learning  Journey

         May  –  Jul  2014:    HTML,  CSS,  JS      mid-­‐Jul  2014:      Go  (1st  backend)      mid-­‐Aug  2014:    deployed  1st  app  –  CRUD  app     (codeacademy,  books,   websites)   (everywhere)  
  7. About  Me   Lawyer  (1-­‐2  yrs)     Learning  Journey

         May  –  Jul  2014:    HTML,  CSS,  JS      mid-­‐Jul  2014:      Go  (1st  backend)    mid-­‐Aug  2014:    deployed  1st  app  –  CRUD  app      end-­‐Aug  2014:      deployed  2nd  app  –  API  client   (codeacademy,  books,   websites)   (everywhere)  
  8. Go  Resources   golang.org   Books  and  websites   Sample

     applicaIons   Stackoverflow,  Go-­‐nuts  mailing  list        
  9. Go  Resources   golang.org  (Go  Tour,  Docs,  Go  blog)  

    Books  and  websites     Sample  applicaIons     Stackoverflow,  Go-­‐nuts  mailing  list        
  10. Go  Resources   golang.org  (Go  Tour,  Docs,  Go  blog)  

    Books  and  websites  (www.golang-­‐book.com,  www.gobyexample.com)   Sample  applicaIons     Stackoverflow,  Go-­‐nuts  mailing  list        
  11. Go  Resources   golang.org  (Go  Tour,  Docs,  Go  blog)  

    Books  and  websites  (www.golang-­‐book.com,  www.gobyexample.com)   Sample  applicaIons  (Go  Wiki,  from  books)   Stackoverflow,  Go-­‐nuts  mailing  list        
  12. CRUD  App     API  Client     Flickr,  Weather

     API     Simple  CRUD  App  using  MySQL   for  data  persistence    
  13. 1st  app:  CRUD  App   Sign  up/Sign  in    Read

     Status    Create  Status    Delete  Status    Edit  Status   Sign  out     MySQL      
  14. Basic  Structure   package  main     Import  (  

     “fmt”    “net/http”   )     func  handler(w  http.ResponseWriter,  r  *http.Request)  {    fmt.Fprint(w,  “hello  world!”)   }     func  main()  {    http.HandleFunc(“/”,  handler)    http.ListenAndServe(“:8080”,  nil)   }      
  15. Basic  Structure   package  main     Import  (  

     “fmt”    “net/http”   )     func  handler(w  http.ResponseWriter,  r  *http.Request)  {    fmt.Fprint(w,  “hello  world!”)   }     func  main()  {    http.HandleFunc(“/”,  handler)    http.ListenAndServe(“:8080”,  nil)   }       Local  server  connecIon   Handler  funcIon  when  root  is   requested     Print  output  to  client       All  executable  commands  use  package  main   Go’s  stdlib   Entry  point  
  16. Libraries   import  (    "database/sql"    "html/template"    "fmt"

       "log"    "net/http"    "os"    _  "github.com/go-­‐sql-­‐driver/mysql"    "github.com/gorilla/mux"    "github.com/gorilla/securecookie”   )  
  17. Libraries   Standard  library   import  (    "database/sql"  

     "html/template"    "fmt"    "log"    "net/http"    "os"    _  "github.com/go-­‐sql-­‐driver/mysql"    "github.com/gorilla/mux"    "github.com/gorilla/securecookie”   )   External  packages  
  18. Data  Structs   Type  Slice  of  Pointers  to  Post  struct

      type  User  struct  {    Userid      int64    Username  string    Password  string    Posts        []*Post   }     type  Post  struct  {    Tweetid    string    Username  string    Status      string   }  
  19. Database  func>ons   Return  slice  of  slice  of  strings  

    func  ReadStatus()  (res  [][]string)  {    err  :=  db.Ping()    if  err  !=  nil  {      log.Fatal(err)    }    rows,  err  :=  db.Query("SELECT  id,  tweet,  username  FROM  posts  WHERE    username  =  ?  ORDER  BY  id  DESC",  currentuser)    if  err  !=  nil  {      log.Fatal(err)    }    defer  rows.Close()      var  tweet,  id,  username  string    for  rows.Next()  {      err  :=  rows.Scan(&id,  &tweet,  &username)      if  err  !=  nil  {        return  res      }      var  a  []string      a  =  append(a,  id,  tweet,  username)      res  =  append(res,  a)    }    return   }  
  20. Database  func>ons   Return  slice  of  slice  of  strings  

    func  ReadStatus()  (res  [][]string)  {    err  :=  db.Ping()    if  err  !=  nil  {      log.Fatal(err)    }    rows,  err  :=  db.Query("SELECT  id,  tweet,  username  FROM  posts  WHERE    username  =  ?  ORDER  BY  id  DESC",  currentuser)    if  err  !=  nil  {      log.Fatal(err)    }    defer  rows.Close()      var  tweet,  id,  username  string    for  rows.Next()  {      err  :=  rows.Scan(&id,  &tweet,  &username)      if  err  !=  nil  {        return  res      }      var  a  []string      a  =  append(a,  id,  tweet,  username)      res  =  append(res,  a)    }    return   }   Verify  db  connecIon   Raw  queries   Append  strings  to  slice   Append  slice  of  strings  to  output  
  21. Handler  func>ons   Append  slice  of  Post   instances  to

     Posts  slice   func  homeHandler(w  http.ResponseWriter,  r  *http.Request)  {    currentuser  =  getUserName(r)    if  currentuser  !=  ""  {      var  as  []Post      a  :=  User{}      m  :=  ReadStatus()        for  i  :=  0;  i  <  len(m);  i++  {        as  =  append(as,  Post{Tweetid:  m[i][0],  Username:          currentuser,  Status:  m[i][1]})      }      a  =  User{Username:  currentuser}      for  i  :=  0;  i  <  len(m);  i++  {        a.Posts  =  append(a.Posts,  &as[i])      }        renderTemplate(w,  "home",  "homepage",  a)    }  else  {      http.Redirect(w,  r,  "/",  302)    }   }   Wrapper  func  around   html/template  library   Create  slice  with  Post  instances  
  22. Func  main   Open  connecIon  pool   Handlers  for  URL

     paths   func  main()  {    db,  err  =  sql.Open("mysql",  os.Getenv("DB_USERNAME") +":"+os.Getenv("DB_PASSWORD")+"@tcp("+os.Getenv("DB_CLEARDB")+": 3306)/"+os.Getenv("DB_NAME"))    if  err  !=  nil  {      log.Fatal(err)    }    defer  db.Close()      router.HandleFunc("/",  logHandler)    router.HandleFunc("/login",  loginHandler)    router.HandleFunc("/home",  homeHandler)    router.HandleFunc("/home/tweets",  usertweetHandler).Methods("POST")    router.HandleFunc("/logout",  logoutHandler).Methods("POST")    router.HandleFunc("/home/delete",  deleteHandler).Methods("POST")    router.HandleFunc("/home/edit",  editHandler).Methods("POST")    router.HandleFunc("/home/save",  saveHandler).Methods("POST”)    router.PathPrefix("/").Handler(http.FileServer(http.Dir("./layout/")))    http.Handle("/",  router)      err  :=  http.ListenAndServe(":"+os.Getenv("PORT"),  nil)    if  err  !=  nil  {      panic(err)    }   }   Port  for  server   connecIon  
  23. 2nd  app:  API  Client   Get   a   series

      of   photos   from   Flickr   for   a   random   city   and   display   current   weather   data   for   the   same   city  
  24. Libraries   import  (    "encoding/json"    "fmt"    "html/template"

       "io/ioutil"    "log"    "math/rand"    "net/http"    "os"    "strconv"    "time"   )