Skip to content

Instantly share code, notes, and snippets.

@heridev
Last active March 20, 2024 21:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save heridev/9caa981f5ba19361640ada99c1ed468c to your computer and use it in GitHub Desktop.
Save heridev/9caa981f5ba19361640ada99c1ed468c to your computer and use it in GitHub Desktop.
How to create your own HTTP API client gem in Ruby

Another great reference on creating Gems

https://buttercms.com/blog/launching-your-own-ruby-gem-build-it/

Experimenting with the process

  1. We need to start by creating the gem
bundle gem smsparatodos_client
  1. Defining dependencies in smsparatodos_client.gemspec and for this one we are going to add httparty gem
spec.add_dependency 'httparty'
  1. Implement the API client and configuration

lib/smsparatodos_client/configuration.rb

module SmsParataTodosClient
  class Configuration
    attr_accessor :auth_client, :auth_token

    def initialize
      @auth_client = ''
      @auth_token = ''
    end
  end
end

lib/smsparatodos_client.rb

require 'httparty'
require_relative 'smsparatodos_client/configuration'

module SmsParaTodosClient
  class << self
    attr_accessor :configuration
  end

  def self.configure
    self.configuration ||= Configuration.new
    yield(configuration)
  end
end

And the actual client

lib/smsparatodos_client/client.rb

module SmsparaTodosClient
  class Client
    include HTTParty
    base_uri 'api.smsparatodos.com/v2'

    def initialize
      @auth_token = SmsParaTodosClient.configuration.auth_token
      @auth_client = SmsParaTodosClient.configuration.auth_client
    end
  
    def send_sms(number:, content:, type: 'standard_delivery', customer_reference_id:, mobile_hub_id:)
      self.class.post('/sms/create', {
        headers: {
          'Content-Type' => 'application/json',
          'Authorization-Token'=> "Bearer #{@auth_token}",
          'Authorization-Client' => @auth_client
        },
        body: {
          sms_number: number,
          sms_content: content,
          sms_type: type,
          sms_customer_reference_id: customer_reference_id,
          mobile_hub_id: mobile_hub_id 
        }.to_json
      })
    end
  end
end

So this way you can specify your data in an initializer like this

config/initializers/smsparatodos_client.rb

SmsParaTodosClient.configure do |config|
  config.auth_token = ENV['SMS_AUTH_TOKEN']
  config.auth_client = ENV['SMS	_AUTH_CLIENT']
end
  1. And then use it everywhere
client = SmsParaTodosClient::Client.new
response = client.send_sms(
  number: "+523121231111",
  content: "smsparatodos.com es increíble",
  customer_reference_id: "123",
  mobile_hub_id: "6d5be464-xxxx-xxxx-xxxx-xxxx7242c70d7"
)

Before we go, let's add some basic tests using Rspec

  1. Let's start by adding the gem to our smsparatodos_client.gemspec
spec.add_development_dependency 'rspec', '~> 3.0'

Run bundle install to install the dependencies 2. Initialize RSpec

Next, initialize RSpec in your gem directory to create the spec helper files:

bundle exec rspec --init
  1. Writing Test Let's create the test under the /spec directory, and if you are testing the Client class, you might create a file named client_spec.rb within the spec/smsparatodos_client directory

Here is the spec

spec/smsparatodos_client/client_spec.rb

require 'spec_helper'
require 'smsparatodos_client'

RSpec.describe SmsParaTodosClient::Client do
  before do
    SmsParaTodosClient.configure do |config|
      config.auth_token = 'test_token'
      config.auth_client = 'test_client'
    end
  end

  describe '#send_sms' do
    let(:client) { described_class.new }
    
    it "sends an SMS and returns a success response" do
      stub_request(:post, "https://api.smsparatodos.com/v2/sms/create")
        .with(
          headers: {
            'Authorization-Token' => 'Bearer test_token',
            'Authorization-Client' => 'test_client',
            'Content-Type' => 'application/json'
          },
          body: {
            sms_number: '+5143434343',
            sms_content: 'test message', 
            sms_type: 'standard_delivery',
            mobile_hub_id: 'test_hub_id'
          }.to_json
        ).to_return(status: 200, body: '', headers: {})

      response = client.send_sms(
        number: "+523121231111",
        content: "Test message",
        customer_reference_id: "123",
        mobile_hub_id: "test_hub_id"
      )
      expect(response.code).to eq 200
    end
  end
end

Then you can run your tests with

bundle exec rspec

That's it, now you know how to create your own HTTP client gem for one of your custom APIs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment