-
Notifications
You must be signed in to change notification settings - Fork 125
Update readme with simple tutorial #2
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,122 @@ | ||
# swift-nio-http-client | ||
This package provides simple HTTP Client library built on top of SwiftNIO. | ||
|
||
Swift HTTP Client library built on top of SwiftNIO | ||
## Getting Started | ||
|
||
Add the following entry in your <code>Package.swift</code> to start using <code>HTTPClient</code>: | ||
|
||
### Swift 5 | ||
|
||
```swift | ||
dependencies: [ | ||
.package(url: "https://github.com/swift-server/swift-nio-http-client.git", from: "1.0.0") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. did we tag yet? if not, maybe be more explicit about that, see swift-log and swift-metrics READMEs There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. replaced with |
||
] | ||
``` | ||
|
||
## Status | ||
|
||
This library provides the following: | ||
1. Async single request methods | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "single request methods" is a bit unclear, rephrase? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed, do you thinks its better now? |
||
2. Simple follow-redirect support (cookie headers are dropped) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed, thanks |
||
3. Body download streaming | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Streaming body download There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed, thanks |
||
4. TLS support | ||
5. Cookie parsing (but not storage) | ||
|
||
## How to use | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Usage guide There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed |
||
|
||
### Request-Response API | ||
The code snippet below illustrates how to make a simple GET request to a remote server: | ||
|
||
```import HTTPClient | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "```swift" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed here and in all other blocks |
||
|
||
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew) | ||
let response = try httpClient.get(url: "https://swift.org").wait() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. personally i dont love guiding users to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good point! re-wrote example |
||
|
||
if response.status == .ok { | ||
// handle the response | ||
} | ||
|
||
// close the client | ||
try? httpClient.syncShutdown() | ||
``` | ||
|
||
It is important to close client instance after use to cleanly shutdown underlying NIO ```EventLoopGroup```. Alternatively, you can provide shared ```EventLoopGroup```: | ||
``` | ||
let httpClient = HTTPClient(eventLoopGroupProvider: .shared(userProvidedGroup)) | ||
``` | ||
In this case shutdown of the client is not neccecary. | ||
|
||
Library provides methods for most HTTP-methods. In case you need to have more control over the method, or you want to add headers or body, use ```HTTPRequest``` struct: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Library provides methods for most HTTP-methods -> Most common HTTP methods are supported out of the box There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done, thanks! |
||
```import HTTPClient | ||
|
||
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew) | ||
defer { | ||
try? httpClient.syncShutdown() | ||
} | ||
|
||
var request = try HTTPRequest(url: "https://swift.org", method: .POST) | ||
request.headers.add(name: "User-Agent", value: "Swift HTTPClient") | ||
request.body = .string("some-body") | ||
|
||
let response = try httpClient.execute(request: request).wait() | ||
|
||
if response.status == .ok { | ||
// handle the response | ||
} | ||
``` | ||
|
||
### Redirect following | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Redirects There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
To enable follow-redirects behaviour, enable in using client configuration: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Enable follow-redirects behavior using the client configuration: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed |
||
``` | ||
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew, | ||
configuration: HTTPClientConfiguration(followRedirects: true)) | ||
``` | ||
|
||
### Timeouts | ||
Timeouts (connect and read) can be set in the client configuration: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Timeouts (connect and read) can also be set using the client configuration: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed |
||
``` | ||
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew, | ||
configuration: HTTPClientConfiguration(timeout: Timeout(connectTimeout: .seconds(1), | ||
readTimeout: .seconds(1)))) | ||
``` | ||
or on per-request basis: | ||
``` | ||
let response = try httpClient.execute(request: request, timeout: Timeout(connectTimeout: .seconds(1), readTimeout: .seconds(1))).wait() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. format to be more readable There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. re-formatted, is it better now? |
||
``` | ||
|
||
### Streaming | ||
In case greater control over body processing is needed or you want to process HTTP Reponse body in a streaming manner, following delegate protocol could be used (example shows how to count bytes in response body without copiying it to the memory): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When dealing with larger amount of data, it's critical to steam the response body instead of aggregating it-memory. Handling a response stream is done using a delegate protocol. The following example demonstrates how to count the number of bytes in a streaming response body: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed, thanks |
||
``` | ||
class CountingDelegate: HTTPResponseDelegate { | ||
typealias Response = Int | ||
|
||
var count = 0 | ||
|
||
func didTransmitRequestBody() { | ||
// this is executed when request is sent, called once | ||
} | ||
|
||
func didReceiveHead(_ head: HTTPResponseHead) { | ||
// this is executed when we receive HTTP Reponse head part of the request (it contains response code and headers), called once | ||
} | ||
|
||
func didReceivePart(_ buffer: ByteBuffer) { | ||
// this is executed when we receive parts of the response body, could be called zero or more times | ||
count += buffer.readableBytes | ||
} | ||
|
||
func didFinishRequest() throws -> Int { | ||
// this is called when request is fully read, called once, this is where you return a result or throw any errors you require to propagate to the client | ||
return count | ||
} | ||
|
||
func didReceiveError(_ error: Error) { | ||
// this is called when we receive any network-related error, called once | ||
} | ||
} | ||
|
||
let request = try HTTPRequest(url: "https://swift.org") | ||
let delegate = CountingDelegate() | ||
|
||
let count = try httpClient.execute(request: request, delegate: delegate).wait() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. drop wait |
||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SwiftNIOHTTPClient