Slide 1

Slide 1 text

Golang Web Services Construindo Web Services com Golang 5 de Fevereiro 2015 – CPBR8 #dev #golang #webservices

Slide 2

Slide 2 text

Edson Hilios Engenheiro @ Centro de Inovação Telefónica | Vivo http://edson.hilios.com.br

Slide 3

Slide 3 text

Agenda 1. Visão geral do Go 2. Introdução a sintaxe 3. Configurando seu workspace 4. Construindo um web service

Slide 4

Slide 4 text

Go aka Golang É uma linguagem desenvolvida por engenheiros do Google em 2007. Com o objetivo de juntar o poder de linguagens como C e Java com a facilidade de escrita e manutenção de código do Python.

Slide 5

Slide 5 text

Quem use Go?

Slide 6

Slide 6 text

Por quê Go? ● Sintaxe simples* ● Alta performance ● Excelente biblioteca padrão ● Compila rapido ● Facil manipulação de threads

Slide 7

Slide 7 text

0 1 2 3 4 5 6 7 8 9 10 Ferramentas $ go build // Compila gerando um executavel $ go run // Compila sem gerar um executavel $ go get // Baixa e instala um pacote $ go install // Compila e instala um pacote $ go test // Executa os testes de um pacote $ go fmt // Formata seu código (Go code-style) $ go vet // Encontra erros que não de compilação $ godoc // Gera a documentação

Slide 8

Slide 8 text

Sintaxe

Slide 9

Slide 9 text

Caracteristicas ● Compilada ● Tipada com inferencia ● Possui primitivos, hash-maps, slices e arrays ● Total acesso a memória ● Garbage-collected ● Não é orientada a objetos ● Paradigmas de linguagem funcional

Slide 10

Slide 10 text

0 1 2 3 4 5 6 7 8 9 10 Hello, World! package main import "fmt" func main() { fmt.Println("Hello, World!") } hello.go

Slide 11

Slide 11 text

0 1 2 3 Executando Execute o comando go run no seu shell. $ go run hello.go Hello, World!

Slide 12

Slide 12 text

0 1 2 3 4 5 6 7 8 9 10 Variaveis package main import "fmt" func main() { var helloWord string helloWord = "Hello, World!" fmt.Println(helloWord) }

Slide 13

Slide 13 text

0 1 2 3 4 5 6 7 8 9 10 Variaveis package main import "fmt" func main() { helloWord := "Hello, World!" fmt.Println(helloWord) }

Slide 14

Slide 14 text

0 1 2 3 4 5 6 7 8 9 10 Variaveis const HELLO_WORLD = "Hello, World!" var ( boleano bool inteiro int pontoFlutuante float64 arrayDeStrings []string matriz3por3 [3][3]int mapaDeInteiros map[int]string ponteiro *string )

Slide 15

Slide 15 text

0 1 2 3 4 5 6 7 8 9 10 Condicionais import "log" if len(x) > 0 { log.Println("Array") } file, err := os.Open("arquivo.txt") if err != nil { log.Fatal(err) }

Slide 16

Slide 16 text

0 1 2 3 4 5 6 7 8 9 10 Loops sum := 0 for i := 0; i < 10; i++ { sum += i } sum := 0 for i, value := range array { sum += value }

Slide 17

Slide 17 text

0 1 2 3 4 5 6 7 8 9 10 func HelloTo(name string) string { fmt.Printf("Hello, %s!", name) } // Documentação da função func MultipleReturn (a int) (int, error) { var err error if True { err = fmt.Errorf("Algo errado!") } return a + 1, err } Funções

Slide 18

Slide 18 text

0 1 2 3 4 5 6 7 8 9 10 Structs type Carro struct { Fabricante, Modelo, Cor string Portas int } focus := Carro{Fabricante: "Ford", Modelo: "Focus", Cor: "Preto", Portas: 5} cruze := new(Carro) cruze.Fabricante = "Chevrolet" // ...

Slide 19

Slide 19 text

