
Dependency graphs of Go web frameworks - markkit
https://github.com/groob/goviz-frameworks
======
mholt
Just want to highlight a couple points of caution/clarification by groob from
the reddit discussion[1].

In response to "What conclusion should I draw from this?":

> _I don 't think the lesson here is to judge these frameworks. The graph
> alone is not an indication of quality, there are other things to consider. I
> think the lesson is that goviz is awesome and you should run it against your
> own projects, where you know the code well. Having tightly coupled code
> should be avoided. A dependency graph can pinpoint areas of your application
> that are in need of refactoring, as well as code that is either easy or hard
> to remove._

In response to "what's the deal with net/http?"

> _Please don 't draw the wrong conclusion from these graphs. Vault is a
> complex, production ready application which does much more than your typical
> CRUD app. I find the vault http code to be of good quality, and written in
> an idiomatic style. If I was learning how to wrote APIs in Go today, I'd
> look at the vault http package to learn from._

[1]:
[https://www.reddit.com/r/golang/comments/50uni1/dependency_g...](https://www.reddit.com/r/golang/comments/50uni1/dependency_graphs_of_go_web_frameworks/)

------
Ciantic
It would be interesting to see graph on different authors (or people with
publishing and committing rights), to see what sort of attack vector we are
seeing in here.

E.g. Beego there seems to rely only on astaxie's own packages (and Go
packages).

That was my primary take away from NPM debacle, injecting malicious code on
one repository from hundreds of authors of small packackges is risk, whereas
it's not as big with few dependency authors.

------
ajacksified
_Checks dependency graph in his isomorphic React web framework_

This is gonna take a while. Maybe I'll learn Go while my cluster processes the
tree...

~~~
merb
Guess that's impossible without Spark or Hadoop.

~~~
edem
Then try to analyze the dependencies of Hadoop.

------
EthanV2
It would be interesting to see this kind of graph created for other languages
like Python, Node.js, etc. to see how they all compare. It would be neat to
visualise which language/framework has the worst case of dependency hell

Edit: Spelling

