             self.language = language
         }
     }
-    
-    /// This is the typical JSON type used by webservices.
-    public typealias JSON = [String: AnyObject]
     
     // MARK: - Constants -
     

    }
    
}

//
//  # Request: JSON Extension
//

public extension Service.Request
{
    
    // MARK: - Types -
    
    fileprivate enum JSONKey: String
    {
        /// Query.
        case query
        /// Fields.
        case fields
        /// Language.
        case language = "lang"
    }
    
    // MARK: - Deserialization -
    
    /// Initializes the `Request` instance with a given JSON object.
    ///
    /// - Parameters:
    ///   - json: The JSON object.
    ///
    /// - Returns: The new `Result` instance.
    init?(json: Service.JSON)
    {
        if let query = json[Service.Request.JSONKey.query.rawValue] as? String {
            self.query      = query
            self.language   = json[Service.Request.JSONKey.language.rawValue] as? String
            
            if let string = json[Service.Request.JSONKey.fields.rawValue] as? String {
                let fields = string.components(separatedBy: ",")
                self.fields = fields.flatMap { Service.Result.Field(rawValue: $0) }
            }
        } else {
            return nil
        }
    }
    
    // MARK: - Serialization -
    
    /// Serializes the object to the IPAPI format.
    func toJSON() -> Service.JSON
    {
        var ret: Service.JSON = [:]
        
        ret[Service.Request.JSONKey.query.rawValue]     = self.query as AnyObject?
        ret[Service.Request.JSONKey.fields.rawValue]    = self.fields?.map { $0.rawValue }.joined(separator: ",") as AnyObject?
        ret[Service.Request.JSONKey.language.rawValue]  = self.language as AnyObject?
        
        return ret
    }
    
}

            return nil
        }
        
        let encoder = JSONEncoder()
        let body = queries.flatMap({ try? encoder.encode($0) }).flatMap({ String(data: $0, encoding: .utf8) })
        guard let jsonBody = try? JSONSerialization.data(withJSONObject: body, options: []) else {
            completion?(nil, Error.invalidRequestData)
            return nil
