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

Writing web services with GO

Tor
January 28, 2014

Writing web services with GO

An intro to go-lang with an example web service

Tor

January 28, 2014
Tweet

More Decks by Tor

Other Decks in Programming

Transcript

  1. Respected  Parents   Ken  Thompson   Unix,  B,  UTF-­‐8,  Plan

     9       Rob  Pike   Plan  9,  UTF-­‐8,  Limbo,  Unix  team   The  Unix  Programming  Environment   The  PracJce  of  Programming  
  2. History   Start   Late  2007   Public    

    2009   Go  1.0   March  2012   Go  1.1   May  2013   Go  1.2   November   2013   Rob  Pike   Ken  Thompson   Robert  Griesmer  
  3. Hello   package  main     import  "fmt"    

    func  greet()  {    fmt.Println("Hello,  I  love  you,  won’t  you  tell  me  your  name?”)   }     func  main()  {    greet()   }  
  4. Basic  Types   bool     string     int

       int8    int16    int32    int64   uint  uint8  uint16  uint32  uint64  uintptr     byte  //  alias  for  uint8     rune  //  alias  for  int32            //  represents  a  Unicode  code  point     float32  float64     complex64  complex128  
  5. DeclaraJons   var  i  int   i  =  getInteger()  

      j  :=  getInteger()     value,  err  :=  getValueOrError()     value2,  _  :=  getValueOrError()  
  6. CondiJons   var  even  bool     if  x%2  ==

     0  {          even  =  true   }     if  x%2  ==  0  {          even  =  true   }  else  {          even  =  false   }     if  mod  :=  x%2;  mod  ==  0  {          even  =  true   }  
  7. Loops   factorial  :=  1   for  i  :=  2;

     i  <=  num;  i++  {          factorial  *=  i   }     nextPowerOf2  :=  1   for  nextPowerOf2  <  num  {          nextPowerOf2  *=2   }     for  {          //  Forever   }  
  8. Slice   primes  :=  []int{2,  3,  5,  7,  11,  13}

        fmt.Println("primes[1:4]  ==",  primes[1:4])     zeroes  :=  make([]int,  5)   fmt.Println("zeroes  ==",  zeroes)     for  i,  v  :=  range  primes  {            fmt.Print("(%d)  =  %d\n",  i,  v)   }   for  _,  v  :=  range  primes  {            fmt.Print("%d\n",  v)   }  
  9. Map   m  :=  make(map[string]int)   m["Ten"]  =  10  

    fmt.Println(m)                                                                                                 capitals  :=  map[string]string{      "Jerusalem":  "Israel",      "Paris":  "France",      "London":  "UK",   }   fmt.Println(capitals)                                                                                                 delete(capitals,  "London")   v,  present  :=  capitals["London"]   fmt.Println("The  capital:",  v,  "Present?",  present)  
  10. Custom  Types   type  Name  string     type  Person

     struct  {          first  Name          last    Name   }     type  Hero  struct  {          Person          power  string   }     type  Crowd  struct  {          people  []Person   }  
  11. Methods   func  (dude  Person)  FullName()  string  {    

         return  fmt.Sprint("%s  %s",  dude.first,  dude.last)   }     func  (dude  Person)  SetFirst(name  Name)  {          dude.first  =  name   }     func  (h  *Hero)  ToString()  string  {          return  fmt.Sprint("Name:  %s  Power:  %s",  h.FullName(),  h.power)   }     func  NewPerson(f,  l  Name)  Person  {          return  Person{f,  l}   }  
  12. interfaces   type  Talker  interface  {        

     Talk()  string   }     func  (dude  Person)  Talk()  string  {          return  fmt.Sprint("My  name  is  %s",  dude.FullName())   }     func  MakeSomeoneTalk(talker  Talker)  string  {          return  talker.Talk()   }     func  interfaces()  {          fmt.Println(MakeSomeoneTalk(NewPerson("Robert",  "de  Niro")))   }  
  13. FuncJons   type  PersonAcJon  func(some  Person)  Name     func

     (guy  Person)  DoublePersonAcJon(acJon  PersonAcJon)   string  {      return  fmt.Sprint("%s  %s",  acJon(guy),  acJon(guy))   }     func  DuplicateName(guy  Person)  string  {          return  guy.  DoublePersonAcJon(func(guy  Person)  Name  {                  return  guy.first          })   }  
  14. defer   func  MeasureStart(label  string)  (string,  Jme.Time)  {    

         return  label,  Jme.Now()   }     func  Measure(label  string,  startTime  Jme.Time)  {          duraJon  :=  Jme.Now().Sub(startTime)          fmt.Println(label,  "ComputaJon  took",  duraJon)   }     func  benchmark()  {          defer  Measure(MeasureStart("benchmark()"))          Jme.Sleep(Jme.Second)   }  
  15. CommunicaJng  SequenJal  Processes     “Do  not  communicate  by  sharing

     memory;   instead  share  memory  by  communicaJng”  
  16. go  rouJnes   var  a  string     func  Init()

     {      a  =  "finally  started"      return   }     func  doSomethingElse()  {      //  …   }     func  Simple()  string{      go  Init()      doSomethingElse()      return  a   }  
  17. tradiJonal   var  (      a  string    

     wg  sync.WaitGroup   )     func  Init()  {      defer  wg.Done()      a  =  "finally  started"   }     func  Simple()  string{      wg.Add(1)      go  Init()      wg.Wait()      //  do  something  else      return  a   }  
  18. channel   package  channel     var  (    

     a  string      ready  chan  bool   )     func  Init()  {      a  =  "finally  started"      ready  <-­‐  true   }     func  Simple()  string{      ready  =  make(chan  bool)      go  Init()        //  do  something  else      <-­‐ready      return  a   }  
  19. Producer  /  Consumer   func  producer(c  chan  string){    

     defer  close(c)      for  {          work  :=  getWork()          c  <-­‐  work      }   }       func  consumer(c  chan  string)  {      for  msg  :=  range  c  {              process(msg)      }   }     func  ProducerConsumer()  {      c  :=  make(chan  string)      go  producer(c)      consumer(c)   }  
  20. Producer  /  Consumer   func  producer(c  chan  string){    

     defer  close(c)      for  {          work  :=  getWork()          c  <-­‐  work      }   }       func  consumer(c  chan  string,  abort  <-­‐chan  Jme.Time)  {      for  {          select  {          case  msg  :=  <-­‐c:              process(msg)          case  <-­‐  abort:              return          }      }   }     func  ProducerConsumer()  {      c  :=  make(chan  string)      go  producer(c)            abort  :=  Jme.A|er(2*Jme.Second)      consumer(c,  abort)   }  
  21. Web  Server   package  main     import  (  

           "fmt"          "net/hBp"   )     func  handler(w  hBp.ResponseWriter,  r  *hBp.Request)  {          fmt.Fprint(w,  ”Request  from  %s",  r.URL.Path[1:])   }     func  main()  {          hBp.HandleFunc("/",  handler)          hBp.ListenAndServe(":8080",  nil)   }  
  22. user.json   {        "object":"user",      

     "entry":[              {                    "uid":"499535393",                    "id":"499535393",                    "Jme":1326210816,                    "changed_fields":[                          "locaJon"                    ]              }        ]   }  
  23. User   type  Entry  struct  {      ChangedFields  []string

     `json:"changed_fields"`   }     type  User  struct  {      Entries  *[]Entry  `json:"entry”`      Body        []byte   }  
  24. New  User   func  NewUser(io  io.Reader)  (u  *User,  err  error)

     {      body,  err  :=  iouJl.ReadAll(io)      if  err  !=  nil  {          return  nil,  err      }        err  =  json.Unmarshal(body,  &u)      u.Body  =  body      if  err  !=  nil  {          return  nil,  err      }      return  u,  nil   }  
  25. Publish   func  (u  *User)  Publish(conn  ConnecJon)  (err  error)  {

         for  _,  entry  :=  range  *u.Entries  {          for  _,  field  :=  range  entry.ChangedFields  {              err  =  conn.Publish(u.Body,  field)              if  err  !=  nil  {                  return  err              }          }      }      return  nil   }  
  26. Event  Handler   func  EventHandler(w  hBp.ResponseWriter,  r  *hBp.Request)  {  

       user,  err  :=  NewUser(r.Body)      if  err  !=  nil  {          errorResponse("NewUser",  err,  w)          return      }        err  =  user.Publish(conn)      if  err  !=  nil  {          errorResponse("User.Publish",  err,  w)          return      }        w.WriteHeader(200)      fmt.Fprint(w,  `{"success":true}`)   }  
  27. Server   var  conn  ConnecJon     func  init()  {

         conn  =  ConnecJon{Uri:  `amqp://guest:guest@localhost:5672`}      err  :=  conn.Setup()      if  err  !=  nil  {          log.Fatalf("Failed  to  init  amqp  connecJon:  %s",  err)      }   }     func  main()  {      log.Println("StarJng  server  on  8080")      hBp.HandleFunc("/event",  EventHandler)      hBp.ListenAndServe(":8080",  nil)   }