OData and Ruby

Sunday, July 11, 2010

The Open Data Protocol is gaining traction and is something to look at if you expose data over the web. .NET 4 has everything you need to build and consume OData with WCF Data Services. It's also easy to consume OData from outside of .NET - everything from JavaScript to Excel.

I've been working with Ruby against a couple OData services, and using Damien White's ruby_odata. Here is some ruby code to dump out the available courses in Pluralsight's OData feed.

require 'lib/ruby_odata'

svc = OData::Service.new "http://www.pluralsight-training.net/Odata/"
svc.Courses
courses = svc.execute
courses.each do |c|
   puts "#{c.Title}"
end

ruby_odata builds types to consume the feed, and also maps OData query options.

svc.Courses.filter("substringof('Fundamentals', Title) eq true")
fundamentals = svc.execute
fundamentals.each do |c|
    puts "#{c.Title}"
end

There is one catch - the Pluralsight model uses inheritance for a few of the entities:

<EntityType Name="ModelItemBase">
    <Property Name="Title" Type="Edm.String" ...="" />
    <!-- ... -->
</EntityType>
<EntityType Name="Course" BaseType="ModelItemBase">
    <Property Name="Name" Type="Edm.String" Nullable="true" />
    <!-- ... -->
</EntityType>

Out of the box, ruby_odata doesn't handle the BaseType attribute and misses inherited properties, so I had to hack around in service.rb with some of the Nokogiri APIs that parse the service metadata (this code only handles a one level of inheritance, and gets invoked when building entity types):

def collect_properties(edm_ns, element, doc)
    props = element.xpath(".//edm:Property", "edm" => edm_ns)
    methods = props.collect { |p| p['Name'] }
    unless element["BaseType"].nil?
        base = element["BaseType"].split(".").last()
        baseType = doc.xpath("//edm:EntityType[@Name=\"#{base}\"]",
                             "edm" => edm_ns).first()
        props = baseType.xpath(".//edm:Property", "edm" => edm_ns)
        methods = methods.concat(props.collect { |p| p['Name']})
    end
    return methods    
end

The overall Ruby <-> OData experience has been quite good.


Comments
Comments are now closed.
by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!