Kitura / SwiftyRequest

SwiftyRequest is an HTTP networking library built for Swift.
Apache License 2.0
110 stars 19 forks source link

SwiftNIOs Future/Promises in SwiftyRequest #81

Closed gerwindehaan closed 5 years ago

gerwindehaan commented 5 years ago

We started using SwiftyRequest to built a new HTTP Client tool which allows our server apps to interact with various REST API services. We started out by just using its Response callbacks to chain requests. To avoid nested callbacks pyramids and to better chain these for readibility, we started exploring possibilities to use Future/Promise constructs and integrate this with SwiftyRequest features.

In our most recent experiment we selected SwiftNIOs EventLoopFuture constructs as an alternative to other Future/Promise solutions we used in the past. The two main reasons here are the availability on Linux and that this is also used in async-http-client on which in turn SwiftyRequest is building upon since recently.

After wrapping the Reponse callbacks in EventLoopFuture in our application, which seems to work, we started wondering:

  1. with the desire of Futures, should we rather work directly work on async-http-client, with the possible need to migrate missing/unique features from SwiftyRequest into that?
  2. should we do anything specific for selecting an EventLoop like re-using the one from SwiftyRequest to share amongst our application (although it is private in the current implementation)?
  3. would it be sensible to have the internally used EventLoopFuture exposed directly from SwiftyRequest instead? I can imagine this would be technically feasible, but at the same time not desirable from an abstraction point of view.

    We could imagine something like this:

    In addition to the current RestRequest.response method:

    public func response(templateParams: [String: String]? = nil,
                            queryItems: [URLQueryItem]? = nil,
                            completionHandler: @escaping (Result<HTTPClient.Response, RestError>) -> Void)

    have similar method with an EventLoopFuture return type:

    public func responseFuture(templateParams: [String: String]? = nil,
                            queryItems: [URLQueryItem]? = nil) -> EventLoopFuture<Result<HTTPClient.Response, RestError>>

We're thinking of trying to build a proof-of-concept, but any suggestions or warnings are welcome.

ianpartridge commented 5 years ago

Hello, thank you for your interest in SwiftyRequest.

I would recommend that you build directly on async-http-client rather than wrapping SwiftyRequest in another layer of futures/promises, if an async API is a requirement for you.

HTTPClient.get() returns you an EventLoopFuture directly which you can attach callbacks to. You can also configure it with an EventLoopGroup of your choice.

Our intention in SwiftyRequest is to hide future/promises from our users, so if you are integrating with other parts of the SSWG ecosystem you are better off using async-http-client directly.

I hope that helps - please don't hesitate to reopen if you have more questions.