DEV Community

Cover image for Minimal Net/HTTP client template
Gerardo Sandoval
Gerardo Sandoval

Posted on

Minimal Net/HTTP client template

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

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
Enter fullscreen mode Exit fullscreen mode
Usage

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

  client = Client.new(*api_credentials*)
  response = client.get_request({ page: 1, limit: 30 })
Enter fullscreen mode Exit fullscreen mode
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.

Top comments (0)