mirror of https://github.com/vapor/docs.git
152 lines
4.4 KiB
Markdown
152 lines
4.4 KiB
Markdown
---
|
|
currentMenu: http-client
|
|
---
|
|
|
|
> Module: `import HTTP`
|
|
|
|
# Client
|
|
|
|
The client provided by `HTTP` is used to make outgoing requests to remote servers. Let's look at a simple outgoing request.
|
|
|
|
## QuickStart
|
|
|
|
Let's jump right in to make a simple HTTP Request. Here's a basic `GET` request using your Vapor `Droplet`.
|
|
|
|
```swift
|
|
let query = ...
|
|
let spotifyResponse = try drop.client.get("https://api.spotify.com/v1/search?type=artist&q=\(query)")
|
|
print(spotifyR)
|
|
```
|
|
|
|
### Clean Up
|
|
|
|
The url above can be a little tricky to read, so let's use the query parameter to clean it up a little bit:
|
|
|
|
```swift
|
|
try drop.client.get("https://api.spotify.com/v1/search", query: ["type": "artist", "q": query])
|
|
```
|
|
|
|
### Continued
|
|
|
|
In addition to `GET` requests, Vapor's client provides support for most common HTTP functions. `GET`, `POST`, `PUT`, `PATCH`, `DELETE`
|
|
|
|
```swift
|
|
let bytes = myJSON.makeBytes()
|
|
try drop.client.post("http://some-endpoint/json", headers: ["Auth": "Token my-auth-token"], body: .data(jsonBytes))
|
|
```
|
|
|
|
### Full Request
|
|
|
|
To access additional functionality or custom methods, use the underlying `request` function directly.
|
|
|
|
```swift
|
|
public static func get(_ method: Method,
|
|
_ uri: String,
|
|
headers: [HeaderKey: String] = [:],
|
|
query: [String: CustomStringConvertible] = [:],
|
|
body: Body = []) throws -> Response
|
|
```
|
|
|
|
For example:
|
|
|
|
```swift
|
|
try drop.client.request(.other(method: "CUSTOM"), "http://some-domain", headers: ["My": "Header"], query: ["key": "value"], body: [])
|
|
```
|
|
|
|
## Config
|
|
|
|
The `Config/clients.json` file can be used to modify the client's settings.
|
|
|
|
### TLS
|
|
|
|
Host and certificate verification can be disabled.
|
|
|
|
> Note: Use extreme caution when modifying these settings.
|
|
|
|
```json
|
|
{
|
|
"tls": {
|
|
"verifyHost": false,
|
|
"verifyCertificates": false
|
|
}
|
|
}
|
|
```
|
|
|
|
### Mozilla
|
|
|
|
The Mozilla certificates are included by default to make fetching content from secure sites easy.
|
|
|
|
```json
|
|
{
|
|
"tls": {
|
|
"certificates": "mozilla"
|
|
}
|
|
}
|
|
```
|
|
|
|
## Advanced
|
|
|
|
In addition to our Droplet, we can also use and interact with the `Client` manually. Here's how our default implementation in Vapor looks:
|
|
|
|
```swift
|
|
let response = try Client<TCPClientStream>.get("http://some-endpoint/mine")
|
|
```
|
|
|
|
The first thing we likely noticed is `TCPClientStream` being used as a Generic value. This will be the underlying connection that the `HTTP.Client` can use when performing the request. By conforming to the underlying `ClientStream`, an `HTTP.Client` can accept custom stream implementations seamlessly.
|
|
|
|
## Save Connection
|
|
|
|
Up to this point, we've been interacting with the Client via `class` or `static` level functions. This allows us to end the connection upon a completed request and is the recommended interaction for most use cases. For some advanced situations, we may want to reuse a connection. For these, we can initialize our client and perform multiple requests like this.
|
|
|
|
```swift
|
|
let pokemonClient = try drop?.client.make(scheme: "http", host: "pokeapi.co")
|
|
for i in 0...1 {
|
|
let response = try pokemonClient?.get(path: "/api/v2/pokemon/", query: ["limit": 20, "offset": i])
|
|
print("response: \(response)")
|
|
}
|
|
```
|
|
|
|
## ClientProtocol
|
|
|
|
Up to this point, we've focused on the built in `HTTP.Client`, but users can also include their own customized clients by conforming to `HTTP.ClientProtocol`. Let's look at the implementation:
|
|
|
|
```swift
|
|
public protocol Responder {
|
|
func respond(to request: Request) throws -> Response
|
|
}
|
|
|
|
public protocol Program {
|
|
var host: String { get }
|
|
var port: Int { get }
|
|
var securityLayer: SecurityLayer { get }
|
|
// default implemented
|
|
init(host: String, port: Int, securityLayer: SecurityLayer) throws
|
|
}
|
|
|
|
public protocol ClientProtocol: Program, Responder {
|
|
var scheme: String { get }
|
|
var stream: Stream { get }
|
|
init(scheme: String, host: String, port: Int, securityLayer: SecurityLayer) throws
|
|
}
|
|
```
|
|
|
|
By conforming to these underlying functions, we immediately gain access to the public `ClientProtocol` apis we viewed above.
|
|
|
|
## Customize Droplet
|
|
|
|
If we've introduced a custom conformance to `HTTP.ClientProtocol`, we can pass this into our droplet without changing the underlying behavior in our application.
|
|
|
|
For example:
|
|
|
|
```swift
|
|
let drop = Droplet()
|
|
|
|
drop.client = MyCustomClient.self
|
|
```
|
|
|
|
Going forward, all of your calls to `drop.client` will use `MyCustomClient.self`:
|
|
|
|
```swift
|
|
drop.client.get(... // uses `MyCustomClient`
|
|
```
|