# \[Feedback\] NIO-based HTTP Client

**URL:** <https://forums.swift.org/t/feedback-nio-based-http-client/26149>\
**Category:** Proposals\
**Tags:** http\
**Created:** [June 21, 2019, 12:20pm UTC](https://forums.swift.org/t/feedback-nio-based-http-client/26149 "2019-06-21T12:20:19Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![artemredkin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/artemredkin/32/7066_2.png) [@artemredkin](https://forums.swift.org/u/artemredkin)\
**Post date:** [June 21, 2019, 12:20pm UTC](https://forums.swift.org/t/feedback-nio-based-http-client/26149/1 "2019-06-21T12:20:19Z")

</div>

# SSWG HTTP Client Library

- Proposal: SSWG-0005
- Authors: [Artem Redkin](https://github.com/artemredkin), [Tomer Doron](https://github.com/tomerd), [Tanner Nelson](https://github.com/tanner0101), [Ian Partridge](https://github.com/ianpartridge/)
- Sponsors: Swift Server Working Group
- Status: [Implemented](https://github.com/swift-server/swift-nio-http-client)
- Pitch: [Generic HTTP Client Library](https://forums.swift.org/t/generic-http-client-library-pitch/23341)
- Discussion: [Generic HTTP Client Library](https://forums.swift.org/t/discussion-nio-based-http-client/24195)

## Introduction

Number of projects implemented their own HTTP client libraries, like:

- [IBM-Swift](https://github.com/IBM-Swift/Kitura-NIO/blob/master/Sources/KituraNet/HTTP/HTTPServer.swift)
- [vapor](https://github.com/vapor/http/blob/master/Sources/HTTP/Responder/HTTPClient.swift)
- [smoke-framework](https://github.com/amzn/smoke-http/blob/master/Sources/SmokeHTTPClient/HTTPClient.swift)

This shows that there is a need for generic, multi-purpose, non-blocking, asynchronous HTTP client library built on top of `SwiftNIO`. SSWG aims to provide a number of packages that could be shared between different projects, and I think proposed HTTP client library would be a good fit for those projects and other use-cases.

## Motivation

Having one, community-driver project that can be shared between different projects will hopefully solve the need to implement this functionality in every project from scratch.

## Proposed solution

Proposed solution is to have a `HTTPClient` class, that support a number of often-used methods, as well as an ability to pass a delegate for more precise control over the HTTP data transmission:

```swift
class HTTPClient {

    public func get(url: String, timeout: Timeout? = nil) -> EventLoopFuture<Response> {
    }

    public func post(url: String, body: Body? = nil, timeout: Timeout? = nil) -> EventLoopFuture<Response> {
    }

    public func put(url: String, body: Body? = nil, timeout: Timeout? = nil) -> EventLoopFuture<Response> {
    }

    public func delete(url: String, timeout: Timeout? = nil) -> EventLoopFuture<Response> {
    }

    public func execute(request: Request, timeout: Timeout? = nil) -> EventLoopFuture<Response> {
    }

    public func execute<T: HTTPClientResponseDelegate>(request: Request, delegate: T, timeout: Timeout? = nil) -> Task<T.Response> {
    }
}

```

For the first release we have the following features implemented:

1. Simple follow-redirects (cookie headers are dropped)
2. Streaming body download/upload
3. TLS support
4. Cookie parsing (but not storage)

## Detailed design

### Lifecycle

Creating a client is strait-forward:

```swift
let client = HTTPClient(eventLoopGroupProvider: .createNew)

```

This initializer will create new `EventLoopGroup`, so every client instance will have it's own separate `EventLoopGroup`. Alternatively, users can supply shared `EventLoopGroup`:

```swift
let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
let client = HTTPClient(eventLoopGroupProvider: .shared(group))

```

It is important to shutdown your client instance after it is no longer needed, in order to shutdown internal `SwiftNIO` machinery:

```swift
try client.syncShutdown()

```

In case `EventLoopGroup` was provided to the client instance, there is no need to shutdown the client, we expect that lifecycle of that group will be controlled by its owner.

### Request

In case helper methods do not provide required functionality (for example, if user needs to set headers, or use specific HTTP method), clients of the library can use `HTTPClient.Request`:

```swift
extension HTTPClient {
    struct Body {
        public struct StreamWriter {
            let closure: (IOData) -> EventLoopFuture<Void>

            public func write(_ data: IOData) -> EventLoopFuture<Void> {
                return self.closure(data)
            }
        }

        public var length: Int?
        public var stream: (StreamWriter) -> EventLoopFuture<Void>

        public static func byteBuffer(_ buffer: ByteBuffer) -> Body
        public static func stream(length: Int? = nil, _ stream: @escaping (StreamWriter) -> EventLoopFuture<Void>) -> Body
        public static func data(_ data: Data) -> Body
        public static func string(_ string: String) -> Body
    }

    struct Request {
        public var version: HTTPVersion
        public var method: HTTPMethod
        public var url: URL
        public var headers: HTTPHeaders
        public var body: Body?

        public init(url: String,
                    version: HTTPVersion = HTTPVersion(major: 1, minor: 1),
                    method: HTTPMethod = .GET,
                    headers: HTTPHeaders = HTTPHeaders(),
                    body: Body? = nil) throws {}
    }
}

```

Example:

```swift
var request = try HTTPClient.Request(url: "http://swift.org")
request.headers.add(name: "User-Agent", value: "nio-http-client")

let future = client.execute(request: request)

```

### Response

`HTTPClient`'s methods return an `EventLoopFuture<HTTPClient.Reponse`. This struct is defined as follows:

```swift
extension HTTPClient {
    struct Response {
        public var host: String
        public var status: HTTPResponseStatus
        public var headers: HTTPHeaders
        public var body: ByteBuffer?
    }
}

```

where `HTTPResponseStatus` is an enum that describes HTTP codes that could be returned by the server:

```swift
client.get(url: "http://swift.org").whenSuccess { response in
    switch response.status {
        case .ok: print("server return 200 OK")
        case .notFound: print("server return 404 Not Found")
        case .internalServerError: print("server return 500 Internal Server Error")
        ...
    }
}

```

### HTTPClientResponseDelegate

In addition to helper/request methods, library also provides the following delegate, which provides greater control over how HTTP response is processed:

```swift
public protocol HTTPClientResponseDelegate: class {
    associatedtype Response

    // this is executed right after request head was sent, called once
    func didSendRequestHead(task: HTTPClient.Task<Response>, _ head: HTTPRequestHead) {}

    // this is executed when request body part is sent, could be called zero or more times
    func didSendRequestPart(task: HTTPClient.Task<Response>, _ part: IOData) {}

    // this is executed when request is fully sent, called once
    func didSendRequest(task: HTTPClient.Task<Response>) {}

    // this method will be called when we receive Head response, with headers and status code
    // in case backpressure is needed, all reads will be paused until returned future is resolved
    func didReceiveHead(task: HTTPClient.Task<Response>, _ head: HTTPResponseHead) -> EventLoopFuture<Void> {
        return task.eventLoop.makeSucceededFuture(())
    }

    // this method will be called multiple times with chunks of the HTTP response body (if there is a body)
    // in case backpressure is needed, all reads will be paused until returned future is resolved
    func didReceivePart(task: HTTPClient.Task<Response>, _ buffer: ByteBuffer) -> EventLoopFuture<Void> {
        return task.eventLoop.makeSucceededFuture(())
    }

    // this method will be called if an error occurs during request processing
    func didReceiveError(task: HTTPClient.Task<Response>, _ error: Error)

    // this will be called when HTTP response is read fully
    func didFinishRequest(task: HTTPClient.Task<Response>) throws -> Response
}

```

This delegate will be especially helpful when you need to process HTTP response body in a streaming fashion, for example:

```swift
class CountingDelegate: HTTPClientResponseDelegate {
    typealias Response = Int

    var count = 0

    func didReceivePart(_ buffer: ByteBuffer) -> EventLoopFuture<Void> {
        count += buffer.readableBytes
        return task.eventLoop.makeSucceededFuture(())
    }

    func didFinishRequest() throws -> Int {
        return count
    }
}

let request = try HTTPRequest(url: "https://swift.org")
let delegate = CountingDelegate()

try client.execute(request: request, delegate: delegate).futureResult.whenSuccess { count in
    print(count) // count is of type Int
}

```

---

<div class="post-metadata">

**Author:** ![IanPartridge](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ianpartridge/32/434_2.png) [@IanPartridge](https://forums.swift.org/u/IanPartridge)\
**Post date:** [June 21, 2019, 9:22pm UTC](https://forums.swift.org/t/feedback-nio-based-http-client/26149/2 "2019-06-21T21:22:09Z")

</div>

Thanks for posting this. I think this package is shaping up really nicely.

One thing I was wondering about... should we use deadlines instead of timeouts? They can compose better when you have multiple requests that you want to chain within a certain total time.

---

<div class="post-metadata">

**Author:** ![johannesweiss](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/johannesweiss/32/38183_2.png) [@johannesweiss](https://forums.swift.org/u/johannesweiss)\
**Post date:** [June 25, 2019, 12:20pm UTC](https://forums.swift.org/t/feedback-nio-based-http-client/26149/3 "2019-06-25T12:20:50Z")

</div>

Just like for Redis and Postgres (both of which are now done), I propose for this package to change its name. First of all, there is [another](https://github.com/emarashliev/swift-nio-http-client) package using the exact same (project & module) name which is kind of a no-go. And secondly, I think the module name `NIOHTTPClient` is way too close to NIO's existing `NIOHTTP1Client` module name.

What about

- `AsyncHTTPClient` (`async-http-client`)
- `AsyncRequests` (`async-requests`)
- `HTTPClientNIO` (`http-client-nio`)

or something else that's not clashing with existing packages nor sitting in the same prefix as other existing software.

---

<div class="post-metadata">

**Author:** ![IanPartridge](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ianpartridge/32/434_2.png) [@IanPartridge](https://forums.swift.org/u/IanPartridge)\
**Post date:** [June 25, 2019, 12:44pm UTC](https://forums.swift.org/t/feedback-nio-based-http-client/26149/4 "2019-06-25T12:44:08Z")

</div>

I feel pretty strongly that we should aim for some consistency in package and module naming. The NIO team want to reserve the NIO prefix, which is fine, but for the rest we should define some conventions. This will help with discoverability, marketing of our overall effort, and developer sanity.

Currently for package naming we have:

- `swift-nio-http-client`
- `postgres-nio`
- `swift-redis-nio-client`

So basically, a mess.

I propose we go with `swift-http-client-nio`. In other words:

- `swift` - common prefix on everything, makes it clear to people driving by on GitHub that this is a Swift package
- `http-client` - obvious, that's what it is. Enforce uniqueness of this for SSWG packages.
- `nio` - common suffix for NIO-based packages going through SSWG. Avoids collisions with non NIO-based HTTP clients and helps with the marketing of NIO as the go-to foundation for server-side Swift.

Getting consistency would involve some more renaming:

- `nio-postgres` becomes `swift-postgres-client-nio`
- `swift-redis-nio-client` becomes `swift-redis-client-nio`

For module names we can drop the "swift" and go with `import HTTPClientNIO`, `import PostgresClientNIO`, `import RedisClientNIO`.

Thoughts? @Mordil @tanner0101

---

<div class="post-metadata">

**Author:** ![johannesweiss](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/johannesweiss/32/38183_2.png) [@johannesweiss](https://forums.swift.org/u/johannesweiss)\
**Post date:** [June 25, 2019, 1:19pm UTC](https://forums.swift.org/t/feedback-nio-based-http-client/26149/5 "2019-06-25T13:19:06Z")

</div>

> [@IanPartridge](#):
>
> I feel pretty strongly that we should aim for some consistency in package and module naming.

I know we all like consistency. The problem with consistency is that it also facilitates clashes 🙂. So I'd like to argue against too much consistency...

> [@IanPartridge](#):
>
> The NIO team want to reserve the NIO prefix

For everybody's benefit: We don't want to reserve the `NIO` prefix for our own sake but to prevent clashes with NIO stuff. NIO does add top-level types/modules in SemVer minor versions but we will always prefix those with `NIO`. That gives other package authors some help in how to prevent clashes with NIO things. Obviously, clashes are also possible with other packages but the NIO team thought we better start somewhere and have others possibly follow later also putting their new types into certain namespaces.

> [@IanPartridge](#):
>
> - `swift` - common prefix on everything, makes it clear to people driving by on GitHub that this is a Swift package

What's the benefit of the `swift-` prefix? I don't think it adds much value and it makes clashes more likely. I'm not arguing against anybody using it if they feel like it but I'm not sure if we should mandate it.

Given how easily we can have clashes in Swift today, I think there's some actual benefit in using more 'cute' names such as `MongoKitten`, `Stencil`, `Kitura`, `Vapor`, `Alamofire`, `Kingfisher`, ...

---

<div class="post-metadata">

**Author:** ![IanPartridge](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ianpartridge/32/434_2.png) [@IanPartridge](https://forums.swift.org/u/IanPartridge)\
**Post date:** [June 25, 2019, 1:48pm UTC](https://forums.swift.org/t/feedback-nio-based-http-client/26149/6 "2019-06-25T13:48:15Z")

</div>

> [@johannesweiss](#):
>
> What's the benefit of the `swift-` prefix?

"makes it clear to people driving by on GitHub that this is a Swift package". And the precedent is there with `swift-nio`, `swift-log` etc.

---

<div class="post-metadata">

**Author:** ![johannesweiss](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/johannesweiss/32/38183_2.png) [@johannesweiss](https://forums.swift.org/u/johannesweiss)\
**Post date:** [June 25, 2019, 3:22pm UTC](https://forums.swift.org/t/feedback-nio-based-http-client/26149/7 "2019-06-25T15:22:50Z")

</div>

> [@IanPartridge](#):
>
> > What's the benefit of the `swift-` prefix?
> 
> "makes it clear to people driving by on GitHub that this is a Swift package".

Hmm, could be mentioned in the readme first thing, right?

> [@IanPartridge](#):
>
> And the precedent is there with `swift-nio` , `swift-log` etc.

Heh yes 🙂. I think that's because both `log` and `nio` are words that have been used before for different things in different context.

---

<div class="post-metadata">

**Author:** ![rafiki270](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/rafiki270/32/6209_2.png) [@rafiki270](https://forums.swift.org/u/rafiki270)\
**Post date:** [June 25, 2019, 3:39pm UTC](https://forums.swift.org/t/feedback-nio-based-http-client/26149/8 "2019-06-25T15:39:38Z")

</div>

Hi, first I would like to say thanks for the amazing library, have been using it now for about a month and it's just great! The only downside to it is the missing release/tag so I hope you guys won't mind me presenting my opinion over something I haven't even in a slightest bit helped create.

I am not a big fan of having these long names as they are hard to remember, I think any github library should be managed partially as a business, of which a brand is a big part of, if it's to gain any traction. I believe that a part of the massive success of Alamofire or SnapKit on iOS/mac/etc is the name which is to the point, punchy and easy to remember.

Should you go for `swift-http-client-nio` or similar, soon this will become a part of suite of products that have extremely similar name and will be almost indistinguishable from each other. So although a "cute" name is not as descriptive, you will be still able to ude the short perex for the repo and tags on github for it which will suffice as a helper to make the library visible before it becomes more popular.

So to end this with something that I believe could possible work, check the name `HyperTTP` which, if you search on github has 0 results [https://github.com/search?q=hyperttp](https://github.com/search?q=hyperttp)

Either way, give a tag soon pretty, pretty please :)

---

<div class="post-metadata">

**Author:** ![Mordil](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mordil/32/5840_2.png) [@Mordil](https://forums.swift.org/u/Mordil)\
**Post date:** [June 25, 2019, 4:23pm UTC](https://forums.swift.org/t/feedback-nio-based-http-client/26149/9 "2019-06-25T16:23:46Z")

</div>

> [@johannesweiss](#):
>
> First of all, there is [another](https://github.com/emarashliev/swift-nio-http-client) package using the exact same (project & module) name which is kind of a no-go.

Given that the first commit was only 21 days ago, I'd say the "first past the post" is this package we're reviewing.

> [@IanPartridge](#):
>
> propose we go with `swift-http-client-nio` . In other words:
> 
> - `swift` - common prefix on everything, makes it clear to people driving by on GitHub that this is a Swift package
> - `http-client` - obvious, that's what it is. Enforce uniqueness of this for SSWG packages.
> - `nio` - common suffix for NIO-based packages going through SSWG. Avoids collisions with non NIO-based HTTP clients and helps with the marketing of NIO as the go-to foundation for server-side Swift.

It's interesting how we read it differently. I see `swift-redis-nio-client` as `swift`, `redis`, `nio client`.

To your particular suggestion, I think `swift` can be optional, especially if the project is listed under `swift-server` in GitHub.

I personally find specific names of modules to be more helpful when reading code that imports it, as cute names always force me to retain more words so I can recognize them in other uses, and the first time I encounter it - I have to stop and go look up what the package does (or spend time trying to infer what it does from usage, but I still might not have enough context to know what types and code is from the module).

For example, I had no idea that the AWS SDK for Python was `Boto3`.

However, I'm not going to ever say that's a hard requirement for me. `CryptoKit` and `MongoKitten` are "cute" names that also provide some context within their name - "crypto" and "mongo".

However, while working though and thinking about this I thought of `RESPClient` for `RedisNIO`, and it looks like it's available from [Johannes' GitHub search](https://github.com/search?l=&q=RESPClient+filename%3APackage.swift+language%3ASwift&type=Code) for Swift, and fits a precedence for other ecosystems such as Java and C#...

---

<div class="post-metadata">

**Author:** ![artemredkin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/artemredkin/32/7066_2.png) [@artemredkin](https://forums.swift.org/u/artemredkin)\
**Post date:** [June 25, 2019, 4:37pm UTC](https://forums.swift.org/t/feedback-nio-based-http-client/26149/10 "2019-06-25T16:37:01Z")

</div>

what about dropping NIO from the name altogether? Just `HTTPClient` (`swift-http-client`)? Is it really that important to advertise what technology we use underneath? As a second choice I think `AsyncHTTPClient` (`async-http-client)` is also not bad, but HTTPClientNIO is just strange imho...

---

<div class="post-metadata">

**Author:** ![artemredkin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/artemredkin/32/7066_2.png) [@artemredkin](https://forums.swift.org/u/artemredkin)\
**Post date:** [June 25, 2019, 4:41pm UTC](https://forums.swift.org/t/feedback-nio-based-http-client/26149/11 "2019-06-25T16:41:46Z")

</div>

Thank you for using it and kind words :) Users are as important as developers, so your opinion definitely matters!

I personally don't like "brand" names that much, I much prefer something descriptive, at least for core libraries (like logging, http, database layers), that minimises the amount of names I have to remember. It also kind of a pattern that we have with "server-oriented" libraries, I think.

---

<div class="post-metadata">

**Author:** ![johannesweiss](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/johannesweiss/32/38183_2.png) [@johannesweiss](https://forums.swift.org/u/johannesweiss)\
**Post date:** [June 25, 2019, 4:44pm UTC](https://forums.swift.org/t/feedback-nio-based-http-client/26149/12 "2019-06-25T16:44:30Z")

</div>

> [@Mordil](#):
>
> > First of all, there is [another](https://github.com/emarashliev/swift-nio-http-client) package using the exact same (project & module) name which is kind of a no-go.
> 
> Given that the first commit was only 21 days ago, I'd say the "first past the post" is this package we're reviewing.

Well, prior to the one listed, there was [this one](https://github.com/vkill/swift-nio-http-client), again with the same name. The point is that the name `swift-nio-http-client` just seems to invite clashes...  
We can't make anyone (who isn't proposing theirs to the SSWG) else to rename their package so I think we should remain clear of existing packages.

> [@Mordil](#):
>
> However, while working though and thinking about this I thought of `RESPClient` for `RedisNIO` , and it looks like it's available from [Johannes' GitHub search](https://github.com/search?l=&q=RESPClient+filename%3APackage.swift+language%3ASwift&type=Code) for Swift, and fits a precedence for other ecosystems such as Java and C#...

I think those are perfectly good names.

> [@artemredkin](#):
>
> Just `HTTPClient` ( `swift-http-client` )?

`HTTPClient` is [_very_ taken](https://github.com/search?l=Swift&q=HTTPClient+filename%3APackage.swift+language%3ASwift&type=Code) already ~~, miraculously, `swift-http-client` seems free but I think that's another candidate where we will just get clashes.~~ and so it [swift-http-client](https://github.com/gmosx/swift-http-client).

> [@artemredkin](#):
>
> As a second choice I think `AsyncHTTPClient` ( `async-http-client)` is also not bad, but HTTPClientNIO is just strange imho...

`AsyncHTTPClient` seems [free on github](https://github.com/search?l=Swift&q=AsyncHTTPClient+filename%3APackage.swift+language%3ASwift&type=Code).

> [@rafiki270](#):
>
> So to end this with something that I believe could possible work, check the name `HyperTTP` which, if you search on github has 0 results [https://github.com/search?q=hyperttp](https://github.com/search?q=hyperttp)

I like `HyperTTP` 🙂. Pretty descriptive and clashes unlikely.

---

<div class="post-metadata">

**Author:** ![Mordil](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mordil/32/5840_2.png) [@Mordil](https://forums.swift.org/u/Mordil)\
**Post date:** [June 25, 2019, 4:53pm UTC](https://forums.swift.org/t/feedback-nio-based-http-client/26149/13 "2019-06-25T16:53:51Z")

</div>

> [@artemredkin](#):
>
> I personally don't like "brand" names that much, I much prefer something descriptive, at least for core libraries (like logging, http, database layers), that minimises the amount of names I have to remember. It also kind of a pattern that we have with "server-oriented" libraries, I think.

You and I are 100% on the same page.

---

<div class="post-metadata">

**Author:** ![Mordil](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mordil/32/5840_2.png) [@Mordil](https://forums.swift.org/u/Mordil)\
**Post date:** [June 25, 2019, 4:55pm UTC](https://forums.swift.org/t/feedback-nio-based-http-client/26149/14 "2019-06-25T16:55:19Z")

</div>

> [@johannesweiss](#):
>
> I like `HyperTTP` 🙂. Pretty descriptive and clashes unlikely.

Honestly, I'm not entirely opposed to `HyperTTP` as it's "cute" in that it only expands the first part of the acronym, but is still descriptive of the package. (I originally supported just claiming `HTTP`)

---

<div class="post-metadata">

**Author:** ![artemredkin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/artemredkin/32/7066_2.png) [@artemredkin](https://forums.swift.org/u/artemredkin)\
**Post date:** [June 25, 2019, 5:03pm UTC](https://forums.swift.org/t/feedback-nio-based-http-client/26149/15 "2019-06-25T17:03:26Z")

</div>

Buut, since other nio-based projects went with SomethingNIO, we should go for `HTTPClientNIO`...

---

<div class="post-metadata">

**Author:** ![Mordil](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mordil/32/5840_2.png) [@Mordil](https://forums.swift.org/u/Mordil)\
**Post date:** [June 25, 2019, 5:07pm UTC](https://forums.swift.org/t/feedback-nio-based-http-client/26149/16 "2019-06-25T17:07:45Z")

</div>

> [@artemredkin](#):
>
> Buut, since other nio-based projects went with SomethingNIO, we should go for `HTTPClientNIO` ...

I'm open/warm to the idea of switching to `RESPClient` for `RedisNIO`. Until Tanner speaks up about `postgres-nio` he's the only "holdout".

I think we just fundamentally need to answer the question:

Do we feel like we need to have consistency in naming for these foundational packages?

---

<div class="post-metadata">

**Author:** ![johannesweiss](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/johannesweiss/32/38183_2.png) [@johannesweiss](https://forums.swift.org/u/johannesweiss)\
**Post date:** [June 25, 2019, 5:10pm UTC](https://forums.swift.org/t/feedback-nio-based-http-client/26149/17 "2019-06-25T17:10:57Z")

</div>

> [@artemredkin](#):
>
> Buut, since other nio-based projects went with SomethingNIO, we should go for `HTTPClientNIO` ...

> [@Mordil](#):
>
> I'm open/warm to the idea of switching to `RESPClient` for `RedisNIO` . Until Tanner speaks up about `postgres-nio` he's the only "holdout".

But is it really that important that all share the same naming scheme? I think with `PostgresNIO`, `RedisNIO`, and `HyperTTP` (for example) we have three names that are all pretty descriptive.

The other issue with naming everything `SomethingNIO` is what if in a few months time there's a better package to do `Something`. They would then be the only odd one out. So why not just name packages somewhat more creatively to start with?

---

<div class="post-metadata">

**Author:** ![artemredkin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/artemredkin/32/7066_2.png) [@artemredkin](https://forums.swift.org/u/artemredkin)\
**Post date:** [June 25, 2019, 5:11pm UTC](https://forums.swift.org/t/feedback-nio-based-http-client/26149/18 "2019-06-25T17:11:58Z")

</div>

This is a great idea, but I think there are two issues:

- how will it work with configuration timeouts? Configuration timeouts are super useful and I think we should keep them, but then question is - do we add deadlines to `execute` or replace timeout?
- what I'm not yet sure how to implement: how to set connection timeout using deadline? Ie what to do if we timeout before we have a `Channel`?

---

<div class="post-metadata">

**Author:** ![johannesweiss](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/johannesweiss/32/38183_2.png) [@johannesweiss](https://forums.swift.org/u/johannesweiss)\
**Post date:** [June 25, 2019, 5:16pm UTC](https://forums.swift.org/t/feedback-nio-based-http-client/26149/19 "2019-06-25T17:16:44Z")

</div>

> [@artemredkin](#):
>
> This is a great idea, but I think there are two issues:
> 
> - how will it work with configuration timeouts? Configuration timeouts are super useful and I think we should keep them, but then question is - do we add deadlines to `execute` or replace timeout?

You could offer both like NIO does (we have `schedule(in:)` for 'timeouts' and [`schedule(deadline:)`](https://apple.github.io/swift-nio/docs/current/NIO/Protocols/EventLoop.html#/s:3NIO9EventLoopP12scheduleTask8deadline_AA9ScheduledVyqd __GAA11NIODeadlineV_qd__ yKctlF) for deadlines).

> [@artemredkin](#):
>
> - what I'm not yet sure how to implement: how to set connection timeout using deadline? Ie what to do if we timeout before we have a `Channel` ?

Not sure I 100% understand but it could be `client.get("https://foo.bar", deadline: .now() + 5)`. Or maybe you were thinking about configuring a 'default connection timeout'? In that case, yes, you'd need something like `client.defaultConnectionTimeout = .seconds(5)`.

> [@artemredkin](#):
>
> Ie what to do if we timeout before we have a `Channel` ?

Mind expanding on what makes timeouts easier to work with for this compared to deadlines? I'd think deadlines are easier there because they would say 'the whole operation including everything that's necessary must be completed by 5 seconds from now.'

---

<div class="post-metadata">

**Author:** ![artemredkin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/artemredkin/32/7066_2.png) [@artemredkin](https://forums.swift.org/u/artemredkin)\
**Post date:** [June 25, 2019, 5:18pm UTC](https://forums.swift.org/t/feedback-nio-based-http-client/26149/20 "2019-06-25T17:18:57Z")

</div>

I'm talking about `bootstrap.connectionTimeout`, how to set it using a deadline?

[Next page](https://forums.swift.org/t/feedback-nio-based-http-client/26149.md?page=2)
