Net::HTTP is a Ruby library we can turn to in order to send and receive HTTP requests and responses. To begin with, let's take a look at the API documentation.
Net::HTTP provides a rich library which can be used to build HTTP user-agents.
Net::HTTP is designed to work closely with URI. URI::HTTP#host, URI::HTTP#port and URI::HTTP#request_uri are designed to work with Net::HTTP.
For our purposes, a user agent means a client application or service that runs on our behalf. We can use Net::HTTP in order to communicate with a web API if by some tragedy a wrapper is not available.
To begin with, we should take note of the fact that Net::HTTP is designed to work with the URI module. In a nutshell, the URI module provides us with a simple way of parsing a URI string.
For example, when fed a URI / URL string, an URI object will expose a number of methods which can, among others, return the host, port, domain and relative path.
Communicating with a Web API
For a practical application of Net::HTTP, we will be interacting with the Saplo API. When browsing the documentation on their page, 3 things become apparent :
The API uses the RPC model. This basically means that we will be communicating exclusively with POST requests which will contain a method call embedded in the body.
There is no Ruby API wrapper or interface
The company is based in Sweden. Not that there's anything wrong with that :)
Our goal will be to get an authentication token from the API using the "auth.accesstoken" method. Let's begin by gathering the necessary libraries.
<![CDATA[// <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]><![CDATA[><![CDATA[> // ]]]]><![CDATA[>]]>
Note that we have also included 'net/https'. The Saplo API makes use of both HTTP and HTTPS, and we will need the latter for the authentication process.
<![CDATA[// <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]><![CDATA[><![CDATA[> // ]]]]><![CDATA[>]]>
Line 4 : Here we have created our URI object
Line 5 : Set the port variable to the HTTPS standard of 443.
Line 6 : We have also created an instance of Net::HTTP - note that only the host and port are required at this stage.
Lines 7 through 10 : These are optional parameters that need to be set for HTTPS requests.
Line 11 : Instantiates a new Post request object, with a header indicating the content type, which in this case is JSON.
Now that our connection parameters are set, we can move ahead by formatting the body and send the request.
<![CDATA[// <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // <![CDATA[ // ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]]]><![CDATA[><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]]]><![CDATA[><![CDATA[><![CDATA[> // ]]]]]]><![CDATA[><![CDATA[> // ]]]]><![CDATA[>]]>
Line 2 : This is the call to the set_connection_parameters method which we looked at above
Line 3 : Here we set the request body. Note that the entire hash is converted to json. The instance variables @api_key and @secret_key refer to API keys which are declared elsewhere.
Line 4 : We are initiating the request using the "request" method of our Net::HTTP object
Line 5 : The response is parsed in order to retrieve the returned access token
Note that the response is returned as a string, which is subsequently parsed using the JSON module.
Et voilà, we have our authentication token in 8 "simple" steps!
There are shortcut methods available from Net::HTTP, and thankfully most common APIs already have well documented Ruby wrappers. However, I hope the above will be useful should you ever find yourself in the position to have to craft HTTP responses manually.
Net::HTTPSession Class Documentation