Skip to content

Commit

Permalink
improved docs for http client
Browse files Browse the repository at this point in the history
  • Loading branch information
purplefox committed Jul 24, 2012
1 parent 009d17c commit 47c3f4b
Show file tree
Hide file tree
Showing 10 changed files with 317 additions and 217 deletions.
54 changes: 29 additions & 25 deletions core_manual_groovy.html
Expand Up @@ -1041,17 +1041,19 @@ <h4 id="request-method">Request Method</h4><br/>
<p>The request object has a property <code>method</code> which is a string representing what HTTP method was requested. Possible values for <code>method</code> are: <code>GET</code>, <code>PUT</code>, <code>POST</code>, <code>DELETE</code>, <code>HEAD</code>, <code>OPTIONS</code>, <code>CONNECT</code>, <code>TRACE</code>, <code>PATCH</code>.</p>
<h4 id="request-uri">Request URI</h4><br/>
<p>The request object has a property <code>uri</code> which contains the full URI (Uniform Resource Locator) of the request. For example, if the request URI was:</p>
<pre class="prettyprint">http://localhost:8080/a/b/c/page.html?param1=abc&amp;param2=xyz
<pre class="prettyprint">/a/b/c/page.html?param1=abc&amp;param2=xyz
</pre>
<p>Then <code>request.uri</code> would contain the string <code>http://localhost:8080/a/b/c/page.html?param1=abc&amp;param2=xyz</code>.</p>
<p>Then <code>request.uri</code> would contain the string <code>/a/b/c/page.html?param1=abc&amp;param2=xyz</code>.</p>
<p>Request URIs can be relative or absolute (with a domain) depending on what the client sent. In many cases they will be relative.</p>
<p>The request uri contains the value as defined in <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html">Section 5.1.2 of the HTTP specification - Request-URI</a></p>
<h4 id="request-path">Request Path</h4><br/>
<p>The request object has a property <code>path</code> which contains the path of the request. For example, if the request URI was:</p>
<pre class="prettyprint">http://localhost:8080/a/b/c/page.html?param1=abc&amp;param2=xyz
<pre class="prettyprint">/a/b/c/page.html?param1=abc&amp;param2=xyz
</pre>
<p>Then <code>request.path</code> would contain the string <code>/a/b/c/page.html</code></p>
<h4 id="request-query">Request Query</h4><br/>
<p>The request object has a property <code>query</code> which contains the query of the request. For example, if the request URI was:</p>
<pre class="prettyprint">http://localhost:8080/a/b/c/page.html?param1=abc&amp;param2=xyz
<pre class="prettyprint">/a/b/c/page.html?param1=abc&amp;param2=xyz
</pre>
<p>Then <code>request.query</code> would contain the string <code>param1=abc&amp;param2=xyz</code></p>
<h4 id="request-headers">Request Headers</h4><br/>
Expand All @@ -1075,7 +1077,7 @@ <h4 id="request-params">Request params</h4><br/>
<p>Similarly to the headers, the map of request parameters are available using the <code>params</code> property on the request
object.</p>
<p>Request parameters are sent on the request URI, after the path. For example if the URI was:</p>
<pre class="prettyprint">http://localhost:8080/page.html?param1=abc&amp;param2=xyz
<pre class="prettyprint">/page.html?param1=abc&amp;param2=xyz
</pre>
<p>Then the params map would contain the following entries:</p>
<pre class="prettyprint">param1: 'abc'
Expand Down Expand Up @@ -1232,7 +1234,7 @@ <h3 id="creating-an-http-client">Creating an HTTP Client</h3><br/>
<pre class="prettyprint">HttpClient client = vertx.createHttpClient(port: 8181, host: "foo.com")
</pre>
<p>A single <code>HttpClient</code> always connects to the same host and port. If you want to connect to different servers, create more instances.</p>
<p>The default value for hostname is <code>localhost</code>, and the default value for port is <code>80</code>.</p>
<p>The default port is <code>80</code> and the default host is <code>localhost</code>. So if you don't explicitly set these values that's what the client will attempt to connect to.</p>
<h3 id="pooling-and-keep-alive">Pooling and Keep Alive</h3><br/>
<p>By default the <code>HttpClient</code> pools HTTP connections. As you make requests a connection is borrowed from the pool and returned when the HTTP response has ended.</p>
<p>If you do not want connections to be pooled you can call <code>setKeepAlive</code> with <code>false</code>:</p>
Expand All @@ -1250,9 +1252,9 @@ <h3 id="closing-the-client">Closing the client</h3><br/>
<h3 id="making-requests">Making Requests</h3><br/>
<p>To make a request using the client you invoke one the methods named after the HTTP method that you want to invoke.</p>
<p>For example, to make a <code>POST</code> request:</p>
<pre class="prettyprint">def client = vertx.createHttpClient()
<pre class="prettyprint">def client = vertx.createHttpClient(host: "foo.com")

