This project is read-only.

Simple Feed Bindings deep dive

Dec 14, 2009 at 3:11 PM

We’ve had a lot of conversations with various people, inside Microsoft and externally, where the question of how Simple Feed Bindings (SFB) is different from other technologies comes up a lot.  If you are one of those people, then I recommend you first read the backgrounder on how SFB came to be.  Then continue with the rest of this article, as I’m going to describe how to create a new SFB definition and along the way highlight some aspects that should help readers understand the value of SFB.

Creation

Let’s start by creating a new SFB definition.  Imagine that you want to create a feed that will contain items, where each item represents simple contact info for a person.  For now we’ll say that the contact info contains a person’s full name, an address and a phone number – where the phone number is an optional part of the contact info.  Note that it is a best practice to always put application data within custom XML namespaced elements.  For the simple contact info, we are going to define an XML namespace prefix of ‘sci’ and an XML namespace uri of ‘http://example.com/namespaces/sci’.

Here’s what a RSS feed containing the SFB definition for contact info could look like:

Feed #1

<?xml version="1.0" encoding="utf-8"?>

<rss version="2.0" xmlns:sx="http://feedsync.org/2007/feedsync"

    xmlns:sfb="http://feedsync.org/2008/namespaces/binding">

  <channel>

    <sfb:binding

      title="{fullname}" description="{address}">

      <sx:sync updates="1">

        <sx:history sequence="1" by="MHS_Blog_Sample"/>

      </sx:sync>

      <sfb:namespace localprefix="sci" uri="http://example.com/namespaces/sci"/>

      <sfb:field element="sci:fullname" required="true"/>

      <sfb:field element="sci:address" required="true"/>

      <sfb:field element="sci:phonenumber"/>

    </sfb:binding>

  </channel>

</rss>

Since one of the design goals of SFB was to allow people to use a text editor to create definitions, it wasn’t too difficult to come up with one for this example.  Here are some items worth noting in Feed #1:

  • The Binding id is set to a URI value.  This is not required, but it is considered a good practice.  As long as the value is unique, you can use anything.  I know that many people like to use GUIDs as id values, but we should all recognize that sometimes in not possible, or easy,  to generate one.
  • The title attribute is set to an expression such that the value of the <fullname> element will be copied into the <title> element for the item
  • The description attribute is set to an expression such that the value of the <address> element will be copied into the <description> element for the item
  • The binding has FeedSync metadata, which means that the binding can be updated in the future. 
  • The FeedSync id is set to the same value as the Binding id.  This is not required, but it is considered a good practice.  Again, as long as the value is unique, you can use anything.
  • A namespace has been defined such that all references to the ‘sci’ namespace prefix should correspond to the ‘http://example.com/namespaces/sci’ namespace uri.  Note that this information is exclusively used when interpreting the SFB definition and nothing more.  I say this because feeds are free to [re]use XML namespace prefixes as they see fit.  This means that ‘sci’ could map to a different namespace uri within the feed and/or some other namespace prefix could have been chosen to represent the namespace uri for simple contact info.
  • Items will be expected to have a <fullname> element that is defined in the XML namespace uri for simple contact info.  Since no type or contenttype attributes are set for this field, the value of this element will be treated as text.
  • Items will be expected to have an <address> element that is defined in the XML namespace uri for simple contact info.  Since no type or contenttype attributes are set for this field, the value of this element will be treated as text.
  • Items may or may not have a <phonenumber> element that is defined in the XML namespace uri for simple contact info.  Since no type or contenttype attributes are set for this field, the value of this element will be treated as text.

If you were to save the contents of Feed #1 to a local file, and then used one of the FeedSync Service utilities link here (e.g.  FeedSyncServiceUpdateFeed.exe) to update an existing feed on the FeedSync Service, you could inject the SFB definition to that feed.  Once the feed on the FeedSync Service contains a SFB definition, you can then use the FeedSync Feed editor to create, edit or delete items.

Here is what the RSS feed might look like after creating a new item:

Feed #2

<?xml version="1.0" encoding="utf-8"?>

<rss version="2.0" xmlns:sx="http://feedsync.org/2007/feedsync"

    xmlns:sci="http://example.com/namespaces/sci"

    xmlns:sfb="http://feedsync.org/2008/namespaces/binding">

  <channel>

    <sfb:binding

        title="{fullname}" description="{address}">

      <sx:sync updates="1">

        <sx:history sequence="1" by="Paresh_Blog_Sample"/>

      </sx:sync>

      <sfb:namespace localprefix="sci" uri="http://example.com/namespaces/sci"/>

      <sfb:field element="sci:fullname" required="true"/>

      <sfb:field element="sci:address" required="true"/>

      <sfb:field element="sci:phonenumber"/>

    </sfb:binding>

    <item>

      <title>Paresh Suthar</title>

      <description>1 Microsoft Way, Redmond, WA  98052</description>

      <sx:sync updates="1">

        <sx:history sequence="1" by="Paresh@Laptop1"/>

      </sx:sync>

      <sci:fullname>Paresh Suthar</sci:fullname>

      <sci:address>1 Microsoft Way, Redmond, WA  98052</sci:address>

      <sci:phonenumber>425-555-1212</sci:phonenumber>

    </item>

  </channel>

