How I Made Etymologizer, Part 1

I recently created a web app called Etymologizer. The site allows a user to enter a word or series of words. It then color-codes the words by language of origin and displays the etymology when the user mouses over a word.

Here’s an example of how it looks when you type in We hold these truths to be self-evident: that all men are created equal, and then mouse over the word self:

Screen Shot 2016-04-28 at 12.53.22 PM

I created the back end of this project with Rails, and the front end with AngularJS. In this post, I’ll describe how the Rails back end works, and why I decided to create it in Rails.

I wanted to create the project entirely in Angular, but the etymology data comes from Merriam-Webster’s Dictionary API. Unfortunately, the Dictionary API outputs its data in XML, and Angular needs the data to be JSON. At first I considered using this Angular-XML module, but then I decided it would just be easier (and more fun) to create my own Rails API that could act as a go-between: it could transform the Dictionary API’s data from XML to JSON, and then my Angular app could access that JSON from my own Rails API.

So I created a new Rails project, and the first thing I did was install the rails-api gem. (I used Rails 4; Rails 5 actually lets you create APIs without any additional gems.) I also installed the HTTParty gem, which I could use to interact with the Dictionary API.

I then created a new adapter that I could use elsewhere:

module Adapters
  class DictionaryApiConnection
    include HTTParty

    attr_reader :connection

    def initialize
      @connection = self.class
    end

    def base_URL
      "http://www.dictionaryapi.com/api/v1/references/collegiate/xml"
    end

    def URL(word)
      "#{self.base_URL}/#{word}?key=#{ENV['API_key']}"
    end

    def query(word)
      result = connection.get(self.URL(word))
    end

  end
end

In the adapter, I include the HTTParty gem, initialize the adapter with a connection instance variable, and then define my query. The query URL includes the Dictionary API’s base URL, the desired word, and my API key (which is defined elsewhere in my app and is hidden from the public using the figaro gem).

Next, I access the adapter from my controller:

class WordsController < ApplicationController

  def index
    client = Adapters::DictionaryApiConnection.new

    words = params["words"].split
    json_object = []

    words.each do |word|
      json_word = Crack::XML.parse(client.query(word))
      json_object.push(json_word)
    end

    render json: json_object

  end

end

Here’s how this works. The controller creates a new instance of the adapter, which includes a new connection. The API takes in params from the input that the user has typed into the front-end Angular app. The words variable takes the “words” params and splits it into an array of separate words. Then, for each word, I use the crack gem, a terrific little gem that converts XML to JSON very easily with the format Crack::XML.parse([something]). The something in this case is client.query(word), which goes to the adapter, creates a query URL for a word, gets back the XML, and converts it to JSON.

So json_word is the JSON output for a word, and json_object is an array of all the JSON for all the words the user typed in.

The Angular app accesses this JSON, and then it does its magic… which I’ll explain in another post!

1 thought on “How I Made Etymologizer, Part 1”

Leave a Reply

Your email address will not be published. Required fields are marked *