A DataSource is an interace for those classes responsible of fetching and managing raw data. This data can be manipulated in many ways as for example being stored in a local database, being sent via a network or socket interface or any third party services (sending emails via Sengrid or SMS via another service).


val dataSource = MyCustomGetDataSource()
dataSource.get(ByIdentifierQuery("myKey")).onComplete(onSuccess = {
}, onFailure = {


A Query object itself defines intrinsically how data must be manipulated, containing inside all parameters required to execute the action.

For more information, read the Query reference.


All actions handled by a DataSource are grouped in a simple CRUD.


Fetch related functions.

interface GetDataSource<V> : DataSource {
fun get(query: Query): Future<V>
fun getAll(query: Query): Future<List<V>>


Actions related functions. PUT methods will be responsible of editing, modifying, sending or any other action related method.

Note that in the put function, the value is optional. This happens becasue it is not always required to have an actual value to perform the action defined by the Query. In the case of putAll, an empty array can be passed.

interface PutDataSource<V> : DataSource {
fun put(query: Query, value: V?): Future<V>
fun putAll(query: Query, value: List<V>? = emptyList()): Future<List<V>>


Deletion related functions.

Note that only a Query is required and no value is returned rather than a Future encapsulating the output error.

interface DeleteDataSource : DataSource {
fun delete(query: Query): Future<Unit>
fun deleteAll(query: Query): Future<Unit>

IdQuery CRUD extensions

All GetDataSource, PutDataSource and DeleteDataSource interfaces are extended with methods to access the CRUD functions by an Id:

// Swift
extension GetDataSource {
public func get<K>(_ id: K) -> Future<T> where K:Hashable { ... }
public func getAll<K>(_ id: K) -> Future<[T]> where K:Hashable { ... }
extension PutDataSource {
public func put<K>(_ value: T?, forId id: K) -> Future<T> where K:Hashable { ... }
public func putAll<K>(_ array: [T], forId id: K) -> Future<[T]> where K:Hashable { ... }
extension DeleteDataSource {
public func delete<K>(_ id: K) -> Future<Void> where K:Hashable { ... }
public func deleteAll<K>(_ id: K) -> Future<Void> where K:Hashable { ... }

This way, code that originally looked like this:

dataSource.put(ByIdentifierQuery("myKey"), myObject)

can be written as follows:

dataSource.put("myKey", myObject)

DataSource Implementations

Swift exclusive implementations

  • TimedCacheDataSource<T>: A TLRU cache over a data source.
  • RealmDataSource<E,O>: Realm based data source. Available at the MJSWiftCore/Realm pod subspec.
  • KeychainDataSource<T>: Keychain based data source. Available at the MJSwiftCore/Security pod subspec.
  • DataSourceAssembler<T>: Combines three data sources (get, put, delete) into a single object.
  • AnyDataSource<T>: Type erasing for any get+put+delete data source.
  • AnyGetDataSource<T>: Type erasing for a get data source.
  • AnyPutDataSource<T>: Type erasing for a put data source.
  • RetryDataSource<T>: Encapsulates another data source and retries a call when an error happens.

Swift Notes

DataSource base protocol

In order to have a generic type, all GetDataSource, PutDataSource and DeleteDataSource extends from the following base protocol:

public protocol DataSource { }

Kotlin Notes

DataSource base interface

interface DataSource