def request = client.post("http://localhost:8080/some-path/") { resp -&gt;
def request = client.post("/some-path/") { resp -&gt;
println "Got a response: ${resp.statusCode}"
}

Expand All @@ -1261,21 +1263,23 @@ <h3 id="making-requests">Making Requests</h3><br/>
<p>To make a PUT request use the <code>put</code> method, to make a GET request use the <code>get</code> method, etc.</p>
<p>Legal request methods are: <code>get</code>, <code>put</code>, <code>post</code>, <code>delete</code>, <code>head</code>, <code>options</code>, <code>connect</code>, <code>trace</code> and <code>patch</code>.</p>
<p>The general modus operandi is you invoke the appropriate method passing in the request URI as the first parameter. The second parameter is an event handler which will get called when the corresponding response arrives. The response handler is passed the client response object as an argument.</p>
<p>The value specified in the request URI corresponds to the Request-URI as specified in <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html">Section 5.1.2 of the HTTP specification</a>. In most cases it will be a relative URI.</p>
<p><em>Please note that the domain/port that the client connects to is determined by <code>setPort</code> and <code>setHost</code>, and is not parsed from the uri.</em></p>
<p>The return value from the appropriate request method is an instance of <code>org.vertx.groovy.core.http.HTTPClientRequest</code>. You can use this to add headers to the request, and to write to the request body. The request object implements <code>WriteStream</code>.</p>
<p>Once you have finished with the request you must call the <code>end</code> method.</p>
<p>If you don't know the name of the request method in advance there is a general <code>request</code> method which takes the HTTP method as a parameter:</p>
<pre class="prettyprint">def client = vertx.createHttpClient()
<pre class="prettyprint">def client = vertx.createHttpClient(host: "foo.com")

def request = client.request("POST", "http://localhost:8080/some-path/") { resp -&gt;
def request = client.request("POST", "/some-path/") { resp -&gt;
println "Got a response: ${resp.statusCode}"
}

request.end()
</pre>
<p>There is also a method called <code>getNow</code> which does the same as <code>get</code>, but automatically ends the request. This is useful for simple GETs which don't have a request body:</p>
<pre class="prettyprint">def client = vertx.createHttpClient()
<pre class="prettyprint">def client = vertx.createHttpClient(host: "foo.com")

client.getNow("http://localhost:8080/some-path/") { resp -&gt;
client.getNow("/some-path/") { resp -&gt;
println "Got a response: ${resp.statusCode}"
}
</pre>
Expand Down Expand Up @@ -1317,9 +1321,9 @@ <h4 id="ending-http-requests">Ending HTTP requests</h4><br/>
<p>The method can also be called with a string or Buffer in the same way <code>write</code> is called. In this case it's just the same as calling write with a string or Buffer followed by calling <code>end</code> with no arguments.</p>
<h4 id="writing-request-headers">Writing Request Headers</h4><br/>
<p>To write headers to the request, add them to <code>headers</code> property:</p>
<pre class="prettyprint">def client = vertx.createHttpClient()
<pre class="prettyprint">def client = vertx.createHttpClient(host: "foo.com")

def request = client.post("http://localhost:8080/some-path/") { resp -&gt;
def request = client.post("/some-path/") { resp -&gt;
println "Got a response: ${resp.statusCode}"
}

Expand All @@ -1330,7 +1334,7 @@ <h4 id="writing-request-headers">Writing Request Headers</h4><br/>
<pre class="prettyprint">request.putHeader("Some-Header", "Some-Value").putHeader("Some-Other", "Blah")
</pre>
<p>These can all be chained together as per the common vert.x API pattern:</p>
<pre class="prettyprint">client.post("http://localhost:8080/some-path/") { resp -&gt;
<pre class="prettyprint">vertx.createHttpClient(host: "foo.com").post("/some-path/") { resp -&gt;
println "Got a response: ${resp.statusCode}"
}.putHeader("Some-Header", "Some-Value").end()
</pre>
Expand All @@ -1344,9 +1348,9 @@ <h3 id="http-client-responses">HTTP Client Responses</h3><br/>
<p>Client responses are received as an argument to the response handler that is passed into one of the request methods on the HTTP client.</p>
<p>The response object implements <code>ReadStream</code>, so it can be pumped to a <code>WriteStream</code> like any other <code>ReadStream</code>.</p>
<p>To query the status code of the response use the <code>statusCode</code> property. The <code>statusMessage</code> property contains the status message. For example:</p>
<pre class="prettyprint">def client = vertx.createHttpClient()
<pre class="prettyprint">def client = vertx.createHttpClient(host: "foo.com")

client.getNow("http://localhost:8080/some-path/") { resp -&gt;
client.getNow("/some-path/") { resp -&gt;
println "server returned status code: ${resp.statusCode}"
println "server returned status message: ${resp.statusMessage}"
}
Expand All @@ -1355,9 +1359,9 @@ <h4 id="reading-data-from-the-response-body">Reading Data from the Response Body
<p>The API for reading a http client response body is very similar to the API for reading a http server request body.</p>
<p>Sometimes an HTTP response contains a body that we want to read. Like an HTTP request, the client response handler is called when all the response headers have arrived, not when the entire response body has arrived.</p>
<p>To receive the response body, you set a <code>dataHandler</code> on the response object which gets called as parts of the HTTP response arrive. Here's an example:</p>
<pre class="prettyprint">def client = vertx.createHttpClient()
<pre class="prettyprint">def client = vertx.createHttpClient(host: "foo.com")

client.getNow("http://localhost:8080/some-path/") { resp -&gt;
client.getNow("/some-path/") { resp -&gt;
resp.dataHandler { buffer -&gt;
println "I received ${buffer.length} bytes"
}
Expand All @@ -1366,9 +1370,9 @@ <h4 id="reading-data-from-the-response-body">Reading Data from the Response Body
<p>The response object implements the <code>ReadStream</code> interface so you can pump the response body to a <code>WriteStream</code>. See the chapter on streams and pump for a detailed explanation.</p>
<p>The <code>dataHandler</code> can be called multiple times for a single HTTP response.</p>
<p>As with a server request, if you wanted to read the entire response body before doing something with it you could do something like the following:</p>
<pre class="prettyprint">def client = vertx.createHttpClient()
<pre class="prettyprint">def client = vertx.createHttpClient(host: "foo.com")

client.getNow("http://localhost:8080/some-path/") { resp -&gt;
client.getNow("/some-path/") { resp -&gt;
def body = new Buffer()
resp.dataHandler { buffer -&gt;
body &lt;&lt; buffer
Expand All @@ -1382,9 +1386,9 @@ <h4 id="reading-data-from-the-response-body">Reading Data from the Response Body
<p>The body handler is called only once when the <em>entire</em> response body has been read.</p>
<p><em>Beware of doing this with very large responses since the entire response body will be stored in memory.</em></p>
<p>Here's an example using <code>bodyHandler</code>:</p>
<pre class="prettyprint">def client = vertx.createHttpClient()
<pre class="prettyprint">def client = vertx.createHttpClient(host: "foo.com")

client.getNow("http://localhost:8080/some-path/") { resp -&gt;
client.getNow("/some-path/") { resp -&gt;
resp.bodyHandler { body -&gt;
println "The total body received was ${body.length} bytes"
}
Expand All @@ -1399,9 +1403,9 @@ <h3 id="100-continue-handling">100-Continue Handling</h3><br/>
<p>Vert.x allows you to set a <code>continueHandler</code> on the client request object. This will be called if the server sends back a <code>Status: 100 (Continue)</code> response to signify it is ok to send the rest of the request.</p>
<p>This is used in conjunction with the <code>sendHead</code> method to send the head of the request.</p>
<p>An example will illustrate this:</p>
<pre class="prettyprint">def client = vertx.createHttpClient()
<pre class="prettyprint">def client = vertx.createHttpClient(host: "foo.com")

def request = client.put("http://localhost:8080/some-path/") { resp -&gt;
def request = client.put("/some-path/") { resp -&gt;
println "Got a response ${resp.statusCode}"
}

Expand Down

0 comments on commit 47c3f4b

Please sign in to comment.