GO Lang para
desenvolvedores
pragmáticos - parte 2
Wilson Júnior
GO Lang para
desenvolvedores
pragmáticos - parte 2
Wilson Júnior
Wilson Júnior
Desenvolvedor
/Globocom/Rio/Backstage
Apaixonado por Tecnologia, Pessoas,
e aprender novas nerdices.
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
Preparados para a segunda batalha ?!
Entre no diretório de batalha!
cd ~/go/src/github.com/SEU-GITHUB/go-course-2
HTTP Server
simples
# já vão rodando um:
$ pushd 1-http-server
HTTP Server simples
Library: net/http
Documentação: godoc.org/net/http
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))
}
Conseguiram ?!
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
HTTP Server
avançado
# já vão rodando um:
$ pushd 2-advc-http-server
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,
}
Lesson 2 - HTTP Server avançado - Exemplo
log.Printf("Running web server on: http://%sn", server.Addr)
log.Fatal(server.ListenAndServe())
}
Escrevendo o
primeiro handler
# já vão rodando um:
$ pushd 3-handler
O que é um http handler
Como descobrir:
https://godoc.org/net/http#Handler
O que é um http handler
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
O que é um http handler
O que é o ResponseWriter ?
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")
}
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))
}
Escrevendo
testes para o
meu handler
# já vão rodando um:
$ pushd 4-handler-test
Como testaremos nosso handler
Library: net/http/httptest
Documentação: godoc.org/net/http/httptest
Lesson 4 - Testando meu http handler - Exemplo
type MyHandlerSuite struct {
handler http.Handler
}
...
func (s *MyHandlerSuite) SetUpSuite(c *check.C)
{
s.handler = &MyHandler{}
}
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")
}
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")
}
Rodem os testes
$ go test .
Encodando JSON
# já vão rodando um:
$ pushd 5-encode-json
Encodando JSON
Library: encoding/json
Documentação: godoc.org/encoding/json
Lesson 5 - Encodando um JSON - Exemplo
type Person struct {
FirstName string
LastName string
Age int
}
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)
}
}
Executem e abram o
browser
http://localhost:8081
Como colocar os
campos como nomes
diferentes.
Lesson 5 - Encodando um JSON - Exemplo
type Person struct {
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
Age int `json:"age"`
}
Lesson 5 - Encodando um JSON - Exemplo
type Person struct {
FirstName string `json:"firstName"`
LastName string
`json:"lastName,omitempty"`
Age int `json:"age"`
}
Executem e vejam a
diferença
Lesson 5 - Encodando um JSON - Exemplo
{
"firstName": "Wilson",
"lastName": "Júnior",
"age": 24
}
Decodando JSON
# já vão rodando um:
$ pushd 6-decode-json
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)
}
Executaremos e testaremos!
curl -i http://127.0.0.1:8081
-d'{"firstName": "Kaio",
"lastName": "Vinicius", "age": 24}'
Existem outros
encoders/decoders
sem ser JSON!
Outros encoders/decoders
XML encoding/xml
CSV encoding/csv
MessagePack github.com/vmihail
enco/msgpack
Mas, Wilson, o net/http suporta
só um Handler ?, como faço para
ter várias rotas diferentes na
minha aplicação ?
Escolha um Router!
O Router também é um Handler!
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
Usando o Roteador HTTP standard
net/http#ServerMux
# já vão rodando um:
$ pushd 7-simple-http-decoder
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))
}
Executaremos e testaremos!
Abram as duas rotas:
http://localhost:8081/g1
http://localhost:8081/gshow
Viu que roteooou !?
Usando o httptreemux
# já vão rodando um:
$ pushd 8-http-treemux
HTTPTreeMux
Library:
github.com/dimfeld/httptreemux
Documentação:
godoc.org/github.com/dimfeld/httptreemux
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))
}
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!")
}
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!")
}
Executaremos e testaremos!
Execute os dois comandos!
curl http://localhost:8081/cars/gol
curl -XPUT http://localhost:8081/cars/fusca
-d'{"name": 1}'
Viu que roteooou !?
Realizando requests http
# já vão rodando um:
$ pushd 9-http-client
Que tal se consultarmos uma API
do github ?
https://api.github.com/users/wpjunio
r
Lesson 9 - Realizando requests HTTP
type User struct {
Name string `json:"name"`
Company string `json:"company"`
}
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()
Lesson 9 - Realizando requests HTTP
user := &User{}
err = json.NewDecoder(res.Body).Decode(user)
return user, err
}
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)
}
}
Conectando no MongoDB
# já vão rodando um:
$ pushd 10-mongodb
Conectando no MongoDB
Library: gopkg.in/mgo.v2
Documentação: godoc.org/gopkg.in/mgo.v2
Inicialize o mongod
$ mongod --config /usr/local/etc/mongod.conf
Lesson 10 - MongoDB
type Person struct {
Id string `bson:"_id"`
Name string `bson:"name"`
Inative bool `bson:inative`
}
Lesson 10 - MongoDB
type PersonRepository struct {
session *mgo.Session
}
Lesson 10 - MongoDB
func NewPersonRepository(session *mgo.Session) *PersonRepository
{
return &PersonRepository{session}
}
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
}
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)
}
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})
}
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
}
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
}
Lesson 10 - MongoDB
func main() {
session, err := mgo.Dial("localhost:27017/go-course")
if err != nil {
log.Fatal(err)
}
repository := NewPersonRepository(session)
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)
}
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"})
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)
}

