ruby on rails - tutorial - validación y manejo de errores para objetos de servicio
tutorial django (1)
Para casos simples (por ejemplo, con solo un argumento), entonces su check-and-raise con ArgumentError está bien. Tan pronto como comienzas a tener casos complejos (argumentos múltiples, objetos, etc.), empiezo a apoyarme en Virtus y Validaciones de ActiveModel .
Su artículo vinculado realmente los menciona (ver "Extraer objetos de formulario"). Algunas veces uso algo como esto para construir objetos de servicio, ej.
require ''active_model''
require ''virtus''
class CreatePackage
include Virtus
include ActiveModel::Validations
attribute :name, String
attribute :author, String
validates_presence_of :name, :author
def create
raise ArgumentError.new("Invalid package") unless self.valid?
response = JSON.parse(
API::post("/packages", self.attributes),
:symbolize_names => true
)
Package.new(response)
end
end
class Package
include Virtus
attribute :id, Integer
attribute :name, String
attribute :author, String
end
# eg.
service = CreatePackage.new(
:name => "Tim''s Tams",
:author => "Tim",
)
service.valid? # true; if false, see service.errors
package = service.create
package.attributes
# => { :id => 123, :name => "Tim''s Tams", :author => "Tim" }
En cuanto a las excepciones, las dejaría como están para acciones más pequeñas (como esta clase de servicio). Me gustaría envolverlos si estoy escribiendo algo más sustancial, como una biblioteca de cliente API completa.
Nunca volveré a nada. Cosas como un error de red, o una respuesta mala o inaplicable del servidor se benefician de errores explícitos.
Finalmente, hay un enfoque mucho más pesado llamado use_case . Incluso si no lo usa, tiene muchas ideas sobre cómo abordar los objetos de servicio, las validaciones y los resultados que puede encontrar interesantes.
Editar : También, mira Mutaciones . Como use_case, excepto que es más simple y menos completo.
Creé un objeto de servicio en Rails para que funcione como una interfaz entre nuestra aplicación y nuestra API.
Obtuve la idea de http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/
Aquí hay un pequeño ejemplo:
class PackagesService
def self.get_package(package_id)
raise ArgumentError.new("package_id can''t be nil") if package_id.blank?
package = API::get "/packages/#{package_id}"
package = JSON.parse package,
:symbolize_names => true unless package.blank?
end
end
¿Hay algún buen patrón para manejar la validación y / o arrojar errores para los objetos de servicio?
Para validaciones:
- Tengo que verificar todas las entradas para el tipo nulo o incorrecto. ¿Hay alguna forma de validación fácil? Tal vez una extensión de rieles?
Para errores:
- Pude detectar todos los errores de API y luego devolver un nulo de forma segura. Pero el programador que usa el objeto de servicio puede no saber el significado de nil.
- Pude detectar los errores de API y generar otro error, lo que significa un esfuerzo adicional para hacerlo en todas las funciones
- La tercera opción es dejarlo tal como está y dejar que el programador maneje todos los errores de la API.
Avíseme si conoce algún patrón bueno o si tiene mejores ideas para interactuar con una API.