Sunday, October 16, 2016

Why you should not use iris for your Go projects

To make this clear, this is my opinion and mine only. Nobody else was involved in creating this, nor does it have a secret agenda or anything like that. The authors of the mentioned libraries have no link to me nor should you go after them. If you have anything to say about this, please use the comments section below and I'll do my best to answer when needed. If your comment somehow ends up in a moderation queue, I promise that I will publish it as soon as time permits (and as longs as it's not real spam OR contains foul language). Thank you for understanding.

Update five:
Since my article appeared in the latest Go newsletter the following happened:
- the history of iris was rewritten (again)
- the project went from a lot of commits to a single squashed commit back to multiple commits
- I've been called a liar and a competitor of iris (not sure how since I'm not even remotely related to writing muxers or web frameworks for Go)
- I've been blocked by the kataras on iris so I can't properly defend myself against being called a liar, with video proof:
- more importantly: the authors got their attributions back. And that's the single most important thing.

I apologize for everyone trying to use iris in the past days, it probably was your worst Go experience ever (due to so many rewrites). I can promise you that there are a lot better and more mature projects out there and these kind of issues have never happened to them.
You can keep reading if you want but at this point it's going to look like I'm a liar and a scum. So be it. But have a look at this: and because honestly I don't have the time to fake all of this and I' more busy than you can probably ever imagine.

Update six:
Because once it's on the internet it's out there for good... How do you think I've faked this fork: or this ?

Again, with screenshots to make sure we have some more Photoshop skills to add to my cv:

I wonder how those folks got with that history like that :)

Original text:

I've said it so many times to various gophers I guess it's time to put it on a blog post: iris is a toxic framework and you should not use it at all.

Probably there will be people saying that I should write this but I see no other option as I have no power to simply remove it from the Internet. So instead I prefer to tell people why it's toxic and why they should stay away from it. Click here if you trust me and want to see the alternatives out there.

iris looks good on paper, it offers everything you'd need to do web development in Go but once you start using it you'll realize sooner or later that it has some fundamental flaws.

Lets start with the components it's stealing the code from (I'll come back to the stealing part later). The base package it's using is the amazing which is a different implementation of the http protocol than the standard library net/http. The package authors make it clear in their Readme/FAQ section that the implementation is not compatible with the net/http one. What's more, they state explicitly that due to the design philosophy of fasthttp, certain corner cases net/http handles are dropped. But perhaps the biggest gotcha is that it currently does not support http2. You might say that's fine, you don't need it. But if you want to use any other technology such as gRPC, you are out of luck.
So why is this of any concern then for iris users? Because iris does not make this effort (at the time of writing) to make the users aware of these limitations.

Moving forward, another well known Go package iris is stealing from is This has been well documented in the past: and after all the efforts that the community had to try to fix this, the project relapsed again after just a few short months, see You might argue that httprouter is open-source and it's ok for the author of iris to use it, and that's fine, the problem is that nowhere near the project you'll see the license of httprouter nor the attribution of code, as required by the license.

And these are just a couple of examples.

The thing that seem to attract the most people are benchmarks. What many people don't realize is that the benchmarks have been debunked a few good times. Take for example this PR to change the results of a well known benchmark comparing the various http routers Go has and read this comment and the following ones. Fortunately there people were not tricked by iris caching your responses. How would you feel if your API would suddenly get a cache without you asking for it? Probably in some cases it would be ok but what about cases where it's very important not to? Simply by having caching turned on by default, iris is not playing on a even field as as the rest of out there which allow YOU to have control over YOUR application, the way it should be. To this day the author refuses to acknowledge this.

People fear when they see those benchmarks that their app will be slow because of this. In reality, any project that will do a decoding from JSON, call the network the handler they execute or, worse, touch the disk the cost of the http router / net/http will be insignificant in comparison to the costs of handling the request. There are definitely projects that will have bottlenecks in various parts but realistically, if your http router appears in your pprof, please contact me as I would be happy to be proven wrong.

Let's look at the project from another perspective.

