What is a service?
In Convenient Service, a service is a plain Ruby class that includes a config (
ConvenientService::Standard::Configmost of the time).A service either implements
resultdirectly, or composes other services viasteps.## # Without steps. # class Service include ConvenientService::Standard::Config def result success(value: 42) end end ## # With steps. # class OrganizerService include ConvenientService::Standard::Config step Service, out: :value end result = OrganizerService.result result.success? # => true result.data[:value] # => 42Invoking a service always returns a result object, not a raw value. It is inspired by JSend, but not JSend-compatible. Its status is always one of
success,failure, orerror.class FindUser include ConvenientService::Standard::Config attr_reader :id def initialize(id:) @id = id end def result return error("Id is `nil`") if id.nil? users = {1 => {name: "John"}} return failure("User with id `#{id}` does not exist") unless users.key?(id) success(user: users[id]) end end FindUser.result(id: 1).success? # => true FindUser.result(id: 2).failure? # => true FindUser.result(id: nil).error? # => truefailureis for an anticipated negative outcome (a business rule was not met, e.g. a user was not found).erroris for an unexpected condition (e.g. an invalid argument was passed).Besides
result, a service can also be called withcall, at the class or instance level.resultalways returns the full result object.callreturns the result's data hash onsuccess,nilonfailure, and raises onerror.FindUser.call(id: 1) # => {user: {name: "John"}} FindUser.call(id: 2) # => nil FindUser.call(id: nil) # raises ConvenientService::Result::Exceptions::ErrorResultIsCalled FindUser.new(id: 1).call # => {user: {name: "John"}}The first style is a regular service; the second is an organizer service.
See also
- Why do we need services?
- What is a regular service?
- What is an organizer service?
- What is a result?
- What is a config?