Api - markgravity/Base GitHub Wiki

This is an example to create a API, create and list Book

Setup Base Api class

class Api<T:Responsable>: Apiable {
    typealias ResponsableType = T
	
    // Configure your request that will send to server
    static func createRequest(baseUrl:String, 
                              endPoint:String, 
                              method:HTTPMethod, 
                              parameters:Dictionary<String, Any>?, 
                              token:String?)-> DataRequest {
        
        let manager = Alamofire.SessionManager.default
        manager.session.configuration.timeoutIntervalForRequest = 120
        
        
        var url = "\(baseUrl)/\(endPoint)"
        var headers = HTTPHeaders()
        
        // Append token
        if token != nil {
            headers["Authorization"] = "Bearer \(token!)"
        }
        
        var parameters = parameters
        if method == .get && parameters != nil {
            var isFirst = true
            for (key,value) in parameters! {
                let symbol = isFirst ? "?" : "&"
                isFirst = false
                
                let key = key.replacingOccurrences(of: "_", with: "-")
                url = "\(url)\(symbol)\(key)=\(value)"
            }
            
            parameters = nil
        }
        
        let dataRequest = request(url,
                                  method: method,
                                  parameters: parameters,
                                  encoding: JSONEncoding.default,
                                  headers: headers)
        
        return dataRequest
    }
    
    // Handle the way your server throw an error or a success response,
    // then map it to (response, error)
    static func transformResponseObject(_ responseObject:DataResponse<Any>)
    	-> (response:[String:Any]?, error:Error?) {
        guard let result = try? JSON(data: responseObject.data!) else {
            let error = NSError(code: .apiWrongStructure, description: "Wrong response structure")
            return (response: nil, error: error)
        }
        
        // Handle error message by server
        if !result["status"].bool! {
            var message: String = ""
            if let string = result["message"].string {
                message = string
            } else if let dict = result["message"].dictionary {
                message = dict[dict.keys.reversed().first!]?.array?.first?.string ?? ""
            }
            
            let error = NSError(code: 999,
                                  description: message)
            
            return (response: nil, error:error)
        } else {
            let response = responseObject.result.value as! [String:Any]
            
            return (response: response, error:nil)
        }
    }
    
    // Hook func to handle error, prevent api calling completion function
    static func shouldProccess(response:[String:Any]?, error: Error?)-> Bool {
        return true
    }
}

Create API

.1 Create a responsable
struct BookInfo: Responsable {
    static var endPoint: String = "book"

    var id: Int?
    var name: String?

    init?(map: Map) {

    }

    mutating func mapping(map: Map) {
        id          <- map["id"]
        name        <- map["name"]
    }
}

.2 Create a create parameter

struct BookCreateParameter: Parametable {
    var name: String?
    
    init?(map: Map) {}
    func rules(validator: Validator) {
        name           <~ validator["Name", .required]
    }
    
    mutating func mapping(map: Map) {
        name                <- map["name"]
    }
}

.3 Writing api

extension Api where T:BookInfo{
    static func create(parameter: Parametable, token:String)-> ApiRequest<T> {
        
        return createApi(baseUrl: BaseConfigure.ApiBaseUrl,
                         endPoint: BookInfo.endPoint, 
                         method: .post, 
                         parameter: parameter, 
                         token: token)
    }
}

How to use

var parameter = BookCreateParameter()
parameter.name = "Base Book"
Api<BookInfo>.create(parameter: parameter, token:"your api token").response { book, error in
	guard let book = book else {
    	print(error!)
        return
	}
    print("A new book was created: "\(book.name!)")
}
⚠️ **GitHub.com Fallback** ⚠️