~~~
steveklabnik
Two months ago, someone made one for Servo, in Rust:
[https://dirkjan.ochtman.nl/files/servo-
graph.svg](https://dirkjan.ochtman.nl/files/servo-graph.svg)

[https://crates.io/crates/cargo-graph](https://crates.io/crates/cargo-graph)
can be used to produce them easily.

Rust is somewhere between Ruby and Node here: leaning towards small modules
(one of my crates is in this graph, and it exports four functions), but not to
the same level.

    
    
      > It would be neat to visualise which language/framework has
      > the worst case of dependency hell
    

So, one thing I've come to realize is that different people have different
opinions on what "dependency hell" even means. If you have a lot of
dependencies, but your tooling reliably makes it easy to get them, build them,
and upgrade them, is that hell?

~~~
slowmovintarget
There are a number of objective measures of cyclomatic complexity in software.
These metrics show that the higher the complexity, the lower the cohesion of
the code[1].

Code that is complex, and has low cohesion, is harder to understand, and
therefore harder to change. It's the elephant you have to push on every time
you want your program to do something new[2].

    
    
      [1] https://en.wikipedia.org/wiki/Cyclomatic_complexity
      [2] https://www.youtube.com/watch?v=rI8tNMsozo0
    

"Dependency hell" might be subjective, but tools that reduce the upfront cost
of increased dependencies don't remove the other burdens from you, the
developer. In fact they often allow you to produce an impenetrable,
unrecoverable tangle more quickly than doing without them.

Edit: Just realized who I responded to... "But, you knew all that."

~~~
steveklabnik

      > Edit
    

<3

So, what's interesting is, I would often consider many small bits to have a
_lower_ cyclomatic complexity number. That is, whenever I've used tools that
measure this kind of thing, the solution is always to take the big things and
break them up into many, smaller bits. It's possible that this is bias in the
tooling, though.

I think some of this comes down to individual preference as well. It's like
that joke, would you rather fight one horse-sized duck or 100 duck-sized
horses? In this admittedly very stretched metaphor, the former are relatively
monolithic codebases, and the latter are relatively modular ones. I know that
I used to prefer one hundred-line class to ten ten-line classes, but now, much
much prefer the latter. My experience talking to people about this is that
people fall somewhere on this line, often in different places, and that makes
it harder to understand. The action that I'm taking to reduce complexity can
often be perceived as increasing complexity, depending on where the other
person falls on that line.

~~~
slowmovintarget
Lots-of-little-ones (LOLO? LOLO) is the right answer in a number of cases. One
big god service? No; microservices (lots-of-little-ones). Large many-lined
functions with copious branching and conditionals? No, LOLO. Big teams with
multi-hour status meetings? No... LOLO. One big integration at the end of the
project? No...

That dependency diagram for Servo actually looked relatively clean. You can
clearly see which elements are library or utility code. The visualization
would probably be better as a three-dimensional model with weighting.

For OO practice, state of the art is SOLID (with a sprinkling of RAII if you
happen to be using C++). SOLID leads you straight down the path of LOLO. Small
increments FTW.

------
weitzj
That's really great! I went to 'ThoughtWorks On The Beach' in Cologne,
Germany, and there was this really nice idea to just print a dependency graph
of your project to see if you can still grasp it or if it is getting out of
hand.

~~~
karma_vaccum123
Why is this even a concern? We have tools to walk that graph for us, they're
called compilers and linkers. A small codebase can be buggy too.

If you have success with a toolkit and it has good testing and community
support, don't walk away because the graph looks weird.

Take all those frameworks and inline them directly into your main
package...now your graph collapses....are you better off?

~~~
reitanqild
Agree. As long as your dependencies are good so you don't need to open the
hood then don't worry about it.

I just accept it: I'm not an artist or an F1 driver, elegance and unparalleled
performance in the code shouldn't be my concern as long as it is solid and
works. I'm in the business of solving business problems, not at scale, not in
realtime but on a shoestring budget.

~~~
eikenberry
Elegance is the quality in code that makes it easy to understand, easy to
extend and easy to maintain. It is what makes code solid. Code is art.

------
inglor
Could someone tell me what sort of useful information I can distill out of
those graphs?

I'm really not sure at the package level what conclusions we can draw outside
of "many circular dependencies - bad".

I don't think the graphs would be very difference in Node for example - but
unless you're doing something like chunked code bundling I don't understand
why this information is meaningful.

~~~
karma_vaccum123
Go doesn't allow circular dependencies so rest easy.

------
zalmoxes
r/golang discussion:

[https://www.reddit.com/r/golang/comments/50uni1/dependency_g...](https://www.reddit.com/r/golang/comments/50uni1/dependency_graphs_of_go_web_frameworks/)

Also relevant: [https://talks.godoc.org/github.com/broady/talks/web-
framewor...](https://talks.godoc.org/github.com/broady/talks/web-frameworks-
gophercon.slide#1)

------
petre
Go and Node's problem is the dependency hell. Caddy, a simple HTTP 2
webserver, pulled N packages to build. There are Node packages depending on
trivial things (remember left-pad?). Too much modularity and relying on
others' work sucks. Go's problem is solved by static linking, and Node's by
installing all the required libraries in the node_modules directory.

~~~
justinsaccount
> Go and Node's problem is the dependency hell.

Just these two languages? No other languages or systems have problems with
dependencies?

> Caddy, a simple HTTP 2 webserver

Caddy is simple to use, but is not a "simple" server. This is a simple server:

    
    
      package main
    
      import "net/http"
    
      func main() {
          panic(http.ListenAndServe(":8080", http.FileServer(http.Dir("./"))))
      }
    

> Too much modularity and relying on others' work sucks

One of the things caddy implements is automatic ssl support by depending on a
library that implements the acme protocol. This type of thing is not exactly
simple or something you really want to be writing from scratch if you don't
have to.

The problem with node is that there is no such thing as a javascript standard
library and javascript tooling is not great at dead code elimination. This
results in many trivial libraries that each contain a single function. Once
the tooling gets better at dead code elimination there should be fewer larger
libraries.

------
epse
What's up with Revel? That's crazy!

~~~
breakingcups
Syscall package for fsnotify. It's not that weird.

~~~
sethammons
Thinking of fsnotify, know that it is configured to only be able to handle a
given amount of notifications at a time. I ran into an issue where the number
of monitored files exceeded that, and it silently ignored new files that were
being created. Learned the hard way: check your OS for how to configure it and
make sure you operate within its bounds. Or, said a different way, know your
tools before you rely on them.

------
vhost-
No gorilla mux?

