-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRequestable.swift
More file actions
58 lines (55 loc) · 2.66 KB
/
Requestable.swift
File metadata and controls
58 lines (55 loc) · 2.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import Foundation
/// A protocol for a request type. Used to build backend API requests.
public protocol Requestable: Sendable {
/// The request authorization. Defaults to `none`.
var authorization: Request.Authorization { get }
/// The content type of the request. Defaults to `nil`.
var contentType: HTTP.ContentType? { get }
/// A time interval for request timeout. Defaults to 30 seconds.
var timeoutInterval: TimeInterval { get }
/// The request parameters. Defaults to an empty dictionary.
var parameters: HTTP.Parameters { get }
/// An optional `Encodable` body for JSON requests. When provided with `.json` encoding,
/// this is encoded directly using `JSONEncoder` instead of serializing `parameters`.
var body: (any Encodable & Sendable)? { get }
/// An optional multipart form data body for file uploads. Used with `.multipart` encoding.
var multipartBody: MultipartFormData? { get }
/// The encoding used fot the request
var encoding: Request.Encoding { get }
/// The request HTTP method
var httpMethod: HTTP.Method { get }
/// The API endpoint
var endpoint: EndpointType { get }
}
// MARK: -
public extension Requestable {
/// Configure a new `URLRequest` from a requestable object with a server configuration
/// - parameter server: The given server config to use
/// - parameter logger: The logger to use for request logging
/// - parameter encoder: The JSON encoder to use for encoding the body. Defaults to a new `JSONEncoder`.
/// - throws: An error if the request can't be build
/// - returns: A new `URLRequest` with all the configurations
func configure(withServer server: ServerConfig, using logger: NetworkLoggerProtocol, encoder: JSONEncoder = JSONEncoder()) throws -> URLRequest {
var encodedBody: Data?
if let body {
encodedBody = try encoder.encode(body)
}
var multipartData: (data: Data, contentType: String)?
if let multipartBody {
multipartData = (data: multipartBody.encode(), contentType: multipartBody.contentType)
}
let config = Request.Config(request: self, server: server, encodedBody: encodedBody, multipartData: multipartData)
let urlRequest = try URLRequest(withConfig: config)
logger.logRequest(urlRequest)
return urlRequest
}
}
// MARK: -
public extension Requestable {
var authorization: Request.Authorization { .none }
var timeoutInterval: TimeInterval { 30.0 }
var contentType: HTTP.ContentType? { nil }
var parameters: HTTP.Parameters { [:] }
var body: (any Encodable & Sendable)? { nil }
var multipartBody: MultipartFormData? { nil }
}