All Projects → operators-rb → operators-service

operators-rb / operators-service

Licence: MIT license
Service Object based on Either Monad

Programming Languages

ruby
36898 projects - #4 most used programming language

Projects that are alternatives of or similar to operators-service

Funcj
Assorted functional-oriented data structures and algorithms for Java.
Stars: ✭ 60 (+122.22%)
Mutual labels:  monads
Monads
👻 Type safe Option, Result, and Either types; inspired by Rust
Stars: ✭ 228 (+744.44%)
Mutual labels:  monads
interactor
Simple service objects for PHP
Stars: ✭ 36 (+33.33%)
Mutual labels:  service-object
Pipetools
Functional plumbing for Python
Stars: ✭ 143 (+429.63%)
Mutual labels:  monads
Maryamyriameliamurphies.js
A library of Haskell-style morphisms ported to ES2015 JavaScript using Babel.
Stars: ✭ 177 (+555.56%)
Mutual labels:  monads
Pratica
🥃 Functional Algebraic Data Types
Stars: ✭ 246 (+811.11%)
Mutual labels:  monads
Purefun
Functional Programming library for Java
Stars: ✭ 37 (+37.04%)
Mutual labels:  monads
futils
Utilities for generic functional programming
Stars: ✭ 21 (-22.22%)
Mutual labels:  monads
Mu Haskell
Mu (μ) is a purely functional framework for building micro services.
Stars: ✭ 215 (+696.3%)
Mutual labels:  monads
freestyle-kafka
Freestyle Kafka
Stars: ✭ 17 (-37.04%)
Mutual labels:  monads
Swift Monad Maybe Reader And Try
Proof of concept: Maybe, Reader and Try monad
Stars: ✭ 159 (+488.89%)
Mutual labels:  monads
Scala Workflow
Boilerplate-free syntax for computations with effects
Stars: ✭ 173 (+540.74%)
Mutual labels:  monads
kudojs
A utility library to write code in functional programming style in Javascript
Stars: ✭ 22 (-18.52%)
Mutual labels:  monads
Datum
pure functional and generic programming for Erlang
Stars: ✭ 111 (+311.11%)
Mutual labels:  monads
hawkweed
Yet another implementation of missing functions for Python
Stars: ✭ 20 (-25.93%)
Mutual labels:  monads
Fear
Ruby port of some Scala's monads
Stars: ✭ 58 (+114.81%)
Mutual labels:  monads
Neither
Either and Maybe monads for better error-handling in C++ ↔️
Stars: ✭ 236 (+774.07%)
Mutual labels:  monads
monadiccp
Monadic Constraint Programming framework
Stars: ✭ 25 (-7.41%)
Mutual labels:  monads
pyMonet
High abstract python library for functional programming. Contains algebraic data structures known (or unknown) from Haskell or Scala.
Stars: ✭ 31 (+14.81%)
Mutual labels:  monads
konad
Monads composition API that just works. For OOP developers
Stars: ✭ 62 (+129.63%)
Mutual labels:  monads

Operators::Service

Gem Version CircleCI Maintainability

Operators::Service is a lightweight implementation of Service Object based on Either Monad. That gives an home of application business logic.

Service Objects are created when an action:

  • Uses integration with external services

  • Uses several models

  • Is complex (such as calculating sales statistics)

Installation

Add this line to your application's Gemfile:

gem 'operators-service'

And then execute:

$ bundle

Or install it yourself as:

$ gem install operators-service

Usage

class UserCreator < Operators::Service
  attr_reader :params
  
  def initialize(params)
    @params = params
  end

  def call
    user = User.create(params)
    if !user.new_record?
      success(user)
    else
      failure(user.errors)
    end
  end
end

success - returns instance of Dry::Monads::Either::Right

failure - returns instance of Dry::Monads::Either::Left

class UsersController < ApplicationController
  def create
    UserCreator.call(user_params).fmap do |user|
      render json: user
    end.or_fmap do |errors|
      render json: errors.full_messages
    end
  end
  
  private
  
  def user_params
    params.require(:user).permit!
  end
end

More complicated usage

If you need rescue_callbacks then you should define calling instead of call.

class Auth < Operators::Service
  rescue_callbacks AuthError, CredentialsError

  def initialize(options)
    @options = options
  end

  def calling
    return failure('User already authed') if @options[:failure] # returns Dry::Monads::Left('User already authed')

    first_auth_transaction
    second_auth_transaction

    success('ok') # returns Dry::Monads::Right('ok')
  end

  private

  def first_auth_transaction
    # do something...
  end

  def second_auth_transaction
    raise AuthError, 'Auth error message' if @options[:auth_error]
  end

  # Wrapper for your error result
  def error_wrap(error)
    error # 'User already authed' || 'Auth error message'
  end

  # Wrapper for your success results
  def success_wrap(success_result)
    success_result # ok
  end
end
success = Auth.call(email: 'email', password: 'password')
# Dry::Monads::Right('ok')

failure = Auth.call(email: 'email', password: 'password', failure: true)
# Dry::Monads::Left('User already authed')

raised_error = Auth.call(email: 'email', password: 'password', auth_error: true)
# Dry::Monads::Left('Auth error message')

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/operators-rb/operators-service.

License

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

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].