Braque

Braque aims to provide a simple and familiar interface for setting up clients to interact with Hypermedia (hal+json) API services. It is a lightweight wrapper around Hyperclient and ActiveAttr.

Braque is an early-stage and exploratory project. That said, at Artsy, we've used Braque to consume Gris APIs with great benefit.

Build Status

Model setup

Braque::Model is ActiveSupport concern. You can use Braque::Model to map a remote resource to a class in your application. Do so by including Braque::Model in the class, defining the API service's root url, and listing attributes which we expect to receive from the API.

class Article
  include Braque::Model
  api_root_url Rails.application.config_for(:articles_service)['url']

  attribute :id
  attribute :title
  attribute :body
  attribute :summary
  attribute :created_at
  attribute :updated_at
end

Credentials

Braque::Model also supports multiple API authentication strategies. Defining http_authorization_header or accept_header with the model will pass those credentials to the provider API with each request.

For example, http_authorization_header credentials defined here are added to the request's Http-Authorization headers.

class Article
  include Braque::Model
  api_root_url Rails.application.config_for(:articles_service)['url']
  http_authorization_header Rails.application.config_for(:articles_service)['token']

  attribute :id
  attribute :title
end

Defining an accept_header credential will replace Hyperclient's default Accept header with the value you provide.

class Article
  include Braque::Model
  api_root_url Rails.application.config_for(:articles_service)['url']
  accept_header Rails.application.config_for(:articles_service)['accept_header']

  attribute :id
  attribute :title
end

Controllers

In a Rails app, once you've set up your model, you can use the following familiar syntax to query the remote API:

class ArticlesController < ApplicationController
  before_filter :find_article, except: [:index, :new]

  def index
    @articles = Article.list(page: params[:page], size: params[:size])
  end

  def new
  end

  def create
    @article = Article.create params[:article]
    redirect_to article_path(@article)
  end

  def show
  end

  def edit
  end

  def update
    @article = @article.save params[:article]
    redirect_to article_path(@article.id)
  end

  def destroy
    @article.destroy
    redirect_to articles_path
  end

  private

  def find_article
    @article = Article.find(id: params[:id])
  end
end