Picky's Coming of Age

ruby / picky / api

I’m gonna talk about what bothers me in Picky’s current configuration and what I’d like to propose for 2.0. Opinions or ideas for new API features are very welcome!

A spot of bother

Since releasing 1.0, something’s always bothered me about Picky’s configuration.

I used to think it’s the abundance of class methods used in definining indexing, querying, or routing:

class MyBeooootifulPickySearch < Application

  default_indexing removes_characters: /[^äöüa-zA-Z0-9\s\/\-\"\&\.]/
  # etc.


I usually prefer instances on which I define things. In a nutshell, it’s more easily testable. But this is not really the problem.

So, what is it that is bothering me?

What is really bothering me

Take a look at how routing and queries are defined:

Here, we’re routing /all/full, /all/live to queries which includes three indexes, and /contacts/full, /contacts/live to queries with just the contacts index:

route %r{\A/all/full\Z}      => Query::Full.new(accounts_index, users_index, contacts_index),
      %r{\A/all/live\Z}      => Query::Live.new(accounts_index, users_index, contacts_index),
      %r{\A/contacts/full\Z} => Query::Full.new(contacts_index),
      %r{\A/contacts/live\Z} => Query::Live.new(contacts_index)

In the last sentence, I mention two things that are routed – why do I need double the number of route definitions?

Full and Live queries. Why?

Let me talk a little about the client why this is so.

The Picky client does two different types of queries:

A full query needs to be enriched with rendered results, e.g. with list entries.

This means that full queries need to go through the webapp to be enriched (rendered results etc.) and the live queries can go directly to the server, as no enriching is needed.

Also, live and full queries were once very different. I’ve worked hard to unify them, and the only difference that still exists is that live queries don’t contain the result ids, or more precise: They return 0 result ids, while full queries return by default 20 ids.

The other reason was that I needed two different URLs to have Varnish route the live queries directly to the server (since the id count alone didn’t need to be enriched by the webapp), and the full queries were routed through the webapp, like so:

Isn’t it a bit overkill having to define two identical routes for two queries where just the amount of ids is different?


A better solution

What I’d like to have is the following

route %r{\A/all\Z}      => Query.new(accounts_index, users_index, contacts_index),
      %r{\A/contacts\Z} => Query.new(contacts_index)

This would DRY up the code immensely.

Problems with this solution

But now we’re presented with two problems:

Solutions to these problems

I suggest that the first problem is handled by a query parameter ids. So a query through curl would look like this:

curl localhost:8080/contacts?query=miller&ids=20

Even if this means more typing, it is much more convenient and flexible to use. What I now can do is define default amounts in the JS client and in the webapp client (picky-client gem).

The second problem is routing the queries differently. With the new way, you are much more flexible in this. Several solutions are possible. Say you have a Varnish:

Or without Varnish (or Nginx etc.):

Or any other way that suits you best.

Picky 2.0

Since this really irritates me, I’ll start working on it ASAP.

Most work is needed in the documentation – so if after the release, you see the old style anywhere, please tell me so.

Yeah, Picky 2.0 – good times! :)


So we’ve seen

  1. that Picky lives in a wet environment and needs some DRYing up.
  2. that Picky 2.0 is around the corner.

Hope you learnt something new :)

If you have some feedback on what else could be improved, comment away!

Next Picky 2.0