GithubHelp home page GithubHelp logo

fretadao / f_service Goto Github PK

View Code? Open in Web Editor NEW
10.0 6.0 3.0 137 KB

Simpler, safer and more composable operations

License: MIT License

Ruby 99.72% Shell 0.28%
ruby operations service-objects monads chaining-services interactor hacktoberfest library hacktoberfest2023

f_service's People

Contributors

andre-filho avatar bvicenzo avatar dependabot[bot] avatar j133y avatar matheusbsilva avatar matheusrich avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

f_service's Issues

Allow defining inputs (and maybe outputs)

I'm not sure of the syntax yet, but it would be nice to have something like this:

class User::Create < FService::Base
  input :name, type: String
  input :age, type: Integer, should: { be_positive: ->(age) { age.positive? } }
  input :github_username, type: String, default: '[no-username]'

  output :user, type: User

  def run
    # ...
  end
end

User::Create.(name: 'David', age: 40, github_username: 'ddd')

Rename `then` to `and_then`

then already exist in ruby objects. It may be a good idea not to use the same method name in FService::Results. and_then is a pretty straight forward alternative.

Add support to custom data on Base#Check

Hi,

So, myself and my colleagues are always complaining that we cannot pass a custom data to the Base#Check and always need to write both the Success and Failure to be able to use a custom data. I think it is a good idea to keep the actual behavior to validation purposes, but also expand it's usage by having an optional data argument.

Or even better, having a different data prop depending on the actual return could be a good one too, what do you think?

PR: #18

Rename `run` to `call!`

call! is more common in Ruby an is already present as a class method for FService::Base. We should mark run as deprecated in the next version.

We'll use call (without bang) in #27, so call! (with bang) is the drop-in replacement for run.

Add `call` for `FService::Base`

call should be the safe version of the current run (and future call!). call should work pretty much like run does, but it also catches any StandardError that may be raised in its body and encapsulates as a failure:

class Bomb < FService::Base
  def call # safe
    raise StandardError, 'BOOOM!'
  end
end

Bomb.call # remember that Bomb.call == Bomb.new.call
# => #<Failure:uu1D @type=:exception @error=#<StandardError: BOOOM!>>

With call! (with bang), we have the unsafe version:

class Bomb < FService::Base
  def call! # unsafe
    raise StandardError, 'BOOOM!'
  end
end

Bomb.call # remember that Bomb.call == Bomb.new.call
# => BOOOM! (StandardError)

Add Check/Try docs

Hello there!

I've noticed that ther is no Check example on the README file. Do you plan on adding it on a near future?

Allow Success and Failure to have more than one symbol

In exceptions, we can catch or a single error, or a family of errors, using its superclass...

Ex:

ClientError = Class.new(RuntimeError)
UnprocessableEntity = Class.new(ClientError)
Conflict = Class.new(ClientError)

def foo
  create_user
  rescue UnprocessableEntity => error
    "User can not be created fix errors and try again #{error.message}"
  rescue Conflict
    "User already exist."
  rescue ClientError => error
    Sentry.capture_exception("Some unexpected client error happened: #{error.message}")
    "Unknow error happened, please contact system administration"
end

Nowadays it is impossible in FService, because we can create a result using just one symbol....
If we are able to put more than one symbol, we could, for example, pass a specific symbol and a more generic one.

Ex:

class User::Create < FService::Base
  attribute :attr

  def run
    response = create_user(attrs)
    return Success(:ok, :created, data: response.body) if response.status == 200

    if response.status.between?(400, 499)
      error_name = client_error_name(response.status)
      if error_name.error_name.present?
        Failure(:unprocessable_entity, :client_error, data: response.body)
      else
        Failure(:client_error, data: response.body)
      end
    end
  end

  private

  def client_error_name(status)
    return :unprocessable_entity if status = 422
    return :conflict if status = 409
  end
end

And the usage would be:

User::Create(attrs: { name: 'Joe' })
  .on_success(:created) { return 'User created' }
  .on_failure(:unprocessable_entity) { |error| return "User can not be created fix errors and try again #{error}" }
  .on_failure(:conflict) { return "User already exist." }
  .on_failure(:client_error) do
    Sentry.capture_exception("Some unexpected client error happened: #{error.message}")
    return "Unknow error happened, please contact system administration"
  end

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.