diff --git a/README.md b/README.md index f75183b..f317bfc 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,15 @@ # HTTPEngine -![Swift](https://github.com/JZDesign/HTTPEngine/workflows/Swift/badge.svg) +![Swift](https://github.com/JZDesign/HTTPEngine/workflows/Swift/badge.svg) [![SPM compatible](https://img.shields.io/badge/SPM-compatible-e66f20.svg?style=flat)](https://github.com/apple/swift-package-manager) [![Docs](https://img.shields.io/badge/Jazzy-Documentation-634fb3.svg?style=flat)](https://jzdesign.github.io/HTTPEngine/) -A description of this package. +A convenience wrapper around Swift's Combine and URLSession to make `URLRequests` + +## SPM +```swift +dependencies: [ + .package(url: "https://github.com/JZDesign/HTTPEngine.git", .upToNextMajor(from: "0")) +], +``` + +## [View Documentation](https://jzdesign.github.io/HTTPEngine/) + +Documentation generated by [Jazzy](https://github.com/realm/jazzy). \ No newline at end of file diff --git a/Sources/HTTPEngine/Errors.swift b/Sources/HTTPEngine/Errors.swift index fa23147..64e5d11 100644 --- a/Sources/HTTPEngine/Errors.swift +++ b/Sources/HTTPEngine/Errors.swift @@ -1,17 +1,17 @@ import Foundation public struct Errors { - enum Request: Error { + public enum Request: Error { case invalidURL } - enum Response: Error { + public enum Response: Error { case couldNotRetrieveStatusCode case unexpectedStatusCode(HTTPURLResponse) case redirect(Int) case unknown(Int) - enum ClientError: Error { + public enum ClientError: Error { case badRequest_400 case invalidCredentials_401 case forbidden_403 @@ -22,7 +22,7 @@ public struct Errors { case unkown(Int) } - enum ServerError: Error { + public enum ServerError: Error { case internalServerError_500 case notImplemented_501 case badGateway_502 @@ -31,7 +31,30 @@ public struct Errors { case unkown(Int) } - static func errorWith(statusCode: Int) -> Error? { + + /// Returns a human readable HTTP Error + /// - Parameter statusCode: HTTP Status Code + /// - Returns: Error? + /// + /// ```swift + /// code ~= 300...399 -> Errors.Response.redirect(statusCode) + /// code ~= 400 -> Errors.Response.ClientError.badRequest_400 + /// code ~= 401 -> Errors.Response.ClientError.invalidCredentials_401 + /// code ~= 403 -> Errors.Response.ClientError.forbidden_403 + /// code ~= 404 -> Errors.Response.ClientError.notFound_404 + /// code ~= 405 -> Errors.Response.ClientError.notAllowed_405 + /// code ~= 409 -> Errors.Response.ClientError.conflict_409 + /// code ~= 429 -> Errors.Response.ClientError.tooManyRequests_429 + /// code ~= 402, 410...418, 430...499 -> Errors.Response.ClientError.unkown(statusCode) + /// code ~= 500 -> Errors.Response.ServerError.internalServerError_500 + /// code ~= 501 -> Errors.Response.ServerError.notImplemented_501 + /// code ~= 502 -> Errors.Response.ServerError.badGateway_502 + /// code ~= 503 -> Errors.Response.ServerError.unavailable_503 + /// code ~= 504 -> Errors.Response.ServerError.timeout_504 + /// code ~= 505...599 -> Errors.Response.ServerError.unkown(statusCode) + /// default -> Errors.Response.unknown(statusCode) + ///``` + public static func errorWith(statusCode: Int) -> Error? { switch statusCode { case 200...299: return nil case 300...399: return Errors.Response.redirect(statusCode) diff --git a/Sources/HTTPEngine/HTTPEngine+ConvenienceMethods.swift b/Sources/HTTPEngine/HTTPEngine+ConvenienceMethods.swift index f03720a..8144168 100644 --- a/Sources/HTTPEngine/HTTPEngine+ConvenienceMethods.swift +++ b/Sources/HTTPEngine/HTTPEngine+ConvenienceMethods.swift @@ -27,8 +27,9 @@ public extension HTTPEngine { /// ```swift /// // example validator /// validator: { $0 == 202 } + /// // Failure throws Errors.Response.unexpectedStatusCode(HTTPURLRequest) /// ``` - public func makeRequestAndParseResponse( + func makeRequestAndParseResponse( _ decodableResponse: Response.Type, method: HTTPMethod, url: String, @@ -64,8 +65,9 @@ public extension HTTPEngine { /// ```swift /// // example validator /// validator: { $0 == 202 } + /// // Failure throws Errors.Response.unexpectedStatusCode(HTTPURLRequest) /// ``` - public func makeRequestAndParseResponse( + func makeRequestAndParseResponse( _ decodableResponse: Response.Type, method: HTTPMethod, url: String, @@ -95,6 +97,7 @@ public extension HTTPEngine { /// ```swift /// // example validator /// validator: { $0 == 202 } + /// // Failure throws Errors.Response.unexpectedStatusCode(HTTPURLRequest) /// ``` func get( _ value: Response.Type, @@ -120,6 +123,7 @@ public extension HTTPEngine { /// ```swift /// // example validator /// validator: { $0 == 202 } + /// // Failure throws Errors.Response.unexpectedStatusCode(HTTPURLRequest) /// ``` func post( _ value: Response.Type, @@ -145,6 +149,7 @@ public extension HTTPEngine { /// ```swift /// // example validator /// validator: { $0 == 202 } + /// // Failure throws Errors.Response.unexpectedStatusCode(HTTPURLRequest) /// ``` func post( _ value: Response.Type, diff --git a/Sources/HTTPEngine/HTTPEngine.swift b/Sources/HTTPEngine/HTTPEngine.swift index 4bf1438..dfda053 100644 --- a/Sources/HTTPEngine/HTTPEngine.swift +++ b/Sources/HTTPEngine/HTTPEngine.swift @@ -1,8 +1,11 @@ import Foundation import Combine +/// HTTP Request Header public typealias Header = [String: String] +/// Boolean that represents the success or failure of the ResponseValidationClosure public typealias ValidResponse = Bool +/// A function that takes the HTTPResonse's StatusCode in for comparison. Return `true` if the code is expected or `false` if the function should throw an error. public typealias ResponseValidationClosure = (Int) -> ValidResponse public struct HTTPEngine { @@ -75,6 +78,7 @@ public struct HTTPEngine { /// ```swift /// // example validator /// validator: { $0 == 202 } + /// // Failure throws Errors.Response.unexpectedStatusCode(HTTPURLRequest) /// ``` public func makeRequest( method: HTTPMethod, diff --git a/Sources/HTTPEngine/HTTPMethod.swift b/Sources/HTTPEngine/HTTPMethod.swift index c762fbf..b611ef7 100644 --- a/Sources/HTTPEngine/HTTPMethod.swift +++ b/Sources/HTTPEngine/HTTPMethod.swift @@ -1,9 +1,14 @@ import Foundation + public enum HTTPMethod: String, CaseIterable { case post case get case patch case delete case put + case head + case options + case trace + case connect } diff --git a/Sources/HTTPEngine/Utilities.swift b/Sources/HTTPEngine/Utilities.swift index 6e19ee7..bef6693 100644 --- a/Sources/HTTPEngine/Utilities.swift +++ b/Sources/HTTPEngine/Utilities.swift @@ -2,6 +2,9 @@ import Foundation import Combine public extension URLRequest { + + /// Combine convenience method + /// - Returns: URLSession.DataTaskPublisher func dataTaskPublisher() -> URLSession.DataTaskPublisher { return URLSession.shared.dataTaskPublisher(for: self) }