swift-http-types
swift-http-types copied to clipboard
How to set body data to a `HTTPRequest`?
That seems not supported yet?
It is not currently supported. We need to find good mechanisms for sending data, stream, file, and potentially multipart body, and it will likely be a part of the future server and client HTTP APIs rather than on the currency types themselves.
https://github.com/atrick/swift-evolution/blob/bufferview-roadmap/visions/view-types.md https://forums.swift.org/t/requirements-for-a-high-level-http-server-type/65337
In the meantime, I think we could add URLSession
convenience methods that take in a body parameter.
Currently, in order to send a POST
request, the developer needs to manually convert the HTTPRequest
to a URLRequest
so that they can set the body. Then, they would need to manually convert the URLResponse
to an HTTPResponse
because there is no URLSession
convenience method that accepts a URLRequest
.
I was thinking the following two convenience methods could be added:
extension URLSession {
func data(
for request: HTTPRequest,
body: Data,
delegate: URLSessionTaskDelegate? = nil
) async throws -> (Data, HTTPResponse) {
…
}
func data(
for request: HTTPRequest,
bodyStream: InputStream,
delegate: URLSessionTaskDelegate? = nil
) async throws -> (Data, HTTPResponse) {
…
}
}
We currently have these 2:
public func upload(for request: HTTPRequest, fromFile fileURL: URL, delegate: URLSessionTaskDelegate? = nil) async throws -> (Data, HTTPResponse)
public func upload(for request: HTTPRequest, from bodyData: Data, delegate: URLSessionTaskDelegate? = nil) async throws -> (Data, HTTPResponse)
InputStream should be provided in needNewBodyStream
delegate method since URLSession would ask for a new stream from the beginning in situations such as redirection or authentication. It's discouraged to provide a single stream upfront. You can convert HTTPRequest to URLRequest then call uploadTaskWithStreamedRequest
. A convenience was not provided because InputStream doesn't work very well with Swift concurrency.
Ah, I didn’t realize that URLSessionUploadTask
can do short-lived requests; I thought it was only for long-lived requests. Thanks!
URLSessionDataTask
also supports a request body via URLRequest.httpBody
. Do you know what the difference is between using URLSessionDataTask
vs. URLSessionUploadTask
for short-lived requests with bodies? (If so, please also answer this StackOverflow question. 😆)
Upload task is a subclass of data task, so there is little difference between the 2 of them. It's recommended to use upload task instead of httpBody
/httpBodyStream
properties on the URLRequest. Upload/download tasks also have the benefit of working with background sessions (but you'll have to use the delegate instead of the convenience or async methods).