Search code examples
ruby-on-railsapiruby-on-rails-4activeresource

Using ActiveResource::Base to send get requests to API


I am pretty new to Rails so please bear with me.

We are building a Rails 4 app for the Dutch market. During registration processes, it's pretty common to ask the user to fill in their postcode and the address is automatically generated. This works because in NL every door has a unique postcode which consists of 4 numbers and 2 letters(6828WQ).

There is an API for that located at postcodeapi.nu. The api works pretty simple. In order for me to receive the address, I need to send a get request to http://api.postcodeapi.nu/5041EB which would return me the address corresponding to 5041EB postcode. I will make the address dynamic in the future but let's take this link as an example.

This is all clear, but now I don't know how I can send the request and cache the response using ActiveResource. Here is how my model looks:

class Postcode < ActiveResource::Base
    self.site = "http://api.postcodeapi.nu/5041EB"
    headers['Api-Key'] = "495237e793d10330c1db0d57db9d3c7e6e485af7"
end

I did some tests from the console, however I am not really sure how I should approach it. I tried with the simple Postcode.new but that returns an empty response: => #<Postcode:0x00000006b5c178 @attributes={}, @prefix_options={}, @persisted=false>

I have tried everything I know but no success. Maybe ActiveResource is not even the right way for me to fetch the data?


Solution

  • Since the API does not return the JSON that ActiveResources expects, you would have to implement a new parser.

    class Postcode < ActiveResource::Base
      self.site = "http://api.postcodeapi.nu/"
      headers['Api-Key'] = "495237e793d10330c1db0d57db9d3c7e6e485af7"
      self.element_name = ''
      self.include_format_in_path = false
    
      class PostcodeParser < ActiveResource::Collection
        def initialize(elements = {})
          @elements = [elements['resource']]
        end
      end
    
      self._collection_parser = PostcodeParser
    end
    

    This should work for the following query Postcode.find('5041EB'), but not for Postcode.where(id: '5041EB'). The main reason is that the API has a different parameter key for id. The API docs refers to type, but it didn't work.

    I am not sure if ActiveResources is the right approach for this case.