Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

APIClient v2 #36

Closed
kean opened this issue Jul 8, 2022 · 3 comments
Closed

APIClient v2 #36

kean opened this issue Jul 8, 2022 · 3 comments

Comments

@kean
Copy link
Owner

kean commented Jul 8, 2022

I'm considering redesigning the APIClient public API for Get 1.0. It was initially designed to accommodate only the most basic scenarios, but I'd like it to be more flexible. Here is a draft of a new API.

public protocol APIClient2 {
    // No changes in these APIs, except for removal of magic `Response<Data>` and `Response<String>` support (see p3)
    func send<T: Decodable>(_ request: Request<T>) async throws -> Response<T>
    func send<T: Decodable>(_ request: Request<T?>) async throws -> Response<T?>
    @discardableResult func send(_ request: Request<Void>) async throws -> Response<Void>

    // Getting decoded response for `URL`/`URLRequest`
    func value<T: Decodable>(_ type: T.Type, for url: URL) async throws -> Response<T>
    func value<T: Decodable>(_ type: T.Type, for urlRequest: URLRequest) async throws -> Response<T>

    // Getting raw response `Data` (no decoding)
    func data(for url: URL) async throws -> Response<Data>
    func data(for urlRequest: URLRequest) async throws -> Response<Data>
    func data<T>(for request: Request<T>) async throws -> Response<Data>

    // Getting response `String` (no decoding except for .utf8 decoding)
    func string(for url: URL) async throws -> Response<String>
    func string(for urlRequest: URLRequest) async throws -> Response<String>
    func string<T>(for request: Request<T>) async throws -> Response<String>

    // (?) Add `URLSessionDataDelegate` to all APIs too for pogress reporting, etc.
    func response<T: Decodable>(for request: Request<T>, delegate: URLSessionDataDelegate) async throws -> Response<T>
}

Main Changes

  1. You can now use URL and URLRequest in addition to Request
  2. Pass URLSessionDataDelegate for progress reporting, per-task auth, etc.
  3. Remove magic Response<Data> and Response<String> support from send(_:). If you use send(_:), they'll just use the default Decodable implementation for these types. You'll need to call data(for:) or string(for:) instead – faster, more discoverable, self-documenting
@kean
Copy link
Owner Author

kean commented Jul 8, 2022

With the new APIs, you'll be able to use URLRequest, but what if you want to, let's say, change only the cache policy?

func send<Response>(
    _ request: Request<Response>,
    cachePolicy: URLRequest.CachePolicy = .useProtocolCachePolicy
) async throws -> Response where Response: Decodable

@kean
Copy link
Owner Author

kean commented Jul 9, 2022

Another options to cover the latest requirement:

public struct RequestOptions {
    public var cachePolicy: URLRequest.CachePolicy?
    public var timeoutInterval: TimeInterval?

    // Etc
}

public protocol APIClient2 {
    public func send<T: Decodable>(
        _ request: Request<T>,
        options: RequestOptions = .init(),
        delegate: URLSessionDataDelegate? = nil
    ) async throws -> Response<T>
}

@kean
Copy link
Owner Author

kean commented Jul 9, 2022

Going with RequestOptions and also a low-level API to send URLRequest and decoding a request.

@kean kean closed this as completed Jul 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant