Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

Golang para desenvolvedores pragmáticos parte 2

175 Aufrufe

Veröffentlicht am

Curso ministrado na Globo.com

Veröffentlicht in: Software
  • Als Erste(r) kommentieren

Golang para desenvolvedores pragmáticos parte 2

  1. 1. GO Lang para desenvolvedores pragmáticos - parte 2 Wilson Júnior
  2. 2. GO Lang para desenvolvedores pragmáticos - parte 2 Wilson Júnior
  3. 3. Wilson Júnior Desenvolvedor /Globocom/Rio/Backstage Apaixonado por Tecnologia, Pessoas, e aprender novas nerdices.
  4. 4. Vamos começar o projeto ● Faça o fork do projeto em github.com/wpjunior/go-course-2 ● brew install go # 1.8 ● Baixe seu projeto com `go get github.com/SEU-USUARIO-GITHUB/go-cour se-2` Esperamos que vocês já tenham configurado o projeto mais ou menos assim
  5. 5. Preparados para a segunda batalha ?!
  6. 6. Entre no diretório de batalha! cd ~/go/src/github.com/SEU-GITHUB/go-course-2
  7. 7. HTTP Server simples # já vão rodando um: $ pushd 1-http-server
  8. 8. HTTP Server simples Library: net/http Documentação: godoc.org/net/http
  9. 9. Lesson 1 - Simple http server package main import ( "log" "net/http" ) func main() { addr := "127.0.0.1:8081" log.Printf("Running web server on: http://%sn", addr) log.Fatal(http.ListenAndServe(addr, nil)) }
  10. 10. Conseguiram ?!
  11. 11. Exemplos de Listening addresses Addr Descrição "127.0.0.1:8081" Rodará em apenas no endereço 127.0.0.1 na porta 8081, os outros endereços disponíveis da máquina não acessarão a porta 8081 ":8081" Rodará em todos os endereços da máquina na porta 8081 "0.0.0.0:8081" Rodará em todos os endereços da máquina na porta 8081
  12. 12. HTTP Server avançado # já vão rodando um: $ pushd 2-advc-http-server
  13. 13. Lesson 2 - HTTP Server avançado - Exemplo package main import ( "log" "net/http" "time" ) func main() { server := &http.Server{ Addr: "127.0.0.1:8081", Handler: nil, ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, IdleTimeout: time.Second, }
  14. 14. Lesson 2 - HTTP Server avançado - Exemplo log.Printf("Running web server on: http://%sn", server.Addr) log.Fatal(server.ListenAndServe()) }
  15. 15. Escrevendo o primeiro handler # já vão rodando um: $ pushd 3-handler
  16. 16. O que é um http handler Como descobrir: https://godoc.org/net/http#Handler
  17. 17. O que é um http handler type Handler interface { ServeHTTP(ResponseWriter, *Request) }
  18. 18. O que é um http handler O que é o ResponseWriter ?
  19. 19. Lesson 3 - Escrevendo o primeiro handler - Exemplo package main import ( "fmt" "log" "net/http" ) type MyHandler struct{} func (h *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello warriors") }
  20. 20. Lesson 3 - Escrevendo o primeiro handler - Exemplo func main() { addr := "127.0.0.1:8081" handler := &MyHandler{} log.Printf("Running web server on: http://%sn", addr) log.Fatal(http.ListenAndServe(addr, handler)) }
  21. 21. Escrevendo testes para o meu handler # já vão rodando um: $ pushd 4-handler-test
  22. 22. Como testaremos nosso handler Library: net/http/httptest Documentação: godoc.org/net/http/httptest
  23. 23. Lesson 4 - Testando meu http handler - Exemplo type MyHandlerSuite struct { handler http.Handler } ... func (s *MyHandlerSuite) SetUpSuite(c *check.C) { s.handler = &MyHandler{} }
  24. 24. Lesson 4 - Testando meu http handler - Exemplo func (s *MyHandlerSuite) TestOK(c *check.C) { w := httptest.NewRecorder() r, _ := http.NewRequest(http.MethodGet, "/", nil) s.handler.ServeHTTP(w, r) c.Assert(w.Code, check.Equals, http.StatusOK) c.Assert(w.Body.String(), check.Equals, "Hello warriors") }
  25. 25. Lesson 4 - Testando meu http handler - Exemplo func (s *MyHandlerSuite) TestFail(c *check.C) { w := httptest.NewRecorder() r, _ := http.NewRequest(http.MethodGet, "/", nil) s.handler.ServeHTTP(w, r) c.Check(w.Code, check.Equals, http.StatusNotFound) c.Assert(w.Body.String(), check.Equals, "Fail") }
  26. 26. Rodem os testes $ go test .
  27. 27. Encodando JSON # já vão rodando um: $ pushd 5-encode-json
  28. 28. Encodando JSON Library: encoding/json Documentação: godoc.org/encoding/json
  29. 29. Lesson 5 - Encodando um JSON - Exemplo type Person struct { FirstName string LastName string Age int }
  30. 30. Lesson 5 - Encodando um JSON - Exemplo func (h *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { person := &Person{ FirstName: "Wilson", LastName: "Júnior", Age: 24, } encoder := json.NewEncoder(w) err := encoder.Encode(person) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } }
  31. 31. Executem e abram o browser http://localhost:8081
  32. 32. Como colocar os campos como nomes diferentes.
  33. 33. Lesson 5 - Encodando um JSON - Exemplo type Person struct { FirstName string `json:"firstName"` LastName string `json:"lastName"` Age int `json:"age"` }
  34. 34. Lesson 5 - Encodando um JSON - Exemplo type Person struct { FirstName string `json:"firstName"` LastName string `json:"lastName,omitempty"` Age int `json:"age"` }
  35. 35. Executem e vejam a diferença
  36. 36. Lesson 5 - Encodando um JSON - Exemplo { "firstName": "Wilson", "lastName": "Júnior", "age": 24 }
  37. 37. Decodando JSON # já vão rodando um: $ pushd 6-decode-json
  38. 38. Lesson 6 - Decodando um JSON - Exemplo func (h *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { person := &Person{} decoder := json.NewDecoder(r.Body) err := decoder.Decode(person) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } fmt.Fprintln(w, "Recebemos o json!") fmt.Fprintf(w, "first name: %sn", person.FirstName) fmt.Fprintf(w, "last name: %sn", person.LastName) fmt.Fprintf(w, "age: %dn", person.Age) }
  39. 39. Executaremos e testaremos!
  40. 40. curl -i http://127.0.0.1:8081 -d'{"firstName": "Kaio", "lastName": "Vinicius", "age": 24}'
  41. 41. Existem outros encoders/decoders sem ser JSON!
  42. 42. Outros encoders/decoders XML encoding/xml CSV encoding/csv MessagePack github.com/vmihail enco/msgpack
  43. 43. Mas, Wilson, o net/http suporta só um Handler ?, como faço para ter várias rotas diferentes na minha aplicação ?
  44. 44. Escolha um Router!
  45. 45. O Router também é um Handler!
  46. 46. Alguns http routers famosos Pacote Pós Const net/http#ServeMux Vem na standard library, pode atender casos simples de uso. Não permite casos como roteamento por template, regex, nem por verbo http httptreemux Utiliza um algoritmo usando radix, é rápido e possui roteamento por verbos http. Mais um pacote para manter, no meio a tantos pacotes de routing. Outros routers https://github.com/avelino/awesome-go#web-frameworks
  47. 47. Usando o Roteador HTTP standard net/http#ServerMux # já vão rodando um: $ pushd 7-simple-http-decoder
  48. 48. Lesson 7 - Usando o roteador HTTP standard - Exemplo func main() { addr := "127.0.0.1:8081" router := http.NewServeMux() router.Handle("/g1", &G1Handler{}) router.Handle("/gshow", &GShowHandler{}) log.Printf("Running web server on: http://%sn", addr) log.Fatal(http.ListenAndServe(addr, router)) }
  49. 49. Executaremos e testaremos!
  50. 50. Abram as duas rotas: http://localhost:8081/g1 http://localhost:8081/gshow
  51. 51. Viu que roteooou !?
  52. 52. Usando o httptreemux # já vão rodando um: $ pushd 8-http-treemux
  53. 53. HTTPTreeMux Library: github.com/dimfeld/httptreemux Documentação: godoc.org/github.com/dimfeld/httptreemux
  54. 54. Lesson 8 - Usando o httptreemux - Exemplo func main() { addr := "127.0.0.1:8081" router := httptreemux.NewContextMux() router.Handler(http.MethodGet, "/cars/:id", &GetCarHandler{}) router.Handler(http.MethodPut, "/cars/:id", &UpsertCarHandler{}) log.Printf("Running web server on: http://%sn", addr) log.Fatal(http.ListenAndServe(addr, router)) }
  55. 55. Lesson 8 - Usando o httptreemux - Exemplo type UpsertCarHandler struct{} func (h *UpsertCarHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { params := httptreemux.ContextParams(r.Context()) fmt.Fprintf(w, "Eu deveria criar um carro chamado: %s!", params["id"]) fmt.Fprintln(w, "Não crio por que sou mal!") }
  56. 56. Lesson 8 - Usando o httptreemux - Exemplo type GetCarHandler struct{} func (h *GetCarHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { params := httptreemux.ContextParams(r.Context()) fmt.Fprintf(w, "Eu deveria buscar um carro chamado: %s!", params["id"]) fmt.Fprintln(w, "Não busco por que estou com preguiça!") }
  57. 57. Executaremos e testaremos!
  58. 58. Execute os dois comandos! curl http://localhost:8081/cars/gol curl -XPUT http://localhost:8081/cars/fusca -d'{"name": 1}'
  59. 59. Viu que roteooou !?
  60. 60. Realizando requests http # já vão rodando um: $ pushd 9-http-client
  61. 61. Que tal se consultarmos uma API do github ?
  62. 62. https://api.github.com/users/wpjunio r
  63. 63. Lesson 9 - Realizando requests HTTP type User struct { Name string `json:"name"` Company string `json:"company"` }
  64. 64. Lesson 9 - Realizando requests HTTP func GetGithubUser(username string) (*User, error) { url := fmt.Sprintf("https://api.github.com/users/%s", username) req, _ := http.NewRequest(http.MethodGet, url, nil) res, err := http.DefaultClient.Do(req) if err != nil { return nil, err } defer res.Body.Close()
  65. 65. Lesson 9 - Realizando requests HTTP user := &User{} err = json.NewDecoder(res.Body).Decode(user) return user, err }
  66. 66. Lesson 9 - Realizando requests HTTP func main() { user, err := GetGithubUser(MyUsername) if err == nil { log.Printf("Temos o usuário: %#vn", user) } else { log.Println("Falha ao buscar usuário: ", err) } }
  67. 67. Conectando no MongoDB # já vão rodando um: $ pushd 10-mongodb
  68. 68. Conectando no MongoDB Library: gopkg.in/mgo.v2 Documentação: godoc.org/gopkg.in/mgo.v2
  69. 69. Inicialize o mongod $ mongod --config /usr/local/etc/mongod.conf
  70. 70. Lesson 10 - MongoDB type Person struct { Id string `bson:"_id"` Name string `bson:"name"` Inative bool `bson:inative` }
  71. 71. Lesson 10 - MongoDB type PersonRepository struct { session *mgo.Session }
  72. 72. Lesson 10 - MongoDB func NewPersonRepository(session *mgo.Session) *PersonRepository { return &PersonRepository{session} }
  73. 73. Lesson 10 - MongoDB func (r *PersonRepository) Create(p *Person) error { session := r.session.Clone() defer session.Close() collection := session.DB("").C(PersonCollection) err := collection.Insert(p) if mongoErr, ok := err.(*mgo.LastError); ok { if mongoErr.Code == 11000 { return ErrDuplicatedPerson } } return err }
  74. 74. Lesson 10 - MongoDB func (r *PersonRepository) Update(p *Person) error { session := r.session.Clone() defer session.Close() collection := session.DB("").C(PersonCollection) return collection.Update(bson.M{"_id": p.Id}, p) }
  75. 75. Lesson 10 - MongoDB func (r *PersonRepository) Remove(id string) error { session := r.session.Clone() defer session.Close() collection := session.DB("").C(PersonCollection) return collection.Remove(bson.M{"_id": id}) }
  76. 76. Lesson 10 - MongoDB func (r *PersonRepository) FindAllActive() ([]*Person, error) { session := r.session.Clone() defer session.Close() collection := session.DB("").C(PersonCollection) query := bson.M{"inative": false} documents := make([]*Person, 0) err := collection.Find(query).All(&documents) return documents, err }
  77. 77. Lesson 10 - MongoDB func (r *PersonRepository) FindById(id string) (*Person, error) { session := r.session.Clone() defer session.Close() collection := session.DB("").C(PersonCollection) query := bson.M{"_id": id} person := &Person{} err := collection.Find(query).One(person) return person, err }
  78. 78. Lesson 10 - MongoDB func main() { session, err := mgo.Dial("localhost:27017/go-course") if err != nil { log.Fatal(err) } repository := NewPersonRepository(session)
  79. 79. Lesson 10 - MongoDB // creating a person person := &Person{Id: "123", Name: "Juliana"} err = repository.Create(person) if err == ErrDuplicatedPerson { log.Printf("%s is already createdn", person.Name) } else if err != nil { log.Println("Failed to create a person: ", err) }
  80. 80. Lesson 10 - MongoDB // updating a person person.Name = "Juliana updated" err = repository.Update(person) if err != nil { log.Println("Failed to update a person: ", err) } repository.Create(&Person{Id: "124", Name: "Marcos"}) repository.Create(&Person{Id: "125", Name: "Kaio", Inative: true}) repository.Create(&Person{Id: "126", Name: "Gabriel"}) repository.Create(&Person{Id: "127", Name: "Maisa"})
  81. 81. Lesson 10 - MongoDB // findAll people, err := repository.FindAllActive() if err != nil { log.Println("Failed to fetch people: ", err) } for _, person := range people { log.Printf("Have in database: %#vn", person) }

×