Last active
April 22, 2019 22:03
-
-
Save MatrixSenpai/7a9cb6b070640f726b0bacc5bf1397a3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enum HTTPMethod: String { | |
case get, put, post, patch, delete | |
} | |
public protocol APIRequest { | |
associatedtype Response: Decodable | |
var base : String { get } | |
var endpoint: String { get } | |
var method : HTTPMethod { get } | |
} | |
typealias Response = (Error?, APIRequest.Response?) | |
public class Client { | |
private let baseURL: URL? | |
private let token : String | |
private let session: URLSession | |
init(token: String, baseURL: URL?) { | |
self.baseURL = baseURL | |
self.token = token | |
self.session = URLSession(configuration: .default) | |
} | |
internal func send<T: APIRequest>(_ request: T, completion: @escaping Response) -> Observable<T.Response> { | |
let request = self.endpoint(for: request) | |
let task = self.session.dataTask(with: request) { data, response, error in | |
if let data = data { | |
do { | |
let res = try decoder.decode(T.Response.self, from: data) | |
completion(nil, res) | |
} catch let e { | |
completion(e, nil) | |
} | |
} else if let e = error { | |
completion(e, nil) | |
} | |
} | |
task.resume() | |
} | |
private func endpoint<T: APIRequest>(for request: T) -> URLRequest { | |
guard let base = URL(string: request.endpoint, relativeTo: baseURL) else { | |
fatalError("Bad endpoint!") | |
} | |
var call = URLRequest(url: base) | |
call.httpMethod = request.method.rawValue | |
call.addValue("Bearer \(token)", forHTTPHeaderField: "Authorization") | |
return call | |
} | |
} | |
struct GetItem: APIRequest { | |
typealias Response = [Item] | |
var base: String { return "get/item" } | |
var method: HTTPMethod { return .get } | |
var endpoint: String { | |
switch path { | |
case .all: return base | |
case .filter(let id): | |
return base + "/filter/by/\(id)" | |
} | |
} | |
var path: Subpath | |
enum Subpath { | |
case all | |
case filter(by id: Int) | |
} | |
} | |
extension Client { | |
func getItems(by id: Int?) -> Response<GetItem.Response> { | |
return send(GetItem(.filter(by: id))) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is a simple HTTP REST API that does not use any 3rd-party libraries