Teckel

Ruby service classes with enforced1 input, output and error data structure definition.

Gem Version Build Status codecov API Documentation Coverage

Installation

Add this line to your application's Gemfile:

gem 'teckel'

And then execute:

$ bundle

Or install it yourself as:

$ gem install teckel

Motivation

Working with Interactor, Trailblazer's Operation and Dry-rb's Transaction and probably a hand full of inconsistent "service objects", I missed a system that:

  1. provides and enforces well defined input, output and error structures
  2. makes chaining multiple operation easy and reliable
  3. is easy to debug

Usage

For a full overview please see the Docs:

class CreateUser
  include Teckel::Operation

  # DSL style declaration
  input Struct.new(:name, :age, keyword_init: true)

  # Constant style declaration
  Output = ::User

  # Well, also Constant style, but using classic `class` notation
  class Error
    def initialize(message:, status_code:, meta:)
      @message, @status_code, @meta = message, status_code, meta
    end
    attr_reader :message, :status_code, :meta
  end
  error_constructor :new

  def call(input)
    user = User.new(name: input.name, age: input.age)
    if user.save
      success!(user)
    else
      fail!(
        message: "Could not create User",
        status_code: 400,
        meta: { validation: user.errors }
      )
    end
  end
end

CreateUser.call(name: "Bob", age: 23) #=> #<User @age=23, @name="Bob">

CreateUser.call(name: "Bob", age: 5)  #=> #<CreateUser::Error @message="Could not create User", @meta={:validation=>[{:age=>"underage"}]}, @status_code=400>

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/fnordfish/teckel. Feature requests should provide a detailed explanation of the missing or changed behavior, if possible including some sample code.

Please also see DEVELOPMENT.md for planned features and general guidelines.

Footnotes

  • 1: Obviously, it's still Ruby and you can cheat. Don’t!