The first thing that should trigger a "huh, I need to look a bit more into this" reaction is: there is a single contributor to it. And it was always a single contributor. The author of the project actively rejects PRs and the occasional accident when a PR gets merged that contribution will be obliterated any time soon after, when the author decides to flatten the history of the repository (again). Which helps deliver the next point, API stability.
But before that, I'll briefly mention that the issues that are opened on Github are almost always edited to reflect a different reality, comments get deleted and conversations get locked. It happened to me (I admit that I could have done better in the initial message but I couldn't change things as my issue was instantly locked by the author and I couldn't do anything about it anymore).

The author is simply trying to paint a different reality than the one experienced by everyone else and this is dangerous. Will you trust your production code on this?

Back to API stability.
If anything, most of the Go projects that have been out there for a while can brag about the stability of their API. And for a good reason. Projects like gorilla/mux, httprouter, fasthttp, have a vast, rich history, filled with contributors. fasthttp mentions that things might break ocassionaly (and I have no statistics about how often that happens), but when used by so many people, they will tend to follow the "Go way" of not breaking stability to the best of their extent.
Even with the advent of a proper package manager, I think the authors of gorilla/mux will not suddenly start and break things apart because they can do so now. Oh and in the 3.5 years I've been using Go and I've first used gorilla/mux all the projects I've wrote can still compile against it. That's a really fantastic job from all the persons involved in the project.

If I haven't convinced you yet here's the last point.

The author now receives donations for iris. And don't get me wrong, it's within his right to do BUT... remember when I said that the projects iris is based at its core are.
There are other components which the author at least mentions briefly in the Readme (but again without mentioning their license) are in a state where I can't judge but probably they should be mentioned.
And remember the other contributors to the project? Ah, right, you can't can you, because there's no history to show them, to show their work, the fact that they've put maybe hours or more into getting something done just so that they are either denied or obliterated from history.

Here we are, at the end of this rather long article, probably left with a question, what should you use instead then?

There are many projects out there which are great and can be used, but as always, it always depends on your needs.
Someone was asking last night what framework should he use for a four pages and a form website written in Go. For that, net/http should be more than enough to handle but here is a list, not exhaustive by any means of projects I think can fit the needs of many (if not all) devs out there:

- net/http -> obvious choice for very simple projects
- gorilla/mux, julienschmidt/httprouter -> for anything else.
- there are more out there and probably some are just as good but I don't have experience with them so I can't recommend them. I've seen people using: pressly/chi, some using labstack/echo and others having various other choices

They can all be used with things such as urfave/negroni or GoKit for handling the middleware part of your apps. negroni is pretty simple to use GoKit can look a bit intimidating in the beginning but it's is extremely powerful.

For databases, if you are using SQL then jmoiron/sqlx is an excellent complement to the database/sql.

These are all components which play well with the standard library, follow established patterns and above all, are composable, one of the best features of Go.

You might feel that you need a framework, especially if you are coming from another programming language which has terrible support for HTTP interaction, but I can assure you that once you've experienced how things are supposed to be done in Go, you will feel liberated and the control you'll gain over how your application works will be unprecedented.

In conclusion, iris could have been a nice project, maybe even an interesting one, but all the issues that the project leadership display from cheating to stealing makes it a no-go. There are plenty alternatives out there, all brilliant, all truly open-source and all ready to be used in your next Go project.


On 17/10/2016, the author decided to make a PR to have a his library added again into the awesome-go collection. When things didn't go his way, the following happened:
- he changed his github handle to then revert to the previous out. If you've had problems fetching iris, that's why it happened
- started using language that is really not nice (see below)
(this was taken literally after the Github comment appeared in the UI, you can recognize the nice glowing yellow)
- there have been other heavier words exchanged, as you can see from some other replies, but I would not advise using them.

This just proves once again that in a simple conversation, when things don't go the way the author desires he will just revert to primitive language and he would rather have things broken (see the renaming that happened) rather than try to work his way on this.

It's sad because I really don't enjoy doing this and I sure would have liked to spend my time doing something better for the community than writing these lines.

Update two:
Before the author figures out how to remove the closed PRs, here's a couple of those merged ones, as you can see, their authors do not appear in the contributors list anymore:

