cloud native go
play

Cloud Native Go Building Scalable, Resilient Microservices for the - PDF document

Cloud Native Go 6/28/17, 11)02 AM Cloud Native Go Building Scalable, Resilient Microservices for the Cloud in Go 1 / 29 file:///Users/kimberlyamaral/Desktop/cng-presentation/pres.html#1 Page 1 of 38 Cloud Native Go 6/28/17, 11)02 AM Agenda


  1. Cloud Native Go 6/28/17, 11)02 AM Cloud Native Go Building Scalable, Resilient Microservices for the Cloud in Go 1 / 29 file:///Users/kimberlyamaral/Desktop/cng-presentation/pres.html#1 Page 1 of 38

  2. Cloud Native Go 6/28/17, 11)02 AM Agenda 1. Introduction 2. Boring Stuff 3. Live Demos Cloud Native Go 4. Q & A Building Scalable, Resilient Microservices for the Cloud in Go 2 / 29 1 / 29 file:///Users/kimberlyamaral/Desktop/cng-presentation/pres.html#1 Page 2 of 38

  3. Cloud Native Go 6/28/17, 11)02 AM Agenda Introduction 1. Introduction 2. Boring Stuff Wrote a few books (2 fantasy, 15+ .NET/C#, Go) 3. Live Demos Maker, Tinkerer, Linguist 4. Q & A Taught people how migrate/build cloud native for Pivotal Lead Software Engineer for Capital One Twitter: @KevinHoffman , github autodidaddict Go to gopherize.me gopherize.me for your Gopher Avatar 3 / 29 2 / 29 file:///Users/kimberlyamaral/Desktop/cng-presentation/pres.html#1 Page 3 of 38

  4. Cloud Native Go 6/28/17, 11)02 AM Why Go? Introduction Fast Low memory, CPU, and Disk footprint Wrote a few books (2 fantasy, 15+ .NET/C#, Go) Docker images from SCRATCH Maker, Tinkerer, Linguist Fit more containers per node/VM Taught people how migrate/build cloud native for Pivotal Single, no-dependency binary Lead Software Engineer for Capital One Beautiful, simple language Twitter: @KevinHoffman , github autodidaddict Short learning curve Go to gopherize.me gopherize.me for your Gopher Avatar 4 / 29 3 / 29 file:///Users/kimberlyamaral/Desktop/cng-presentation/pres.html#1 Page 4 of 38

  5. Cloud Native Go 6/28/17, 11)02 AM What is Cloud Native? Why Go? Fast API First Dependency Management Low memory, CPU, and Disk footprint Design, Build, Release, Run Docker images from SCRATCH Config, Credentials, and Code Fit more containers per node/VM Logs Single, no-dependency binary Beautiful, simple language Disposability Backing Services Short learning curve Environment Parity Administrative Processes Port Binding Stateless Processes Concurrency Telemetry Authentication and Authorization 5 / 29 4 / 29 file:///Users/kimberlyamaral/Desktop/cng-presentation/pres.html#1 Page 5 of 38

  6. Cloud Native Go 6/28/17, 11)02 AM What is Cloud Native? Microservices Shopping List API First HTTP Server Dependency Management Routing Design, Build, Release, Run URL path variables Config, Credentials, and Code Query strings Logs JSON Encode/Decode Middleware (logging, security, etc) Disposability Backing Services Environment Parity Administrative Processes Port Binding Stateless Processes Concurrency Telemetry Authentication and Authorization 6 / 29 5 / 29 file:///Users/kimberlyamaral/Desktop/cng-presentation/pres.html#1 Page 6 of 38

  7. Cloud Native Go 6/28/17, 11)02 AM HTTP Server Microservices Shopping List HTTP Server package main Routing import ( URL path variables ... Query strings ) JSON Encode/Decode func main() { Middleware (logging, security, etc) port := os.Getenv("PORT") if len(port) == 0 { port = "8080" } mux := http.NewServeMux() mux.HandleFunc("/", hello) n := negroni.Classic() n.UseHandler(mux) hostString := fmt.Sprintf(":%s", port) n.Run(hostString) } func hello(res http.ResponseWriter, req *http.Request) { fmt.Fprintln(res, "Hello from Go!") } 7 / 29 6 / 29 file:///Users/kimberlyamaral/Desktop/cng-presentation/pres.html#1 Page 7 of 38

  8. Cloud Native Go 6/28/17, 11)02 AM HTTP Server Routing Routing with Gorilla Mux package main import ( r := mux.NewRouter() ... r.HandleFunc("/products/{key}", ProductHandler) ) r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler) r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler) func main() { port := os.Getenv("PORT") if len(port) == 0 { s := r.PathPrefix("/zombies").Subrouter() port = "8080" s.HandleFunc("/", ZombiesHandler) } s.HandleFunc("/sightings", NewSightingHandler).Methods("POST") s.HandleFunc("/{key}", QueryZombieHandler).Methods("GET") mux := http.NewServeMux() mux.HandleFunc("/", hello) URLs: n := negroni.Classic() n.UseHandler(mux) /zombies hostString := fmt.Sprintf(":%s", port) n.Run(hostString) /zombies/sightings (POST) } /zombies/bob (GET) func hello(res http.ResponseWriter, req *http.Request) { fmt.Fprintln(res, "Hello from Go!") } 7 / 29 8 / 29 file:///Users/kimberlyamaral/Desktop/cng-presentation/pres.html#1 Page 8 of 38

  9. Cloud Native Go 6/28/17, 11)02 AM Routing Routing Accessing Route Data Routing with Gorilla Mux r := mux.NewRouter() vars := mux.Vars(req) r.HandleFunc("/products/{key}", ProductHandler) zombieID := vars["zombie-key"] r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler) r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler) Building URLs s := r.PathPrefix("/zombies").Subrouter() r := mux.NewRouter() s.HandleFunc("/", ZombiesHandler) r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). s.HandleFunc("/sightings", NewSightingHandler).Methods("POST") Name("article") s.HandleFunc("/{key}", QueryZombieHandler).Methods("GET") ... url, err := r.Get("article").URL("category", "technology", "id", "42") URLs: Builds - /articles/technology/42 /zombies /zombies/sightings (POST) /zombies/bob (GET) 9 / 29 8 / 29 file:///Users/kimberlyamaral/Desktop/cng-presentation/pres.html#1 Page 9 of 38

  10. Cloud Native Go 6/28/17, 11)02 AM JSON Marshaling Routing Read JSON from Body: Accessing Route Data payload, _ := ioutil.ReadAll(req.Body) vars := mux.Vars(req) zombieID := vars["zombie-key"] var newMatchRequest newMatchRequest err := json.Unmarshal(payload, &newMatchRequest) Building URLs Write JSON to Response: r := mux.NewRouter() var mr newMatchResponse r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). Name("article") mr.copyMatch(newMatch) w.Header().Add("Location", "/matches/"+newMatch.ID) ... url, err := r.Get("article").URL("category", "technology", "id", "42") formatter.JSON(w, http.StatusCreated, &mr) Builds - /articles/technology/42 10 / 29 9 / 29 file:///Users/kimberlyamaral/Desktop/cng-presentation/pres.html#1 Page 10 of 38

  11. Cloud Native Go 6/28/17, 11)02 AM Middleware JSON Marshaling Read JSON from Body: apiRouter := mux.NewRouter() apiRouter.HandleFunc("/api/post", apiPostHandler(formatter)).Methods("POST") payload, _ := ioutil.ReadAll(req.Body) router.PathPrefix("/api").Handler(negroni.New( var newMatchRequest newMatchRequest negroni.HandlerFunc(isAuthorized(formatter)), err := json.Unmarshal(payload, &newMatchRequest) negroni.Wrap(apiRouter), )) Write JSON to Response: func isAuthorized(formatter *render.Render) negroni.HandlerFunc { var mr newMatchResponse return func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { mr.copyMatch(newMatch) providedKey := r.Header.Get(APIKey) w.Header().Add("Location", "/matches/"+newMatch.ID) if providedKey == "" { formatter.JSON(w, http.StatusCreated, &mr) formatter.JSON(w, http.StatusUnauthorized, struct{ Error string }{"Unauthorized." } else if providedKey != apikey { formatter.JSON(w, http.StatusForbidden, struct{ Error string }{"Insufficient credentials." } else { next(w, r) } } } 11 / 29 10 / 29 file:///Users/kimberlyamaral/Desktop/cng-presentation/pres.html#1 Page 11 of 38

  12. Cloud Native Go 6/28/17, 11)02 AM Middleware Shopping List ✅ HTTP Server apiRouter := mux.NewRouter() apiRouter.HandleFunc("/api/post", apiPostHandler(formatter)).Methods("POST") ✅ Routing ✅ URL path variables router.PathPrefix("/api").Handler(negroni.New( negroni.HandlerFunc(isAuthorized(formatter)), ✅ Query strings negroni.Wrap(apiRouter), )) ✅ JSON Encode/Decode ✅ Middleware (logging, security, etc) func isAuthorized(formatter *render.Render) negroni.HandlerFunc { return func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { providedKey := r.Header.Get(APIKey) if providedKey == "" { formatter.JSON(w, http.StatusUnauthorized, struct{ Error string }{"Unauthorized." } else if providedKey != apikey { formatter.JSON(w, http.StatusForbidden, struct{ Error string }{"Insufficient credentials." } else { next(w, r) } } } 12 / 29 11 / 29 file:///Users/kimberlyamaral/Desktop/cng-presentation/pres.html#1 Page 12 of 38

  13. Cloud Native Go 6/28/17, 11)02 AM We're Doing This All Wrong Shopping List ✅ HTTP Server ✅ Routing ✅ URL path variables ✅ Query strings ✅ JSON Encode/Decode ✅ Middleware (logging, security, etc) 13 / 29 12 / 29 file:///Users/kimberlyamaral/Desktop/cng-presentation/pres.html#1 Page 13 of 38

  14. Cloud Native Go 6/28/17, 11)02 AM Do One Thing Great We're Doing This All Wrong A fox knows many things, but a hedgehog one important thing - Archilochus 14 / 29 13 / 29 file:///Users/kimberlyamaral/Desktop/cng-presentation/pres.html#1 Page 14 of 38

Recommend


More recommend