0 1 2 3 4 5 6 7 8 9 10 Métodos func (c *Carro) Buzinar() { fmt.Println("Honk!") } func (c *Carro) String() string { return fmt.Srintf("%s %s cor %d %d portas", c.Fabricante, c.Modelo, c.Cor, c.Portas) } // Executa a função focus.Buzinar()

Slide 20

Slide 20 text

0 1 2 3 4 5 6 7 8 9 10 Interfaces type RestService interface { Get(data url.Values) http.HandlerFunc Post(data url.Values) http.HandlerFunc Put(data url.Values) http.HandlerFunc Delete(data url.Values) http.HandlerFunc }

Slide 21

Slide 21 text

Workspace

Slide 22

Slide 22 text

0 1 2 3 4 5 6 7 8 9 10 Estrutura de pastas # ~/Golang # |-- bin/ # |-- src/ # |-- pkg/ mkdir -p ~/Golang/{bin,src,pkg}

Slide 23

Slide 23 text

0 1 2 3 4 5 6 7 8 9 10 Workspace /* ~/Golang |-- src/ | |-- meuprojeto.com/ | | |-- funcionalidade/ | | | |-- *.go */ import "meuprojeto.com/funcionalidade"

Slide 24

Slide 24 text

0 1 2 3 4 5 6 7 8 9 10 Workspace # Configura o caminho de importação/instalação export GOPATH=$(cd ~/Golang; pwd) # Adiciona aos executaveis do OS export PATH=$PATH:$GOPATH/bin ~/.bash_profile

Slide 25

Slide 25 text

Web Service

Slide 26

Slide 26 text

http://hilios.github.io/cpbr8app/

Slide 27

Slide 27 text

Projeto Task ID pk Description string Completed bool Verbo Rota Descrição GET /tasks Lista todas as Tarefas GET /task?id=* Retorna uma Tarefa POST /task?id=* Cria uma nova Tarefa PUT /task?id=* Atualiza uma Tarefa DELETE /task?id=* Deleta uma Tarefa

Slide 28

Slide 28 text

0 1 2 3 4 5 6 7 8 9 10 Estrutura # $GOPATH/src/cpbr8app/ # |-- controllers.go # |-- core.go # |-- db.go # |-- main.go # |-- models.go $ mkdir -p $GOPATH/src/cpbr8app $ cd $GOPATH/src/cpbr8app

Slide 29

Slide 29 text

0 1 2 3 4 5 6 7 8 9 10 package main import "net/http" func helloHandler(rw http.ResponseWriter, r *http.Request) { fmt.Fprint(rw, "Hello, Web!") } func main() { http.HandleFunc("/", helloHandler) http.ListenAndServe(":8000", nil) } main.go Hello, Web! 0 1 2 3 4 5 6 7 8 9 10 11 12

Slide 30

Slide 30 text

http://localhost:8000

Slide 31

Slide 31 text

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import ( "encoding/json" "net/http" "net/url" ) // Interface de um serviço REST type RestInterface interface { Get(values url.Values) (int, interface{}) Post(values url.Values) (int, interface{}) Put(values url.Values) (int, interface{}) Delete(values url.Values) (int, interface{}) } core.go

Slide 32

