Introducing Gearhead

If ActiveAdmin, Grape, and InheritedResources had a baby, I think it would be Gearhead. Gearhead handles all the boilerplate for your RESTful API so you can focus on consuming it.

Contents

Why

I’m always trying to reduce the amount of boilerplate code I write. It’s boring and often tedious. Sure, my framework of choice does a lot of heavy lifting for me, but there’s always something else I’m stuck doing that I would consider gruntwork.

While gruntwork is rightfully part of the development process, that doesn’t mean I can’t try to reduce it.

I’ve always been fascinated with this idea of metaprogramming code to expose a database. This past weekend I had some free brain space so I decided to see what I could do. Turns out, I really like what I have. This

The pitchdeck

With Gearhead, you can turn your entire database schema into a RESTful JSON API with just three commands:

$ bundle add gearhead 
$ rails g gearhead:install --automount=true --endpoint=/api/v1
$ rails server 

What this gives you

CRUD

The standard CRUD actions for each ActiveRecord model, all mapped to their appropriate HTTP verbs? Yep.

GET /api/v1/people GET /api/v1/people/1 POST /api/v1/people PUT/PATCH /api/v1/people/1 DELETE /api/v1/people/1

Pagination

Pagination out of the box? Sure. Want to tune it? You can.

GET /api/v1/people?page=5

Querying, sorting, and filtering

Gearhead hooks into Ransack for all possible filtering needs.

GET /api/v1/people?q[first_name_cont]="Josh" 

Handles your scopes

Not by default, but you can expose them:

GET /api/v1/people?scope=verified 

Serialization included

Uses Fast-JSONAPI under the hood by default. Configurable, of course.

Param handling

Don’t let just anyone overwrite your user_id column. Oh nonono.

And more!

I’m probably forgetting.

Getting down and dirty

Gearhead has a concept called Gears, which are used by the controller to process the request and build the response.

We can customize Gears to customize our response.

Let’s create a Gear in app/gears. We’ll call it posts_gear.rb:

Gearhead.register Post do; end

Customizing serialization

Probably the most important part. By default, Gearhead spits out the entire row.

Gearhead.register Post do 
  attributes :id, :published_at, :body, :user_id 
  attribute :excerpt do |resource| 
    resource.body.first(1000)
  end 
end 

We can also change the serializer from FastJSONAPI to ActiveModelSerializers on a global basis in an initializer, or on the Gear-level:

Gearhead.register Post do 
  serializer_adapter :active_model_serializers 
end

and it’ll do all the work for us.

Configurating pagination

Ships with the great Pagy out-of-the-box.

Gearhead.register Post do 
  per_page 5 # defaults to 30 
  max_per_page 500 # defaults to 100 
  pagination_adapter :will_paginate 
end 

Collection and member routes

I didn’t forget about you.

Gearhead.register Post do
  collection_action :favorites do 
    # ... do something 
  end 

  member_action :favorite, via: :post do 
    resource.update!(favorited: true)
  end 
end 

There’s a lot more

For a fun weekend project I have already put this into production and it’s not breaking so I suppose that’s a good sign.

Check it out for yourself and make a pull request. :)