</rss>

Here are some items worth noting in Feed #2:

  • The item has its own, separate FeedSync metadata
  • The values for <sci:fullname> and <sci:address> are duplicated in the <title> and <description> respectively, which seems unnecessary.  You might also be thinking that the <sci:fullname> and <sci:address> elements could be eliminated and just use the <title> and <description>.  These are valid observations/thoughts and worth discussing.  First we should remember that the expression values (specified for the title and description attributes) for the <sfb:binding> element are simplistic.  The second thing to think about is that, from an application’s point of view,  it would be clunky to have parts of the data live in custom defined elements where other parts lived in elements defined by the feed format (i.e. <title> and <description> for RSS feeds).  The third thing to think about is that if you want to make the data that lives in a feed be expressable in other item container formats (e.g. POX, JSON, SQL, etc…), the less data that lives in feed format specific fields, the better.

Modification

Let’s modify the SFB definition to 1) Change the expression values to be more meaningful and 2) Add a new field to contact info to indicate if the contact is friendly.

Since SFB primarily deals with feeds, one goal is to produce content that can be displayed by feed reader applications in a meaningful way to users.  To help accomplish this goal, we can set expression values to be a combination of static and computed content to be displayed for the title and description of items.  Computed content is represented by using {} to enclose the name of a <sfb:field> element.  In the case of the title expression, we are going to use ‘Simple Contact Info for {sci:fullname}’.  In the case of the description expression, we are going to use an HTML table that looks like this:

<table>

  <tr><td><b>Fullname:</b></td><td>{sci:fullname}</td></tr>

  <tr><td><b>Address:</b></td><td>{sci:address}</td></tr>

  <tr><td><b>Phonenumber:</b></td><td>{sci:phonenumber}</td></tr>

  <tr><td><b>Friendly:</b></td><td>{sci:friendly}</td></tr>

</table>

This table is a combination of static text and multiple values from various <sci:***> elements.  Note that since we are setting the value of an XML attribute, the HTML table must be XML encoded.  If we eliminated all unnecessary whitespace, the XML encoded value would look like this:

&lt;table&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Fullname:&lt;/b&gt;&lt;/td&gt;&lt;td&gt;{sci:fullname}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Address:&lt;/b&gt;&lt;/td&gt;&lt;td&gt;{sci:address}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Phonenumber:&lt;/b&gt;&lt;/td&gt;&lt;td&gt;{sci:phonenumber}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Friendly:&lt;/b&gt;&lt;/td&gt;&lt;td&gt;{sci:friendly}&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

For the new field, we will add a required boolean value to indicate whether the contact is friendly, with the default value being ‘true’. This means that we will need to add the following XML to the SFB definition:

<sfb:field element="sci:friendly" required="true" defaultvalue="true"/>

The resulting feed could look like:

Feed #3

<?xml version="1.0" encoding="utf-8"?>

<rss version="2.0" xmlns:sx="http://feedsync.org/2007/feedsync"

    xmlns:sci="http://example.com/namespaces/sci"

    xmlns:sfb="http://feedsync.org/2008/namespaces/binding">

  <channel>

    <sfb:binding

       title="Simple Contact Info for {fullname}"

description="&lt;tablestyle=&#39;width:100%&#39;&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Fullname:&lt;/b&gt;&lt;/td&gt;&lt;td&gt;{sci:fullname}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Address:&lt;/b&gt;&lt;/td&gt;&lt;td&gt;{sci:address}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Phonenumber:&lt;/b&gt;&lt;/td&gt;&lt;td&gt;{sci:phonenumber}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Friendly:&lt;/b&gt;&lt;/td&gt;&lt;td&gt;{sci:friendly}&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;">

      <sx:sync updates="2">

        <sx:history sequence="2" by="Paresh_Blog_Sample"/>

      </sx:sync>

      <sfb:field element="sci:fullname" required="true"/>

      <sfb:field element="sci:address" required="true"/>

      <sfb:field element="sci:phonenumber"/>

      <sfb:field element="sci:friendly" required="true"

        defaultvalue="true"/>

    </sfb:binding>

    <item>

      <title>Paresh Suthar</title>

      <description>1 Microsoft Way, Redmond, WA  98052</description>

      <sx:sync updates="1">

        <sx:history sequence="1" by="Paresh@Laptop1"/>

      </sx:sync>

      <sci:fullname>Paresh Suthar</sci:fullname>

      <sci:address>1 Microsoft Way, Redmond, WA  98052</sci:address>

      <sci:phonenumber>425-555-1212</sci:phonenumber>

    </item>

  </channel>

</rss>

