ComposableRequest
public struct ComposableRequest<RequestBody, ResponseBody, ResponseError> : Requestable where ResponseError : Error
A ComposableRequest is a generic type used to execute HTTP requests without needing to create request-specific Requestable types.
Basic usage might look like this:
cancellable = ComposableRequest<AnyJSON, AnyJSON, HTTPError>()
.path("/users")
.method(.post)
.headers([.contentType: .contentType(.json)])
.body(
[
"name": "morpheus",
"job": "leader"
]
)
.send(on: "https://reqres.in/api")
.sink { result in
// handle completion
} receiveValue: { response in
// handle response
}
You can specialize a ComposableRequest with body types, as well as an error model of your choosing.
If you use body types String, Data, Codable, RequestParameters or AnyJSON, default encoder and decoders are provided for you.
If you use an error type HTTPError, a response validator is used for you.
If you provide your own error model, rember to provide a validator, as the default validator automatically allows all responses to continue
-
Create a
ComposableRequestDeclaration
Swift
public init()
-
Set the request path
let request = ComposableRequest<Any, Any, Error>() .path("/posts/create")Declaration
Swift
public func path(_ path: String) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
pathThe path
Return Value
The request
-
Set the request path
let request = ComposableRequest<Any, Any, Error>() .path { // ... logic to determine the request path ... return path }Declaration
Swift
public func path(_ pathBuilder: @escaping () -> String) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
pathBuilderThe closure that builds the request path
Return Value
The request
-
Add a URL query
let request = ComposableRequest<Any, Any, Error>() .query(URLQueryItem(name: "key", value: "value"))Declaration
Swift
public func query(_ query: URLQueryItem) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
queryThe query parameter
Return Value
The request
-
Add a URL query
let request = ComposableRequest<Any, Any, Error>() .query { // ... logic to determine the request query ... return URLQueryItem(name: "key", value: "value") }Declaration
Swift
public func query(_ queryBuilder: @escaping () -> URLQueryItem) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
queryBuilderThe closure that returns the URL query
Return Value
The request
-
Add URL queries
let request = ComposableRequest<Any, Any, Error>() .query(URLQueryItem(name: "key1", value: "value1"), URLQueryItem(name: "key2", value: "value2"))Declaration
Swift
public func query(_ queries: URLQueryItem...) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
queriesQuery items
Return Value
The request
-
Replace the exsting URL queries with new ones
let request = ComposableRequest<Any, Any, Error>() .queries([URLQueryItem(name: "key1", value: "value1") URLQueryItem(name: "key2", value: "value2")])Declaration
Swift
public func queries(_ query: [URLQueryItem]) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
queriesThe queries
Return Value
The request
-
Replace the existing URL queries with new ones
let request = ComposableRequest<Any, Any, Error>() .queries { // ... logic to determine the request queries ... return [URLQueryItem(name: "key1", value: "value1") URLQueryItem(name: "key2", value: "value2")] }Declaration
Swift
public func queries(_ queryBuilder: @escaping () -> [URLQueryItem]) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
queryBuilderThe closure that builds the queries
Return Value
The request
-
Set the HTTP method
let request = ComposableRequest<Any, Any, Error>() .method(.post)Declaration
Swift
public func method(_ method: RequestMethod) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
methodThe method to use
Return Value
The request
-
Set the HTTP method
let request = ComposableRequest<Any, Any, Error>() .method { ... logic to determine the request method ... return .post }Declaration
Swift
public func method(_ methodBuilder: @escaping () -> RequestMethod) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
methodBuilderClosure that builds the request method
Return Value
The request
-
Add a header
let request = ComposableRequest<Any, Any, Error>() .header(key: "User-Agent", value: "MyUserAgentValue")Declaration
Swift
public func header(key: RequestHeaders.Key, value: RequestHeaders.Value?) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
keyThe header field
valueThe header value
Return Value
The request
-
Add a header
let request = ComposableRequest<Any, Any, Error>() .header { /// ... logic to determine header ... return (key: "User-Agent", value: "MyUserAgentValue") }Declaration
Swift
public func header(_ headerBuilder: @escaping () -> (RequestHeaders.Key, RequestHeaders.Value?)) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
headerBuilderThe closure that builds the header
Return Value
The request
-
Add headers
let request = ComposableRequest<Any, Any, Error>() .headers(pair1, pair2, pair3)Declaration
Swift
public func headers(_ pairs: (key: RequestHeaders.Key, value: RequestHeaders.Value)...) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
pairsThe pairs of headers to add
Return Value
The request
-
Add headers
let request = ComposableRequest<Any, Any, Error>() .headers([pair1, pair2, pair3])Declaration
Swift
public func headers(_ pairs: [(key: RequestHeaders.Key, value: RequestHeaders.Value)]) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
pairsThe pairs of headers to add
Return Value
The request
-
Replace the existing headers with new ones
let request = ComposableRequest<Any, Any, Error>() .headers(["User-Agent" : "MyAgent", "ContentType": "application/json"])Declaration
Swift
public func headers(_ headers: RequestHeaders) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
headersThe new headers
Return Value
The request
-
Replace the existing headers with new ones
let request = ComposableRequest<Any, Any, Error>() .headers { /// ... logic to determine header ... return ["User-Agent" : "MyAgent", "ContentType": "application/json"] }Declaration
Swift
public func headers(_ headersBuilder: @escaping () -> RequestHeaders) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
headersBuilderThe closure that builds the headers
Return Value
The request
-
Set the request body
let request = ComposableRequest<Any, Any, Error>() .body(myBody)Declaration
Swift
public func body(_ body: RequestBody?) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
bodyThe body
Return Value
The request
-
Set the request body
let request = ComposableRequest<Any, Any, Error>() .body { // ... logic to determine body ... return myBody }Declaration
Swift
public func body(_ bodyBuilder: @escaping () -> RequestBody?) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
bodyBuilderThe closure that builds the body
Return Value
The request
-
Set the request authentication
let request = ComposableRequest<Any, Any, Error>() .authentication(.token(.bearer, "myToken"))Declaration
Swift
public func authenticate(with authentication: RequestAuthentication?) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
authenticationThe authentication
Return Value
The request
-
Set the request authentication
let request = ComposableRequest<Any, Any, Error>() .authentication { /// ... logic to determine authentication ... return .token(.bearer, "myToken")) }Declaration
Swift
public func authenticate(with authenticationBuilder: @escaping () -> RequestAuthentication?) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
authenticationBuilderThe closure that builds the authentication
Return Value
The request
-
Set the request authentication using basic username and password credentials
let request = ComposableRequest<Any, Any, Error> .authentication(withUsername: "myUserName", password: "myPassword")Declaration
Swift
public func authenticate(withUsername username: String, password: String) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
usernameUsername
passwordPassword
Return Value
The request
-
Set the request authentication using an authorization token
let request = ComposableRequest<Any, Any, Error> .authentication(withToken: "myToken", type: .bearer)Declaration
Swift
public func authenticate(withToken token: String, type: RequestAuthentication.TokenType) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
tokenThe token
typeThe type of token
Return Value
the request
-
Add a fallback response to the request
Declaration
Swift
public func fallbackResponse(_ fallbackResponse: RequestResponse<ResponseBody>?) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
fallbackResponseThe response to use if the request fails
Return Value
The request
-
Add a fallback response to the request
Declaration
Swift
public func fallbackResponse(_ fallbackResponseBuilder: @escaping () -> RequestResponse<ResponseBody>?) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
fallbackResponseClosure that builds the fallback response, used if the request fails
Return Value
The request
-
Add a request body encoder
Declaration
Swift
public func encodeBody(with handler: @escaping (RequestBody?) throws -> Data?) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
handlerClosure used to transform
RequestBodyintoDataReturn Value
The request
-
Add a request body encoder
Declaration
Swift
public func encodeBody(with encoder: BodyEncoder<RequestBody>) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
encoderEncoder used to handle request
Return Value
The request
-
Add a response body decoder
Declaration
Swift
public func decodeBody(with handler: @escaping (Data?) throws -> ResponseBody?) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
handlerClosure used to transform
ResponseBodyintoDataReturn Value
The request
-
Add a response body decoder
Declaration
Swift
public func decodeBody(with decoder: BodyDecoder<ResponseBody>) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
decoderDecoder used to handle response
Return Value
The request
-
Add a response validator
Declaration
Swift
public func validateResponse(with handler: @escaping (Response) -> Result<Response, ResponseError>) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
handlerClosure used to validate a
ResponseReturn Value
The request
-
Add a response validator
Declaration
Swift
public func validateResponse(with responseValidator: ResponseValidator<ResponseBody, ResponseError>) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
responseValidatorResponse validator
Return Value
The request
-
Add a timeout interval
Declaration
Swift
public func timeoutInterval(_ interval: TimeInterval) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
intervalThe interval for requests to timeout
Return Value
The request
-
Add a timeout interval
Declaration
Swift
public func timeoutInterval(_ intervalBuilder: @escaping () -> TimeInterval) -> ComposableRequest<RequestBody, ResponseBody, ResponseError>Parameters
intervalBuilderClosure to build the timeout interval
Return Value
The request
-
Send this request on the main thread
Declaration
Swift
public func send(on host: String, retries: Int = 0, sla: TimeInterval = 120) -> AnyPublisher<Response, Failure>Parameters
hostThe host
retriesThe number of retries
slaThe SLA to use before timing out
Return Value
A publisher to observe request responses
-
Send this request
Declaration
Swift
public func send<S>(on host: String, retries: Int = 0, sla: S.SchedulerTimeType.Stride = .seconds(120), using scheduler: S) -> AnyPublisher<Response, Failure> where S: SchedulerParameters
hostThe host
retriesThe number of retries
slaThe SLA to use before timing out
schedulerThe scheduler to use
Return Value
A publisher to observe request responses
-
Declaration
Swift
public var path: String { get } -
Declaration
Swift
public var query: [URLQueryItem] { get } -
Declaration
Swift
public var method: RequestMethod { get } -
Declaration
Swift
public var headers: RequestHeaders { get } -
Declaration
Swift
public var body: RequestBody? { get } -
Undocumented
Declaration
Swift
public var authentication: RequestAuthentication? { get } -
Declaration
Swift
public var fallbackResponse: RequestResponse<ResponseBody>? { get } -
Declaration
Swift
public var requestEncoder: BodyEncoder<RequestBody> { get } -
Declaration
Swift
public var responseDecoder: BodyDecoder<ResponseBody> { get } -
Declaration
Swift
public var responseValidator: ResponseValidator<ResponseBody, ResponseError> { get } -
Declaration
Swift
public var timeoutInterval: TimeInterval { get }
View on GitHub
Install in Dash
ComposableRequest Structure Reference