- Send a GET request containing the following user inputs to Zillow's Mortgage Affordability API. Inputs as follows:
- Annual Income, Monthly Payment, Down, Monthly Debts, Rate, Schedule, Term, Debt to Income, Income Tax, Property Tax, Hazard, PMI, HOA, ZIP
- A successful response from the GET request will contain the following attributes/information:
- Affordability Amount, Monthly Principle and Interest, Monthly Property Tax, Monthly Hazard Insurance, Monthly PMI, Monthly HOA Dues, Total Monthly Payment, Total Payments, Total Interest Payments, Total Principal, Total Taxes Fees and Insurance, Monthly Income, Monthly Debts, Monthly Income Tax, Monthly Remaining Budget
- Figaro is a useful gem making is possible to easily set environment variables and more importantly it allows you to keep private tokens/api keys from being tracked by GIT.
- Include the gem Figaro in your
Gemfileand runbundlein the terminal. - Once the gem is bundled, in the terminal run
figaro install. This will create anapplication.ymlfile in your config directory - as well as create a.gitignorefile.
- Include the gem Figaro in your
- To set personal API key as an environment variable:
-
In
config/application/ymlset:zillow_api_key: "YOUR API KEY" test: zillow_api_key: ~
-
You can call the zillow_api_key with
ENV['zillow_api_key']. Put this where you would normally put the API key.
-
- Install gem RestClient to handle HTTP requests to the Zillow Server.
- Create a database-less model called
Calculatorwhich will contain the API method. I have searched through StackOverflow and come to the conclusion that there are a wide range of opinions as to whether or not to include the API call in a model or a library. In the end, I decided to go with a model since in this instance the web application is very small and I wasn't worried about code bloat.- Require the RestClient gem at the head of the model with
require 'rest-client'. This will give us access to RestClient methods. - Below is a working API call. I have tested this call in the terminal using
Calculator.mortage_affordability({ :annualincome => '100000', :monthlypayment => '1000', :down => '10000', :monthlydebts => '2000' })and the response from the zillow server is a success.def self.mortage_affordability(options = {}) options[:estimate] = 'false' options[:output] = 'json' base_uri = "http://www.zillow.com/webservice/mortgage/CalculateAffordability.htm?" api_key = 'zws-id=' + ENV['zillow_api_key'] + '&' unless options[:annualincome].present? || options[:monthlypayment].present? raise ArgumentError, 'Is required: either Annual Income or Monthly Payment!' end unless options[:down].present? raise ArgumentError, 'The Amount Down is required' end unless options[:monthlydebts].present? raise ArgumentError, 'The Monthly Debts option is required' end response = RestClient.get base_uri + api_key + options.map { |k, v| "#{k}=#{v}" }.join('&') response_hash = JSON.parse(response) end
- In the method above I have done the following:
- I have an options hash:
options = {}. I'm expecting up to 14 to be included in the API call. - I have set
options[:estimate]andoptions[:output]directly in the method. At this time I do not want to give the user the option of whether or not they want an estimate. Additionally, I want the request to return JSON which is why I specified it here. - I declared a variable called
base_uri. This makes it easier further down the method to concatenate the full URL for the request. - I declared a varibale called
api_keywhich concatenates together my api token/key with Zillow's unique naming structure. - I have declared 3
unlessstatements which check whether or not the user has input the minimum requirments/values as specified by the Zillow API guide. - I declare and send a
RestClient.getrequest which concatenates thebase-uri,api_key, and all the hash options. This has been assigned to theresponsevariable. - Lastly, I parse the
responseand assign it toresponse_hashso that later the attributes can be accessed viaresponse_hash['response']['monthlyIncomeTax']
- Within
config/routes.rbdefine the index route and set it to the root page. This will make the index view the homepage/default:get 'calculator/index' root to: 'calculator#index'
- Create a controller called
Calculatorwithindexandget_ratesactions. Theindexaction is only needed to display the index view. Theget_ratesaction will act as the middle man in passing the form attributes to themortgage_affordabilitymethod.-
Pseudo code:
get_rates assign the form parameters to a variable call Calculator.mortgage_affordability passign in the paramters listen for a response if response is a success save response to a variable if response fails render error to view respond to format html and js end
-
- Create an
index.html.erbview. - Create a form partial for
_get_rates.html.erband display the partial in the index view using<%= render partial: 'get_rates' %>. - Within the form partial, create a form using
form_for. This form will have a handful oftext_fieldswhich will be optional inputs for the user. The possible inputs are detailed in the functionality section.-
The form code will look like this:
<%= form_for :get_rates do |f| %> <%= f.text_field :annualincome %> <%= f.text_field :monthlypayment %> <%= f.text_field :down %> <%= f.text_field :monthlydebts %> # ... there ~ 14 options/attributes <%= f.submit %> <% end %>
-
- Create another view called
get_rates.js.erb. This is where we will use jQuery to append the API response toget_rates.html.erb.-
Pseudo code:
if the get_rates call was a success append the response to html element within get_rates view else render error end
-
- Require the RestClient gem at the head of the model with