Providers
Los Providers son un concepto clave en el sistema ReactiveModel. Te permiten desacoplar la lógica de acceso a datos de la capa reactiva. Al implementar una interfaz simple, los providers hacen posible integrar tus modelos y colecciones con cualquier tipo de fuente de datos — desde almacenamiento local e IndexedDB hasta SQL, NoSQL, APIs REST, o incluso sistemas de archivos.
🎯 Propósito
El objetivo principal de un provider es externalizar la lógica de persistencia para que la capa reactiva (items y colecciones) pueda permanecer agnóstica de cómo se obtienen, almacenan o actualizan los datos.
Esto permite:
Separación clara de responsabilidades
Pruebas y mocks más fáciles
Integración plug-and-play con varios backends o motores de almacenamiento
Manejo uniforme de fuentes de datos locales y remotas
🔁 Concepto Compartido
El concepto de provider se usa en ambos:
Item<T>— para operaciones de entidad únicaCollection<T>— para operaciones de grupo
Aunque ambos dependen de un provider, cada uno requiere una interfaz diferente, adecuada a su propósito.
📦 Providers de Item
Se usan en la clase Item<T> para interactuar con una entidad única. Debes implementar la interfaz IEntityProvider:
Interfaz
Métodos Clave
load(specs?): (Opcional) Obtiene un item por ID u otros criterios. Debe retornar los datos del item directamente (no envueltos en un objeto de respuesta).publish(data): (Opcional) Guarda o actualiza un item. Debe retornar los datos del item actualizado directamente.delete(specs?): (Opcional) Elimina un item. Debe retornartruesi es exitoso, o lanzar un error si falla.
Ejemplo
Uso en Item
📚 Providers de Collection
Se usan en la clase Collection<T> para interactuar con una lista de items. Debes implementar la interfaz ICollectionProvider:
Interfaz
Métodos Clave
load(specs?)olist(specs?): (Requerido) Obtiene una lista de items. Debe retornar:Un array de items directamente:
Promise<ItemData[]>Un objeto con información de paginación:
Promise<{ items: ItemData[], next?: string, total?: number }>
publish(data): (Opcional) Crea o actualiza items en masa.remove(specs?): (Opcional) Elimina items de la colección.
Ejemplo
Uso en Collection
⚙️ Beneficios Clave
✅ Agnóstico del backend o motor de almacenamiento: Funciona con APIs REST, GraphQL, IndexedDB, SQL, etc.
✅ Totalmente compatible con APIs remotas o almacenamiento local: Implementa una vez, usa en cualquier lugar
✅ Interfaz uniforme: Mismo patrón para cargar, guardar, eliminar
✅ Reutilizable y testeable: Fácil de mockear para pruebas unitarias
✅ Escala desde archivos simples hasta capas de datos complejas: Empieza simple, evoluciona según necesites
🧪 Mejores Prácticas de Implementación
Manejo de Errores
Los métodos del provider deben manejar errores internamente y lanzar errores significativos:
Transformación de Respuestas
Los providers deben retornar solo los datos, no el wrapper de respuesta de la API:
Seguridad de Tipos
Usa interfaces de TypeScript para asegurar la seguridad de tipos:
🔮 Uso Avanzado
Lógica Personalizada del Provider
Puedes agregar lógica personalizada a tus providers:
Operaciones en Lote
Para colecciones, puedes implementar operaciones en lote:
📄 Resumen
Entidad Única
Item<T>
IEntityProvider
Promise<ItemData>
Colección
Collection<T>
ICollectionProvider
Promise<ItemData[]> o Promise<{ items, next, total }>
Los providers manejan la complejidad de las interacciones con la API mientras proporcionan una interfaz limpia para tus modelos reactivos. Validan respuestas, manejan errores y retornan solo los datos necesarios, manteniendo tus modelos enfocados en gestionar estado y reactividad.
Last updated