Minimal Net/HTTP client template
Tags: ruby, client, http, api
Published: 2021-01-17 21:35:55

---
title: Minimal Net/HTTP client template
published: true
description: Example of a client API wrapper built with Net::HTTP.
tags: ruby, client, http, api 
cover_image: https://i.iinfo.cz/images/98/http-ruby-1.jpg
---

Have you ever wanted to fetch information from an API and realize that there is no existent library or gem for that specific service?  

If you find yourself in that situation and are planning to build your own client, you may already know that there are plenty of third party HTTP client libraries to use (Faraday, HTTParty, rest-client, etc.)... And yeah, without issues you can use any of those to build your client, but also you can achieve that with minimal effort using `Net::HTTP`.

`Net::HTTP` may not be the first option for most developers, its implementation is not the simplest or the easiest, but it definitely capable of building a robust client without the need of requiring additional code.

Here's an example of a client built with `Net::HTTP`. 

## Net::HTTP Client example

```ruby
require 'net/http'
require 'uri'

class Client
  API_ENDPOINT = "http://api.example.com"

  def initialize(api_key, secret_key)
    # set credentials or token if required
    @api_key = api_key
    @secret_key = secret_key
    @api_uri = URI(API_ENDPOINT)
  end

  def get_request(opts)
    request(
      Net::HTTP::Get.new("/users"),
      opts # additional request options defined by the API I.E. { page: 1, limit: 30 }
    )
  end

  def post_request(opts)
    request(
      Net::HTTP::Post.new(api_uri.merge("/create_user")),
      opts # User options that are required to create the user
    )
  end

  private

  def request(net_request, data = nil)
    # execute and store the request response
    @response = api_client(net_request, data)
    # parse response
    parsed_response = JSON.parse(response.body)
    # return the parsed response, otherwise raise an error
    return parsed_response if response_successful?

    raise CustomError, "#{parsed_response['code']} - #{parsed_response['message']}"
  end
  
  # Receives a valid Net::HTTP request object and data to set as the request body
  def api_client(net_request, data)
    Net::HTTP.start(api_uri.host, use_ssl: use_ssl) do |http|
      # Set headers
      headers.each { |key, value| net_request[key] = value }
      # Set request body from the data argument
      net_request.body = data.to_json if data 
      # Execute the request 
      http.request(net_request)
    end
  end

  def headers
    # define headers here
    {
      'Content-Type' =>  'application/json',
      'Authorization' => #<auth token or keys>,
      ...
    }  
  end

  def response_successful?
    response.code == '200'
  end
end
```

##### Usage

The client usage is very simple, just initialize the client, call the specific request method and pass the required options.

```ruby
  client = Client.new(*api_credentials*)
  response = client.get_request({ page: 1, limit: 30 })
```

#####Adding more request endpoints
You just need to add a new method to the client with the specific `Net::HTTP` request object and pass the parameters required by the API.


That's it!... a simple `Net::HTTP` client template for you to use.