1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
# Getting Started
This guide explains how to get started with `Async::HTTP`.
## Installation
Add the gem to your project:
~~~ bash
$ bundle add async-http
~~~
## Core Concepts
- {ruby Async::HTTP::Client} is the main class for making HTTP requests.
- {ruby Async::HTTP::Internet} provides a simple interface for making requests to any server "on the internet".
- {ruby Async::HTTP::Server} is the main class for handling HTTP requests.
- {ruby Async::HTTP::Endpoint} can parse HTTP URLs in order to create a client or server.
- [`protocol-http`](https://github.com/socketry/protocol-http) provides the abstract HTTP protocol interfaces.
## Usage
### Making a Request
To make a request, use {ruby Async::HTTP::Internet} and call the appropriate method:
~~~ ruby
require 'async/http/internet/instance'
Sync do
Async::HTTP::Internet.get("https://httpbin.org/get") do |response|
puts response.read
end
end
~~~
The following methods are supported:
~~~ ruby
Async::HTTP::Internet.methods(false)
# => [:patch, :options, :connect, :post, :get, :delete, :head, :trace, :put]
~~~
Using a block will automatically close the response when the block completes. If you want to keep the response open, you can manage it manually:
~~~ ruby
require 'async/http/internet/instance'
Sync do
response = Async::HTTP::Internet.get("https://httpbin.org/get")
puts response.read
ensure
response&.close
end
~~~
As responses are streamed, you must ensure it is closed when you are finished with it.
#### Persistence
By default, {ruby Async::HTTP::Internet} will create a {ruby Async::HTTP::Client} for each remote host you communicate with, and will keep those connections open for as long as possible. This is useful for reducing the latency of subsequent requests to the same host. When you exit the event loop, the connections will be closed automatically.
### Downloading a File
~~~ ruby
require 'async/http/internet/instance'
Sync do
# Issue a GET request to Google:
response = Async::HTTP::Internet.get("https://www.google.com/search?q=kittens")
# Save the response body to a local file:
response.save("/tmp/search.html")
ensure
response&.close
end
~~~
### Posting Data
To post data, use the `post` method:
~~~ ruby
require 'async/http/internet/instance'
data = {'life' => 42}
Sync do
# Prepare the request:
headers = [['accept', 'application/json']]
body = JSON.dump(data)
# Issues a POST request:
response = Async::HTTP::Internet.post("https://httpbin.org/anything", headers, body)
# Save the response body to a local file:
pp JSON.parse(response.read)
ensure
response&.close
end
~~~
For more complex scenarios, including HTTP APIs, consider using [async-rest](https://github.com/socketry/async-rest) instead.
### Timeouts
To set a timeout for a request, use the `Task#with_timeout` method:
~~~ ruby
require 'async/http/internet/instance'
Sync do |task|
# Request will timeout after 2 seconds
task.with_timeout(2) do
response = Async::HTTP::Internet.get "https://httpbin.org/delay/10"
ensure
response&.close
end
rescue Async::TimeoutError
puts "The request timed out"
end
~~~
### Making a Server
To create a server, use an instance of {ruby Async::HTTP::Server}:
~~~ ruby
require 'async/http'
endpoint = Async::HTTP::Endpoint.parse('http://localhost:9292')
Sync do |task|
Async(transient: true) do
server = Async::HTTP::Server.for(endpoint) do |request|
::Protocol::HTTP::Response[200, {}, ["Hello World"]]
end
server.run
end
client = Async::HTTP::Client.new(endpoint)
response = client.get("/")
puts response.read
ensure
response&.close
end
~~~
|