Slide 32 text

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 func RestController(i RestInterface) http.HandlerFunc { return func(rw http.ResponseWriter, r *http.Request) { r.ParseForm() // Coleta os dados enviados values := r.Form method := r.Method switch method { case "GET": code, data := i.Get(values) case "POST": code, data := i.Post(values) case "PUT": code, data := i.Put(values) // ... o mesmo para DELETE default: code, data := 405, nil } core.go 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

Slide 33

Slide 33 text

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // ... continuação j, err := json.Marshal(data) if err != nil { code = 500 // Internal Server Error } // Lida quando ocorre um erro if code >= 400 { http.Error(rw, http.StatusText(code), code) return } // Escreve o response rw.WriteHeader(code) rw.Write(j) } } core.go 31 32 33 34 35 363 7 38 39 40 41 42 43 44 45 46

Slide 34

Slide 34 text

0 1 2 3 MGO é o driver de MongoDB para Golang, o comando go get baixa o repositório para o seu workspace. Instalando dependencias # Instala a biblioteca em ~/Golang/src $ go get labix.org/v2/mgo

Slide 35

Slide 35 text

0 1 2 3 4 5 6 7 8 9 10 import "labix.org/v2/mgo" var conn *MongoConnection func init() { conn = new(MongoConnection) } db.go Banco de dados

Slide 36

Slide 36 text

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 db.go type MongoConnection struct { session *mgo.Session } func (m *MongoConnection) Connect() { session, err := mgo.Dial("localhost") if err != nil { panic(err) } m.session = session } func (m *MongoConnection) Close() { m.session.Close() }

Slide 37

Slide 37 text

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // Retorna a conexão com o BD global func GetMongoConnection() (*MongoConnection) { return conn } // Retorna uma conexão com o Banco e a sessão utilizada func GetDatabase() (*mgo.Database, *mgo.Session) { session := conn.session.Copy() return session.DB("cpbr8app"), session } db.go

Slide 38

Slide 38 text

0 1 2 3 4 5 6 7 8 9 10 func main() { db := GetMongoConnection() db.Connect() // Executa somente após esta função terminar defer db.Close() http.HandleFunc("/", helloHandler) http.ListenAndServe(":8000", nil) } Conectando ao BD main.go

Slide 39

Slide 39 text

0 1 2 3 4 5 6 7 8 9 10 import "labix.org/v2/mgo/bson" type Task struct { Id bson.ObjectId `bson:"_id" json:"id"` Description string `bson:"desc" json:"desc"` Completed bool `bson:"ok" json:"ok"` } type TaskList struct { Tasks []Task `json:tasks` } Modelo models.go

Slide 40

Slide 40 text

0 1 2 3 4 5 6 7 8 9 10 Modelo func GetTaskList(db *mgo.Database) *TaskList { var tasks []Task collection := db.C("tasks") collection.Find(nil).All(&tasks) return &TaskList{tasks} } models.go

Slide 41

Slide 41 text

0 1 2 3 4 5 6 7 8 9 10 import "net/url" type TasksController struct{} // Retorna uma lista com todas as Tasks func (t *TasksController) Get(v url.Values) (int, i{}) { db, s := GetDatabase() defer s.Close() return 200, GetTaskList(db) } Controlador 0 1 2 3 4 5 6 7 8 9 10 11 12 controllers.go

Slide 42

Slide 42 text

0 1 2 3 4 5 6 7 8 9 10 func main() { // ... conexão com o BD tasks := new(TasksController) http.HandleFunc("/tasks", RestController(tasks)) http.HandleFunc("/", helloHandler) http.ListenAndServe(":8000", nil) } Rotas main.go

Slide 43

Slide 43 text

http://localhost:8000/tasks

Slide 44

Slide 44 text

0 1 2 3 4 5 6 7 8 9 10 Modelo func GetTaskById(db *mgo.Database, id string) *Task { var task Task oid := mgo.ObjectIdHex(id) collection := db.C("tasks") collection.FindId(oid).One(&task) return &task } models.go

Slide 45

Slide 45 text

0 1 2 3 4 5 6 7 8 9 10 Controlador type TaskController struct{} // Retorna a task pelo ID func (t *TasksController) Get(v url.Values) (int, i{}) { db, s := GetDatabase() defer s.Close() task := GetTaskById(v.Get("id")) if task == nil { return 404, nil } return 200, task } controllers.go

Slide 46

Slide 46 text

0 1 2 3 4 5 6 7 8 9 10 func main() { // ... task := new(TaskController) http.HandleFunc("/task", RestController(task)) // ... } Rotas main.go

Slide 47

Slide 47 text

http://localhost:8000/task?id=*

Slide 48

Slide 48 text

Code @ GitHub http://github.com/hilios/cpbr8app/ ● POST, PUT, DELETE ● Suporte a CORS ● App em AngularJS

Slide 49

Slide 49 text

Tks! Golang ref: http://gobyexample.com Twitter: @hilios Site: http://edson.hilios.com.br Apresentação: http://speakerdeck.com/hilios GitHub: http://github.com/hilios