I have provided the code for my firebase API client.
Is it smart to use generics, to initialize any entity straight from json this way?
To download lists, I needed an indicator to let me know that I'm requesting a list of entities, so I added a GETALL to my HTTPMethod enum, is this bad, and something that would be confusing to others?
I also feel like this isn't flexible because I can't get entities on a node that may be a different nested levels. Hopefully that makes sense. So this probably doesn't follow open/closed principle since I have nest my entities in firebase differently ill have to change implementation inside FirebaseAPI.
From open source code i've seen, I haven't quite seen a api client designed like this and not sure if I'm using an anti pattern or something. Any help or guidance to make this maintainable.
class FirebaseAPI {
private let session: URLSession
init() {
self.session = URLSession.shared
}
/// Responsible for Making actual API requests & Handling response
/// Returns an observable object that conforms to JSONable protocol.
/// Entities that confrom to JSONable just means they can be initialized with json.
func rx_fireRequest<Entity: JSONable>(_ endpoint: Endpoint) -> Observable<[Entity]> {
return Observable.create { [weak self] observer in
self?.session.dataTask(with: endpoint.request, completionHandler: { (data, response, error) in
/// Parse response from request.
let parsedResponse = Parser.init(data: data, response: response, error: error)
.parse()
switch parsedResponse {
case .error(let error):
observer.onError(error)
return
case .success(let data):
var entities = [Entity]()
/// Consider edge case where a list of entities are retrieved, rather than a single entity.
/// Iterate through each entity and initialize.
/// Denoted by 'GETALL' method.
switch endpoint.method {
case .GETALL:
/// Key (underscored) is unique identifier for each entity, which is not needed here.
/// value is k/v pairs of entity attributes.
for (_, value) in data {
if let value = value as? [String: AnyObject], let entity = Entity(json: value) {
entities.append(entity)
} else {
observer.onError(NetworkError.initializationFailure)
return
}
observer.onNext(entities)
observer.onCompleted()
return
}
default:
if let entity = Entity(json: data) {
observer.onNext([entity])
observer.onCompleted()
} else {
observer.onError(NetworkError.initializationFailure)
}
}
}
})
return Disposables.create()
}
}
}
Aucun commentaire:
Enregistrer un commentaire