Skip to content

Instantly share code, notes, and snippets.

@dev-rice
Last active August 11, 2017 00:51
Show Gist options
  • Save dev-rice/fadbac649ba5d623e2098aebeca17256 to your computer and use it in GitHub Desktop.
Save dev-rice/fadbac649ba5d623e2098aebeca17256 to your computer and use it in GitHub Desktop.
  1. When first writing code where you call a function that returns an error make it panic(err). This is like a TODO in code because you will catch it in a diff.

  2. https://github.com/rosenhouse/counter-demo/blob/master/server/main.go#L18 All dependencies are in main. There are no inter package dependencies so if you look at a dependency graph it would be a wide tree with depth of 1.

    One way to achieve this is to have an exported struct that depends on unexported interfaces. This makes it so you don't have to have dependencies between files

    package handlers
    
    import (
      "fmt"
      "net/http"
      "strings"
    )
    
    type packageLinesCounter interface {
      Count(packagePath string) (int, error)
    }
    
    type Lines struct {
      Counter packageLinesCounter
    }
    
    func (h *Lines) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
      pkgPath := strings.TrimPrefix(req.URL.Path, "/lines/")
      lines, err := h.Counter.Count(pkgPath)
      if err != nil {
        resp.WriteHeader(500)
        resp.Write([]byte(fmt.Sprintf(`{"error": %q}`, err)))
        return
      }
      resp.Write([]byte(fmt.Sprintf(`{"lines": %d}`, lines)))
    }
  3. Only pass things as arguments when you know that it is something that can be changed. With the case above if there was a request logger that had a guid attached to it, you would need the first argument of every public method be a logger. This could not bet set in main because we know that it is going to change for every single request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment