Skip to content

Latest commit

 

History

History
101 lines (75 loc) · 3.54 KB

UPGRADING.md

File metadata and controls

101 lines (75 loc) · 3.54 KB

Upgrading to v2.0

v2.0 is a major upgrade over v1.x and is not backward compatible.

The client has been completely rewritten from scratch to provide a more consistent interface and take advantage of Ruby 1.9.3 and Ruby 2.0.

If you are upgrading your code from v1.x, here's the major changes you should be aware of.

  1. The client is now an instance.

    All the API calls are performed within the scope of an instance, rather than a class, making it possible to pass the client around, write thread-safe code and create multiple client instances with different API credentials for a multi-environment application.

    # v1
    DNSimple::Client.username   = 'YOUR_USERNAME'
    DNSimple::Client.password   = 'YOUR_PASSWORD'
    domain = DNSimple::Domain.find("example.com")
    
    # v2
    client = Dnsimple::Client.new(username: 'YOUR_USERNAME', password: 'YOUR_PASSWORD')
    domain = client.domains.domain("example.com")
  2. API call responses are now simple struct-like objects, rather Model-like objects.

    domain = client.domains.domain("example.com")
    # => Dnsimple::Struct::Domain

    A struct-like object is designed to be a simple container of key/value attributes, as opposite to a fully-features instance you can interact with.

  3. API methods are now defined as methods of the client instance.

    This is a consequence (or the cause, depending on the POV) of the previous point. It is no longer possible to call persistence methods on an object returned from the API, as it was in v1.

    record = client.domains.record("example.com", 1)
    # this will fail
    record.name = "www"
    record.update

    Instead, treat the object a simple read-only container. If you need to manipulate a Record, Domain or another instance, write your own object that encapsulate the desired persistence behavior.

    Here's a very simple example.

    class DnsimpleRecord
      def self.find(client, domain, record_id)
        client.record(domain, record_id)
      end
    
      def self.create(client, domain, attributes)
        new(client.create_record(domain, attributes))
      end
    
      def initialize(client, instance)
        @client   = client
        @instance = instance
      end
    
      def update_ip(ip)
        @client.update_record(@instance.domain_id, @instance.record_id, content: ip)
      end
    end

    Although this approach seems more verbose at first glance, it encourages the encapsulation of your application logic inside custom objects, rather than promoting the patching of the core library objects.

    Moreover, we found that in most cases developers need access to a very limited set of operations rather all the possible API methods attached to a resource. And it's likely you already have a model in your application, what you need is just a simple way to interact with the third-party DNSimple application.

    Last but not least, this approach guarantees that if you want to alter the state of an object and you already know its id, you don't need to perform a #find call to instantiate an object to call the update on:

    # version 1
    record = Dnsimple::Record.find("example.com", 12)
    record.name = "updated"
    record.content = "127.0.0.1"
    record.update
    
    # version 2
    record = Dnsimple::Record.find("example.com", 12)
    record.update(name: "updated", content: "127.0.0.1")

    Instead, simply execute

    client.domains.update_record("example.com", 12, name: "updated", content: "127.0.0.1")