And this little gem:

Update three: typos :D

Updated four:

It seems the author has done it again and wiped all the git history and at least some libraries got their license added to the list.
I guess I should apologize to the users for breaking their repositories once again. Sorry about that.
Probably I'm going to be accused by him and his "followers" (strangely enough there are only 1-2 people, always the same ones) for lying and spreading false things in the next hours and this will continue for a couple more days.
This lasted about 4-5 months last time, back then someone else exposed the issue and the pattern seems to be repeating itself.
At least people get their rightful attributions meanwhile.

Sunday, September 18, 2016

Using dependency injection in Go

There are three ways to handle dependency injection done in Go.

Explicit, by sending the dependency to your function / method call.

Creating a wrapper to handle injecting that dependency into the code of the of the which can then be used everywhere else in the application.

Adding a field to the structure you already have with the dependency you need.

I've used the log.Printf function especially because logging can become a dependency.
Instead of importing the "log" package then calling log.Printf every time, you should be inject that as a dependency.
This can be useful in order to allow the existence of two (or more) log levels or for swapping out logging libraries without changing the code itself every time you do it.

Sunday, June 5, 2016

How to halve the performance of NATS?

Rename the subject from "a" to "MyTopicName" :)

go get for Github Chrome extension

As I'm a Go user and I frequently get packages from Github, I've made this little extension to help me out running "go get" quicker.

It works by detecting if the repository contains any "significant" amount of Go in it (using the Github breakdown of languages) and adds a button that you can click and have in the clipboard the "go get" command for that repository. There are a few options as well to control the format of the command.

It looks like this:
It's available here: and the sources are available here: Hope you'll find it useful.

Saturday, May 28, 2016

Visualizing profiling in Go: A different way

Many of you will read these lines and know already a bit about how Go can help you out and profile your applications. If not, you can have a quick look at this article Profiling Go Programs from the Go blog. As a testimony to the language, this article predates the Go 1.0 release by almost a year yet it still works today, 4 years after the initial launch of Go. In the next years it will be able to go to school and make friends. But I digress.

So, profiling in Go is a joy and Go already gives you nice tools to visualize the information. Can we do better? For example some folks at Uber thinks so and they've built They also have a wonderful presentation about it, check it out here: Profiling and Optimizing Go . But they've built it. Could we use something that exists already?

The answer is Yes! Of course we can. Because it's Go, and it's amazing, we can use KCacheGrind (and it's cousins) to visualize callgrind profiles, not to mention get a nice visualization while at it.

To give you a quick example:
  • first profile your code and save the profile as profile
  • then run go tool pprof -callgrind -output=profile.grind binaryName profile
  • the launch KCacheGrind and open profile.grind

And to give an example of how this looks like for an application, here are a few screenshots. Thank you to Olivier Gagnon for offering his code for this post.

The code below assumes Linux (Ubuntu specifically but you should be able to get it running on other platforms as well):

// First lets install the dependencies
sudo apt-get install libxrandr-dev libxcursor-dev libxinerama-dev libxi-dev

// Fetch the source code
go get

cd $GOPATH/src/

// In the import () section add:

// Right after main() { opens, add:
    f, err := os.Create("./profile")
    if err != nil {
    defer pprof.StopCPUProfile()

// Build the application
go build -o engine main_dev.go

// And run it

// Wait at least a few seconds and then press Esc to quit it

// Get the profile in callgrind format
go tool pprof -callgrind -output=profile.grind engine profile

// Finally run KCacheGrind
kcachegrind profile.grind

Note, at the time of writing the code was in flux so I had to change this:

@@ -160,8 +169,8 @@ func main() {

gravity := glm.Vec3{0, -5, 0}
gravFG := tornago.NewGravityForceGenerator(&gravity)
- w.AddForceGenerator(boxBody, &gravFG)
- w.AddForceGenerator(boxBody2, &gravFG)
+ w.AddForceGenerator(boxBody, gravFG)
+ w.AddForceGenerator(boxBody2, gravFG)

_ = str

Thank you.