Golang para desenvolvedores pragmáticos parte 2

  • 1.
  • 2.
  • 3.
    Wilson Júnior Desenvolvedor /Globocom/Rio/Backstage Apaixonado porTecnologia, Pessoas, e aprender novas nerdices.
  • 4.
    Vamos começar oprojeto ● 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.
    Preparados para asegunda batalha ?!
  • 6.
    Entre no diretóriode batalha! cd ~/go/src/github.com/SEU-GITHUB/go-course-2
  • 7.
    HTTP Server simples # jávão rodando um: $ pushd 1-http-server
  • 8.
    HTTP Server simples Library:net/http Documentação: godoc.org/net/http
  • 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.
  • 11.
    Exemplos de Listeningaddresses 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.
    HTTP Server avançado # jávão rodando um: $ pushd 2-advc-http-server
  • 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.
    Lesson 2 -HTTP Server avançado - Exemplo log.Printf("Running web server on: http://%sn", server.Addr) log.Fatal(server.ListenAndServe()) }
  • 15.
    Escrevendo o primeiro handler #já vão rodando um: $ pushd 3-handler
  • 16.
    O que éum http handler Como descobrir: https://godoc.org/net/http#Handler
  • 17.
    O que éum http handler type Handler interface { ServeHTTP(ResponseWriter, *Request) }
  • 18.
    O que éum http handler O que é o ResponseWriter ?
  • 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.
    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.
    Escrevendo testes para o meuhandler # já vão rodando um: $ pushd 4-handler-test
  • 22.
    Como testaremos nossohandler Library: net/http/httptest Documentação: godoc.org/net/http/httptest
  • 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.
    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.
    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.
  • 27.
    Encodando JSON # jávão rodando um: $ pushd 5-encode-json
  • 28.
  • 29.
    Lesson 5 -Encodando um JSON - Exemplo type Person struct { FirstName string LastName string Age int }
  • 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.
    Executem e abramo browser http://localhost:8081
  • 32.
    Como colocar os camposcomo nomes diferentes.
  • 33.
    Lesson 5 -Encodando um JSON - Exemplo type Person struct { FirstName string `json:"firstName"` LastName string `json:"lastName"` Age int `json:"age"` }
  • 34.
    Lesson 5 -Encodando um JSON - Exemplo type Person struct { FirstName string `json:"firstName"` LastName string `json:"lastName,omitempty"` Age int `json:"age"` }
  • 35.
    Executem e vejama diferença
  • 36.
    Lesson 5 -Encodando um JSON - Exemplo { "firstName": "Wilson", "lastName": "Júnior", "age": 24 }
  • 37.
    Decodando JSON # jávão rodando um: $ pushd 6-decode-json
  • 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.
  • 40.
    curl -i http://127.0.0.1:8081 -d'{"firstName":"Kaio", "lastName": "Vinicius", "age": 24}'
  • 41.
  • 42.
    Outros encoders/decoders XML encoding/xml CSVencoding/csv MessagePack github.com/vmihail enco/msgpack
  • 43.
    Mas, Wilson, onet/http suporta só um Handler ?, como faço para ter várias rotas diferentes na minha aplicação ?
  • 44.
  • 45.
    O Router tambémé um Handler!
  • 46.
    Alguns http routersfamosos 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.
    Usando o RoteadorHTTP standard net/http#ServerMux # já vão rodando um: $ pushd 7-simple-http-decoder
  • 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.
  • 50.
    Abram as duasrotas: http://localhost:8081/g1 http://localhost:8081/gshow
  • 51.
  • 52.
    Usando o httptreemux #já vão rodando um: $ pushd 8-http-treemux
  • 53.
  • 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.
    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.
    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.
  • 58.
    Execute os doiscomandos! curl http://localhost:8081/cars/gol curl -XPUT http://localhost:8081/cars/fusca -d'{"name": 1}'
  • 59.
  • 60.
    Realizando requests http #já vão rodando um: $ pushd 9-http-client
  • 61.
    Que tal seconsultarmos uma API do github ?
  • 62.
  • 63.
    Lesson 9 -Realizando requests HTTP type User struct { Name string `json:"name"` Company string `json:"company"` }
  • 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.
    Lesson 9 -Realizando requests HTTP user := &User{} err = json.NewDecoder(res.Body).Decode(user) return user, err }
  • 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.
    Conectando no MongoDB #já vão rodando um: $ pushd 10-mongodb
  • 68.
    Conectando no MongoDB Library:gopkg.in/mgo.v2 Documentação: godoc.org/gopkg.in/mgo.v2
  • 69.
    Inicialize o mongod $mongod --config /usr/local/etc/mongod.conf
  • 70.
    Lesson 10 -MongoDB type Person struct { Id string `bson:"_id"` Name string `bson:"name"` Inative bool `bson:inative` }
  • 71.
    Lesson 10 -MongoDB type PersonRepository struct { session *mgo.Session }
  • 72.
    Lesson 10 -MongoDB func NewPersonRepository(session *mgo.Session) *PersonRepository { return &PersonRepository{session} }
  • 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.
    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.
    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.
    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.
    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.
    Lesson 10 -MongoDB func main() { session, err := mgo.Dial("localhost:27017/go-course") if err != nil { log.Fatal(err) } repository := NewPersonRepository(session)
  • 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.
    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.
    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) }