Over at PostRank we serve a lot of data through our API servers. All of those servers parse query strings. Along with, obviously, the query string, we also encode the post data in query string format. This means we’re doing a lot of parsing of query strings. Millions of query strings a day.

Parsing time for those query strings starts to add up. We started with the query string parser from Camping and that served us well for over a year. Eventually, parsing the query data was over 80% of the processing time and something needed to be done. From there we briefly dabbled with the Rack::Utils query string parser. While faster, this still wasn’t fast enough.

From Rack, in a fit of desperation, we wrote our own. With the new version, written in C using Inline Ruby, we were finally fast enough. The parser has served us well but was starting to show some age with the Inline Ruby. We’ve started using Ruby 1.9 for our new API servers while the old servers were on 1.8. RVM doesn’t deal with Ruby Inline very well and we’d end up having to erase the Inline cache when switching between server versions. To that end, we converted the Inline Ruby version into a Ruby extension and, to help deal with Bundler, decided to push it out the door as a gem.

You can check it out on Github or install the gem from gemcutter. At this point, the gem does what we need it too. It doesn’t handle every case, but you should be able to update it, if needed, to handle what you need.

require 'query_string_parser'
p QueryStringParser.qs_parse("my=query&string=parser")
=> {"my"=>"query", "string"=>"parser"}

include QueryStringParser
qs_parse("does[]=array&does[]=data&does[3]=values&does=more")
=> {"does"=>["array", "data", "values", "more"]}

As you can see from the example above individual params will be set their values. If a parameter exists multiple times it will be turned into an array of values. You can set a number into the brackets but it will be ignored by the parser.

If you’re parsing a lot of query strings give the parser a try. Let us know what you think.