Here are some items worth noting in Feed #3:

  • The FeedSync metadata for the SFB definition was updated.  This will enable any subscriber of the feed to detect that the SFB definition has been modified, and can react accordingly.
  • The existing item hasn’t changed or been modified, AND THAT’S OK.  When a SFB definition is modified, there is no necessity or expectation that all existing items be modified.  Instead, it is expected that all subscribers of the feed be prepared for the situation where items may be missing required fields and/or items may contain fields that are not defined in the SFB definition.  Another expectation is that any newly created items, or modification of existing items, will use the latest SFB definition.  This means that if some type of application validation were to occur (e.g. verify that required fields are populated), it would be when the user/app saves changes to an item.
  • Since the SFB definition is inlined with the items (i.e. data), the overall feed is very portable and can be stored in a variety of ways.  To contrast this, if the SFB definition was in a separate location, fixups would most likely be needed per storage mechanism.  For example, if there was a web link in the RSS feed to the SFB definition, then that link would need to be modified if the RSS feed were persisted to a local file – otherwise if an app working with that feed were unable to get connectivity, it would not be able to get SFB updates.

If you were to save the contents of Feed #3 to a local file, and then update the same feed on the FeedSync Service, the SFB definition would be updated there as well.  If you then used the FeedSync Feed editor to create or edit items, you would see the new ‘friendly’ field show up.

Here is what the RSS feed might look like after creating another new item:

Feed #4

<?xml version="1.0" encoding="utf-8"?>

<rss version="2.0" xmlns:sx="http://feedsync.org/2007/feedsync"

    xmlns:sci="http://example.com/namespaces/sci"

    xmlns:sfb="http://feedsync.org/2008/namespaces/binding">

  <channel>

    <sfb:binding

       title="Simple Contact Info for {fullname}"

description="&lt;tablestyle=&#39;width:100%&#39;&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Fullname:&lt;/b&gt;&lt;/td&gt;&lt;td&gt;{sci:fullname}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Address:&lt;/b&gt;&lt;/td&gt;&lt;td&gt;{sci:address}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Phonenumber:&lt;/b&gt;&lt;/td&gt;&lt;td&gt;{sci:phonenumber}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Friendly:&lt;/b&gt;&lt;/td&gt;&lt;td&gt;{sci:friendly}&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;">

      <sx:sync updates="2">

        <sx:history sequence="2" by="Paresh_Blog_Sample"/>

      </sx:sync>

      <sfb:field element="sci:fullname" required="true"/>

      <sfb:field element="sci:address" required="true"/>

      <sfb:field element="sci:phonenumber"/>

      <sfb:field element="sci:friendly" required="true"

        defaultvalue="true"/>

    </sfb:binding>

    <item>

      <title>Paresh Suthar</title>

      <description>1 Microsoft Way, Redmond, WA  98052</description>

      <sx:sync updates="1">

        <sx:history sequence="1" by="Paresh@Laptop1"/>

      </sx:sync>

      <sci:fullname>Paresh Suthar</sci:fullname>

      <sci:address>1 Microsoft Way, Redmond, WA  98052</sci:address>

      <sci:phonenumber>425-555-1212</sci:phonenumber>

    </item>

    <item>

       <title>Simple Contact Info for The Grinch</title>

<description>&lt;tablestyle=&#39;width:100%&#39;&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Fullname:&lt;/b&gt;&lt;/td&gt;&lt;td&gt;The Grinch&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Address:&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Whoville&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Phonenumber:&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Friendly:&lt;/b&gt;&lt;/td&gt;&lt;td&gt;false&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</description>

       <sx:sync updates="1">

         <sx:history sequence="1" by="Paresh@Laptop1"/>

       </sx:sync>

       <sci:fullname>The Grinch</sci:fullname>

       <sci:address>Whoville</sci:address>

       <sci:friendly>false</sci:friendly>

    </item>

  </channel>

</rss>

Here are some items worth noting in Feed #4:

  • For the newly added item, the <title> is a combination of static text and the value from the <sci:fullname> element.
  • For the newly added item, the <description> is a combination of static text and multiple values from various <sci:***> elements.
  • For the newly added item, the <sci:phonenumber> element does not exist, which is ok because it is not a required field per the SFB definition.
  • For the newly added item, the <sci:friendly> element now appears as part of the contact info.
  • The original item, which uses the old SFB definition, exists side by side with new item, which uses the new SFB definition.

Roll Up

I hope that this article provides some better insight into the value of SFB definitions for defining the structure/data of items including:

  • How easy it is to create an SFB definition
  • How to evolve an SFB definition
  • How to generate meaningful, rich content that can be displayed in feed readers using expressions

There are various aspects of SFB that I didn’t touch on including labels, picklists, arrays, extension elements and more.  I highly recommend that you play around with the Simple Feed  Binding Client (link here) to get familiar with all aspects of SFB.

I know that there are other ways/technologies that can be used to accomplish what SFB does, but keep in mind that SFB is meant to be an application specific metamodel and not some type of horizontal technology that competes with the likes of XAML, XSD, Relax NG, etc…  With that being said, please provide any comments/thoughts you might have.