It’s just data

Patches Are... Wait For It... Just Data

James Snell: This is clearly better, IMHO, than the line-based diff, but still requires that the client and server both be able to do identical Atom-to-JSON serializations.

Why?  My daughter is studying Algebra II right now, and evaluating f(g(x)), and if she can master such concepts, so can we:

require 'rexml/document'
require 'json'

doc = REXML::Document.new(open(ARGV[0]).read)

SINGULAR = {'authors'=>'author'}

JSON.parse(open(ARGV[1]).read).each {|rule|
  # map json path to xpath
  path=rule['path']
  path=path[0..-3]+["@#{path.last}"] if path[-2] == 'attributes'
  path.map! {|item| SINGULAR[item] || item}
  name = path.pop if rule['action'] == 'create'
  path=path.join('/')
  path.gsub!(/\/(\d+)/) {"[#{$1.to_i+1}]"}

  # apply the action
  value = rule['value']
  case rule['action']
  when 'edit'
    if path.index('@')
      doc.elements[path].normalized=REXML::Text.normalize(value)
    else
      doc.elements[path].text = value
    end
  when 'create'
    if name[0] == ?@
      name = '@xml:lang' if name=='@lang'
      doc.elements[path].attributes[name[1..-1]] = value
    elsif value == []
      doc.elements[path].add_element(name)
    elsif value != {}
      doc.elements[path].add_element(name).add_text(value)
    end
  end
}

puts doc

Note: the above is just barely enough to handle the input data and patch in James’ example, but with a few more test cases, this could quickly become full function.


Oooh, very nice. Hmmm. We’d still need the canonical json serialization, but this could definitely work.

Posted by James Snell at

This back and forth is getting on my nerves. :)

Is there anything I can do to move things forward? Or are we supposed to let people marinate on patch for a while?

Posted by Robert Sayre at

Heh... I’ve already started writing code to implement this,  no reason someone else couldn’t do the same ;-).

Posted by James Snell at

Is there anything I can do to move things forward?

I still believe that the most glaring piece missing is that nobody has spend some time up front specifying the behaviors that they want addressed.  Sure, plenty of people will debate endlessly about PATCH vs POST or JSON vs YAML, but if the problem space is XML in all its glory (including PI’s, comments, DTD’s, and needless distinctions between CDATA and characters), then the solution space looks markedly different than if it is limited to a specific serialization format.  If the goal is to minimize bytes, and the most common use case is typo fixes on (X)HTML content, then again, the solution space again looks substantially different.

In terms of code, I believe that we have what we need for the moment.  I am confident that what I produced above could readily expand to cover all of Atom from an infoset perspective.  I am equally as confident that what the end result could be readily ported to Python, Java, C, C#, JavaScript, PHP, what have you.  Anybody care to disagree?

Simply put, we need more statements such as these:

I worry about round trips induced by Etag mismatches on PUT and conflict avoidance at all costs, more than I worry about the size of the request.

Ideally expressed in terms of desired behaviors.

Posted by Sam Ruby at

In terms of Atompub, what I want to see is a way of manipulating the Atom model, e.g. changing the values of Text constructs, changing the atom:content, adding/removing category/link/author/contributor elements, working with extensions etc.  I do not care about PI’s, comments, DTD’s, CDATA vs. character data, dealing with entities, or even working with the namespace context (e.g.,when I add an extension via a patch, all I should have to do is specify the namespace and element name and have the server deal with the appropriate xmlns:foo declarations).  For the most part, I think PATCH will only be worthwhile when dealing with small change sets.  By “small” I mean things like fixing a typo, adding a couple category elements, changing the title, or changing the updated timestamp.  If I wanted to make all of these changes at once, I would use PUT; if I wanted to make each change individually, I would use PATCH.

Posted by James Snell at

Sam Ruby: Patches Are... Wait For It... Just Data

json to atom...

Excerpt from Public marks with search json at

Add your comment