{"id":13631709,"url":"https://github.com/operators-rb/operators-service","last_synced_at":"2025-04-17T22:31:36.440Z","repository":{"id":56886932,"uuid":"89339114","full_name":"operators-rb/operators-service","owner":"operators-rb","description":"Service Object based on Either Monad","archived":false,"fork":false,"pushed_at":"2018-08-11T11:37:27.000Z","size":14,"stargazers_count":27,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-10-31T13:30:47.831Z","etag":null,"topics":["interactor","monads","operators","service-object"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/operators-rb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-04-25T08:55:15.000Z","updated_at":"2022-09-27T14:32:45.000Z","dependencies_parsed_at":"2022-08-21T00:20:26.953Z","dependency_job_id":null,"html_url":"https://github.com/operators-rb/operators-service","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/operators-rb%2Foperators-service","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/operators-rb%2Foperators-service/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/operators-rb%2Foperators-service/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/operators-rb%2Foperators-service/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/operators-rb","download_url":"https://codeload.github.com/operators-rb/operators-service/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223768648,"owners_count":17199356,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["interactor","monads","operators","service-object"],"created_at":"2024-08-01T22:02:35.307Z","updated_at":"2024-11-08T23:31:27.962Z","avatar_url":"https://github.com/operators-rb.png","language":"Ruby","readme":"# Operators::Service\n\n[![Gem Version](https://badge.fury.io/rb/operators-service.svg)](https://badge.fury.io/rb/operators-service)\n[![CircleCI](https://circleci.com/gh/operators-rb/operators-service.svg?style=shield\u0026circle-token=ce6107feab9a4989e9c8163c6d652bb1bad40cf7)](https://circleci.com/gh/operators-rb/operators-service)\n[![Maintainability](https://api.codeclimate.com/v1/badges/3fc7bafea686b44d257f/maintainability)](https://codeclimate.com/github/operators-rb/operators-service/maintainability)\n\nOperators::Service is a lightweight implementation of Service Object based on [Either Monad](https://github.com/dry-rb/dry-monads). That gives an home of application business logic.\n\nService Objects are created when an action:\n\n* Uses integration with external services\n\n* Uses several models\n\n* Is complex (such as calculating sales statistics)\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'operators-service'\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install operators-service\n\n## Usage\n\n```ruby\nclass UserCreator \u003c Operators::Service\n  attr_reader :params\n  \n  def initialize(params)\n    @params = params\n  end\n\n  def call\n    user = User.create(params)\n    if !user.new_record?\n      success(user)\n    else\n      failure(user.errors)\n    end\n  end\nend\n```\n\n`success` - returns instance of `Dry::Monads::Either::Right`\n\n`failure` - returns instance of `Dry::Monads::Either::Left`\n\n```ruby\nclass UsersController \u003c ApplicationController\n  def create\n    UserCreator.call(user_params).fmap do |user|\n      render json: user\n    end.or_fmap do |errors|\n      render json: errors.full_messages\n    end\n  end\n  \n  private\n  \n  def user_params\n    params.require(:user).permit!\n  end\nend\n```\n\n### More complicated usage\n\nIf you need `rescue_callbacks` then you should define `calling` instead of `call`.\n\n```ruby\nclass Auth \u003c Operators::Service\n  rescue_callbacks AuthError, CredentialsError\n\n  def initialize(options)\n    @options = options\n  end\n\n  def calling\n    return failure('User already authed') if @options[:failure] # returns Dry::Monads::Left('User already authed')\n\n    first_auth_transaction\n    second_auth_transaction\n\n    success('ok') # returns Dry::Monads::Right('ok')\n  end\n\n  private\n\n  def first_auth_transaction\n    # do something...\n  end\n\n  def second_auth_transaction\n    raise AuthError, 'Auth error message' if @options[:auth_error]\n  end\n\n  # Wrapper for your error result\n  def error_wrap(error)\n    error # 'User already authed' || 'Auth error message'\n  end\n\n  # Wrapper for your success results\n  def success_wrap(success_result)\n    success_result # ok\n  end\nend\n```\n\n```ruby\nsuccess = Auth.call(email: 'email', password: 'password')\n# Dry::Monads::Right('ok')\n\nfailure = Auth.call(email: 'email', password: 'password', failure: true)\n# Dry::Monads::Left('User already authed')\n\nraised_error = Auth.call(email: 'email', password: 'password', auth_error: true)\n# Dry::Monads::Left('Auth error message')\n```\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/operators-rb/operators-service.\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).\n","funding_links":[],"categories":["Ruby"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foperators-rb%2Foperators-service","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foperators-rb%2Foperators-service","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foperators-rb%2Foperators-service/lists"}