Skip to content

Like form objects but, you know, for APIs.

License

Notifications You must be signed in to change notification settings

pragmarb/pragma-contract

Repository files navigation

Pragma::Contract

Build Status Coverage Status Maintainability

Contracts are form objects on steroids for your JSON API.

They are built on top of Reform.

Installation

Add this line to your application's Gemfile:

gem 'pragma-contract'

And then execute:

$ bundle

Or install it yourself as:

$ gem install pragma-contract

Usage

To create a contract, simply inherit from Pragma::Contract::Base:

module API
  module V1
    module Article
      module Contract
        class Base < Pragma::Contract::Base
          property :title
          property :body
        end
      end
    end
  end
end

Since Pragma::Contract is built on top of Reform, you should consult its documentation for the basic usage of contracts; the rest of this section only covers the features provided specifically by Pragma::Contract.

Coercion

Pragma::Contract supports Reform coercion through the dry-types gem.

You can access types with the Pragma::Contract::Types module.

module API
  module V1
    module Article
      module Contract
        class Base < Pragma::Contract::Base
          property :title, type: Pragma::Contract::Types::Coercible::String
          property :body, type: Pragma::Contract::Types::Coercible::String
          property :published_at, type: Pragma::Contract::Types::Form::Date
        end
      end
    end
  end
end

Helpers are also provided as a shorthand syntax:

module API
  module V1
    module Article
      module Contract
        class Base < Pragma::Contract::Base
          property :title, type: coercible(:string)
          property :body, type: coercible(:string)
          property :published_at, type: form(:date)
        end
      end
    end
  end
end

Model finders

This is a common pattern in API contracts:

module API
  module V1
    module Invoice
      module Contract
        class Base < Pragma::Contract::Base
          property :customer

          def customer=(val)
            super ::Customer.find_by(id: val)
          end
        end
      end
    end
  end
end

Pragma::Contract provides a shorthand syntax:

module API
  module V1
    module Invoice
      module Contract
        class Base < Pragma::Contract::Base
          property :customer, type: Customer
        end
      end
    end
  end
end

You can also specify a custom column to find by!

module API
  module V1
    module Invoice
      module Contract
        class Base < Pragma::Contract::Base
          property :customer, type: Customer, by: :email
        end
      end
    end
  end
end

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/pragmarb/pragma-contract.

License

The gem is available as open source under the terms of the MIT License.