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

3 secrets to build web APIs in Go

3 secrets to build web APIs in Go

Based on his experience with Splice, Matt Aimonetti explores 3 critical elements that made a big difference when building a startup on top of Go.
Talk given at Gopher SummerFest and Google I/O

Matt Aimonetti

June 26, 2014
Tweet

More Decks by Matt Aimonetti

Other Decks in Programming

Transcript

  1. Go vs Ruby 10-20% slower to write 20-100x faster to

    run 60-80% less maintenance required batteries included
  2. Routing var V42Routes = Endpoints{ // create Ableton Live session

    { Verb: "POST", Path: "/v42/live/sessions", Handler: handlers.AlsUpload, RequiredParams: handlers.AlsUploadReqParams, Auth: splice.ClientAuth, }, // create Logic session { Verb: "POST", Path: "/v42/logic/sessions", Handler: handlers.LogicUpload, RequiredParams: handlers.LogicUploadReqParams, Auth: splice.ClientAuth, }, }
  3. Routing package router type Endpoint struct { Verb string Path

    string RequiredParams []string Auth func(*splice.ReqEnv, bool) bool Handler splice.Handler }
  4. Routing type Endpoints []Endpoint // Activate all the endpoint API

    routes. func (es Endpoints) Activate(p *pat.PatternServeMux) { for _, e := range es { // [..] set authentication calls // [..] check param requirements handler := splice.ReqWrap(e.Handler, e.Auth) p.Add(e.Verb, e.Path, handler) // [..] collect all CORS verbs accepted for this endpoint so we can create OPTIONS routes. } }
  5. Routing func ReqWrap(handler *Handler, checkAuthFn func(*ReqEnv, bool) bool) http.Handler {

    ! return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() defer reportRequest(req, start, handler.Metrics) reqUuid := uuid.GenUUID() req := &ReqEnv{ ReqUuid: reqUuid, Request: r, Response: &statusResponseWriter{w, 0}, } // [..] set headers (content type, req ID, build) if !checkAuthFn(req, checkAuth) { return } ! ! !
  6. Routing ! ! ! // We must return a 400

    and stop here if there was a problem // parsing the request. err := req.ParseParams() if err != nil { // […]return 400 return } // convert a panic into a 500 defer req.handlePanic() handler.Handle(req) }) }
  7. Monitoring Monitor all the things! Per endpoint: • # of

    requests • Status codes • Response times