The document discusses Atom Publishing Protocol (AtomPub) and its use for publishing and editing web resources through a standardized, open protocol. It covers AtomPub specifications and architecture, including using Atom feeds to represent collections of resources that can be manipulated via HTTP methods like POST, GET, PUT, and DELETE. Key aspects covered include pagination, caching, state control, security, and representing metadata through an AtomPub service document.
3. 11870.com
๏ recuerda y comparte negocios ...
David Calavera Conferencia Rails 2007
4. 11870.com
• recuerda y comparte negocios ...
๏ no solo de comentarios vive el hombre
David Calavera Conferencia Rails 2007
5. 11870.com
• recuerda y comparte negocios ...
• no solo de comentarios vive el hombre
๏ ¿por qué tengo que atarme a la web?
David Calavera Conferencia Rails 2007
6. 11870.com
• recuerda y comparte negocios ...
• no solo de comentarios vive el hombre
• ¿por qué tengo que atarme a la web?
๏ ¿quien tiene que adaptarse?
David Calavera Conferencia Rails 2007
8. “the atom publishing protocol is an
application-level protocol for
publishing and editing web resources”
David Calavera Conferencia Rails 2007
9. ๏ ¿sabes qué es HTTP y como usarlo?
David Calavera Conferencia Rails 2007
10. • ¿sabes qué es HTTP y como usarlo?
๏ ¿sabes qué es XML y como usarlo?
David Calavera Conferencia Rails 2007
11. • ¿sabes qué es HTTP y como usarlo?
• ¿sabes qué es XML y como usarlo?
๏ ¿sabes qué es un feed y como crearlo?
David Calavera Conferencia Rails 2007
30. POST /wp-app.php/posts
HTTP/1.1 201 Created
Content-Type: application/atom+xml;type=entry;charset=quot;utf-8quot;
ETag: quot;c180de84f991g8quot;
David Calavera Conferencia Rails 2007
31. POST /wp-app.php/posts
HTTP/1.1 201 Created
Content-Type: application/atom+xml;type=entry;charset=quot;utf-8quot;
ETag: quot;c180de84f991g8quot;
GET /wp-app.php/post/3
HTTP/1.1 304 Not Modified
If-None-Match: quot;c180de84f991g8quot;
David Calavera Conferencia Rails 2007
32. POST /wp-app.php/posts
HTTP/1.1 201 Created
Content-Type: application/atom+xml;type=entry;charset=quot;utf-8quot;
ETag: quot;c180de84f991g8quot;
GET /wp-app.php/post/3
HTTP/1.1 304 Not Modified
If-None-Match: quot;c180de84f991g8quot;
PUT /wp-app.php/post/3
HTTP/1.1 412 Precondition Failed
If-Match: quot;c180de84f991g8quot;
David Calavera Conferencia Rails 2007
33. más...
• paginación
• caché
๏ control de estado
David Calavera Conferencia Rails 2007
45. atomPub:collection
POST 'http://www.verbosemode.com/wp-app.php/posts'
HTTP/1.1 201 Created
Content-Type: */*
Location: 'http://www.verbosemode.com/wp-app.php/post/3'
Content-Location: 'http://www.verbosemode.com/wp-app.php/post/3'
GET 'http://www.verbosemode.com/wp-app.php/posts'
HTTP/1.1 200 OK
David Calavera Conferencia Rails 2007
49. atomPub:entry
PUT 'http://www.verbosemode.com/wp-app.php/post/3'
HTTP/1.1 204 No Content
Content-Type: application/atom+xml;type=entry
DELETE 'http://www.verbosemode.com/wp-app.php/post/3'
HTTP/1.1 200 OK
GET 'http://www.verbosemode.com/wp-app.php/post/3'
HTTP/1.1 200 OK
David Calavera Conferencia Rails 2007
50. atomPub:entry
<?xml version=quot;1.0quot; encoding=quot;utf-8quot;?>
<entry xmlns=quot;http://www.w3.org/2005/Atomquot;
xmlns:app=quot;http://www.w3.org/2007/appquot; xml:lang=quot;enquot;>
<id>http://www.verbosemode.com/?p=3</id>
<title type=quot;textquot;>Spanish Rails Conf 07</title>
<updated>2007-11-04T15:43:49Z</updated>
<published>2007-11-04T11:38:28Z</published>
<app:edited>2007-11-04T15:43:49Z</app:edited>
<app:control><app:draft>no</app:draft></app:control>
<author><name>david</name></author>
<content type=quot;xhtmlquot;><div xmlns='http://www.w3.org/1999/xhtml'>
Next November 22 and 23 I'm going to attend to ...</div></content>
<link rel=quot;editquot; href=quot;http://www.verbosemode.com/wp-app.php/post/3quot; />
<category scheme=quot;http://www.verbosemode.comquot; term=quot;atomPubquot; />
<category scheme=quot;http://www.verbosemode.comquot; term=quot;railsquot; />
<summary type=quot;textquot;>Next November 22 and 23 I’m ...</summary>
</entry>
David Calavera Conferencia Rails 2007
51. atomPub:entry
¿y... qué pasa con los otros tipos de recursos?
<entry xmlns=quot;http://www.w3.org/2005/Atomquot;
xmlns:app=quot;http://www.w3.org/2007/appquot; xml:lang=quot;enquot;>
<id>http://www.verbosemode.com/wp-content/uploads/2007/11/avatar.png</id>
<title type=quot;textquot;>avatar poster</title>
<updated>2007-11-13T21:59:55Z</updated>
<published>2007-11-13T21:59:55Z</published>
<app:edited>2007-11-13T21:59:55Z</app:edited>
<app:control><app:draft>no</app:draft></app:control>
<author><name>david</name></author>
<link rel=quot;edit-mediaquot;
href=quot;http://www.verbosemode.com/wp-app.php/attachment/file/4quot; />
<link rel=quot;editquot; href=quot;http://www.verbosemode.com/wp-app.php/post/4quot; />
<content type=quot;image/pngquot;
src=quot;http://www.verbosemode.com/wp-content/uploads/2007/11/avatar.pngquot;/>
</entry>
David Calavera Conferencia Rails 2007
52. atomPub:entry
¿y... qué pasa con los otros tipos de recursos?
PUT 'http://www.verbosemode.com/wp-app.php/attachment/file/4'
HTTP/1.1 204 No Content
Content-Type: */*
DELETE 'http://www.verbosemode.com/wp-app.php/attachment/file/4'
HTTP/1.1 200 OK
GET 'http://www.verbosemode.com/wp-app.php/attachment/file/4'
HTTP/1.1 200 OK
David Calavera Conferencia Rails 2007
69. los cuatro verbos http
Net::HTTP.start(@uri.host, @uri.port) do |http|
end
David Calavera Conferencia Rails 2007
70. los cuatro verbos http
Net::HTTP.start(@uri.host, @uri.port) do |http|
#POST
http.request Net::HTTP::Post.new(@uri.path), data
end
David Calavera Conferencia Rails 2007
71. los cuatro verbos http
Net::HTTP.start(@uri.host, @uri.port) do |http|
#POST
http.request Net::HTTP::Post.new(@uri.path), data
#GET
http.request Net::HTTP::Get.new(@uri.path)
end
David Calavera Conferencia Rails 2007
72. los cuatro verbos http
Net::HTTP.start(@uri.host, @uri.port) do |http|
#POST
http.request Net::HTTP::Post.new(@uri.path), data
#GET
http.request Net::HTTP::Get.new(@uri.path)
#PUT
http.request Net::HTTP::Put.new(@uri.path), data
end
David Calavera Conferencia Rails 2007
73. los cuatro verbos http
Net::HTTP.start(@uri.host, @uri.port) do |http|
#POST
http.request Net::HTTP::Post.new(@uri.path), data
#GET
http.request Net::HTTP::Get.new(@uri.path)
#PUT
http.request Net::HTTP::Put.new(@uri.path), data
#DELETE
http.request Net::HTTP::Delete.new(@uri.path)
end
David Calavera Conferencia Rails 2007
74. REXML
๏ parser completo
David Calavera Conferencia Rails 2007
75. REXML
• parser completo
๏ escrito completamente en ruby
David Calavera Conferencia Rails 2007
76. REXML
• parser completo
• escrito completamente en ruby
๏ pasa los test de aceptación de Oasis
David Calavera Conferencia Rails 2007
77. REXML
• parser completo
• escrito completamente en ruby
• pasa los test de aceptación de Oasis
๏ soporta XPath
David Calavera Conferencia Rails 2007
78. REXML y xpath
NS = {'atom' => 'http://www.w3.org/2005/Atom',
'app' => 'http://www.w3.org/2007/app',
'georss' => 'http://www.georss.org/georss/10',
'gml' => 'http://www.opengis.net/gml'
}
REXML::XPath.each( feed.root, './atom:entry', NS) do |entry|
title = REXML::XPath.first(entry,
'./atom:title/text()', NS)
edited = REXML::XPath.first(entry,
'./app:edited/text()', NS)
pos = REXML::XPath.first(entry,
'./georss:where/gml:Point/gml:pos/text()', NS)
end
David Calavera Conferencia Rails 2007
79. REXML y xpath
NS = {'atom' => 'http://www.w3.org/2005/Atom',
'app' => 'http://www.w3.org/2007/app',
'georss' => 'http://www.georss.org/georss/10',
'gml' => 'http://www.opengis.net/gml'
}
REXML::XPath.each( feed.root, './atom:entry', NS) do |entry|
title = REXML::XPath.first(entry,
'./atom:title/text()', NS)
edited = REXML::XPath.first(entry,
'./app:edited/text()', NS)
pos = REXML::XPath.first(entry,
'./georss:where/gml:Point/gml:pos/text()', NS)
end
David Calavera Conferencia Rails 2007
80. REXML y xpath
NS = {'atom' => 'http://www.w3.org/2005/Atom',
'app' => 'http://www.w3.org/2007/app',
'georss' => 'http://www.georss.org/georss/10',
'gml' => 'http://www.opengis.net/gml'
}
REXML::XPath.each( feed.root, './atom:entry', NS) do |entry|
title = REXML::XPath.first(entry,
'./atom:title/text()', NS)
edited = REXML::XPath.first(entry,
'./app:edited/text()', NS)
pos = REXML::XPath.first(entry,
'./georss:where/gml:Point/gml:pos/text()', NS)
end
David Calavera Conferencia Rails 2007
81. REXML y xpath
NS = {'atom' => 'http://www.w3.org/2005/Atom',
'app' => 'http://www.w3.org/2007/app',
'georss' => 'http://www.georss.org/georss/10',
'gml' => 'http://www.opengis.net/gml'
}
REXML::XPath.each( feed.root, './atom:entry', NS) do |entry|
title = REXML::XPath.first(entry,
'./atom:title/text()', NS)
edited = REXML::XPath.first(entry,
'./app:edited/text()', NS)
pos = REXML::XPath.first(entry,
'./georss:where/gml:Point/gml:pos/text()', NS)
end
David Calavera Conferencia Rails 2007
82. REXML y xpath
NS = {'atom' => 'http://www.w3.org/2005/Atom',
'app' => 'http://www.w3.org/2007/app',
'georss' => 'http://www.georss.org/georss/10',
'gml' => 'http://www.opengis.net/gml'
}
REXML::XPath.each( feed.root, './atom:entry', NS) do |entry|
title = REXML::XPath.first(entry,
'./atom:title/text()', NS)
edited = REXML::XPath.first(entry,
'./app:edited/text()', NS)
pos = REXML::XPath.first(entry,
'./georss:where/gml:Point/gml:pos/text()', NS)
end
David Calavera Conferencia Rails 2007
83. Builder
๏ crea xml fácilmente
David Calavera Conferencia Rails 2007
84. require 'builder'
builder = Builder::XmlMarkup.new
xml = builder.feed( 'xmlns' => 'http://www.w3.org/2005/Atom' ) do |feed|
feed.id 'http://conferenciarails.org/atomPub'
feed.updated Time.now
feed.author do |author| author.name 'David Calavera' end
feed.entry do |entry|
entry.title 'entrada para la conferencia rails'
end
end
David Calavera Conferencia Rails 2007
85. Builder
• crea xml fácilmente
๏ no solo se usa con rails
David Calavera Conferencia Rails 2007
86. ๏ in the beginning... was the command line
builder = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>2)
David Calavera Conferencia Rails 2007
87. • in the beginning... was the command line
builder = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>2)
๏ vamos de camping
Camping.goes :Atom
module Atom::Views
def index
html do
head do
title 'Atom Publishing Protocol @ conferecia rails'
end
body do ... end
end
end
David Calavera Conferencia Rails 2007
89. atom-tools
http://code.necronomicorp.com/atom-tools
๏ parsea y manipula feeds
David Calavera Conferencia Rails 2007
90. atom-tools
http://code.necronomicorp.com/atom-tools
• parsea y manipula feeds
๏ adaptado al rfc 5023
David Calavera Conferencia Rails 2007
91. atom-tools
http://code.necronomicorp.com/atom-tools
• parsea y manipula feeds
• adaptado al rfc 5023
๏ abstracción de http y xml
David Calavera Conferencia Rails 2007
92. require 'atom-tools'
http = Atom::HTTP.new
http.user = 'david'
http.pass = 'my password'
http.always_auth :basic
service = Atom::Service.new
'http://verbosemode.com/wp-app.php/service', http
service.collections.each do |collection|
puts collection.accepts
end
David Calavera Conferencia Rails 2007
93. require 'atom-tools'
http = Atom::HTTP.new
http.user = 'david'
http.pass = 'my password'
http.always_auth :basic
service = Atom::Service.new
'http://verbosemode.com/wp-app.php/service', http
service.collections.each do |collection|
puts collection.accepts
end
David Calavera Conferencia Rails 2007
94. require 'atom-tools'
http = Atom::HTTP.new
http.user = 'david'
http.pass = 'my password'
http.always_auth :basic
service = Atom::Service.new
'http://verbosemode.com/wp-app.php/service', http
service.collections.each do |collection|
puts collection.accepts
end
David Calavera Conferencia Rails 2007
95. atom_pub_server
http://svn.thinkincode.net/rails/plugins/atom_pub_server
๏ rails es REST
David Calavera Conferencia Rails 2007
96. atom_pub_server
http://svn.thinkincode.net/rails/plugins/atom_pub_server
• rails es REST
๏ mejor soporte para atom y atomPub
David Calavera Conferencia Rails 2007
97. atom_feed do |feed|
feed.title(quot;My great blog!quot;)
feed.updated((@posts.first.created_at))
for post in @posts
feed.entry(post) do |entry|
entry.tag!('georss:where',
'xmlns:georss' => 'http://www.georss.org/georss/10') do |where|
where.tag!('gml:Poing',
'xmlns:gml' => 'http://www.opengis.net/gml') do |point|
point.tag!('gml:pos', nil, '40.419967 -3.698965')
end
end
David Calavera Conferencia Rails 2007
98. atom_feed({'xmlns:georss' => 'http://www.georss.org/georss/10',
'xmlns:gml' => 'http://www.opengis.net/gml'}) do |feed|
feed.title(quot;My great blog!quot;)
feed.updated((@posts.first.created_at))
for post in @posts
feed.entry(post) do |entry|
entry.georss:where do |where|
where.gml:Point do |point|
point.tag!('gml:pos', '40.419967 -3.698965')
end
end
David Calavera Conferencia Rails 2007
99. atom_pub_server
http://svn.thinkincode.net/rails/plugins/atom_pub_server
• rails es REST
• mejor soporte para atom y atomPub
๏ acts_as_collection
David Calavera Conferencia Rails 2007
101. atom_pub_server
http://svn.thinkincode.net/rails/plugins/atom_pub_server
• rails es REST
• mejor soporte para atom y atomPub
• acts_as_collection
๏ acts_as_service_document
David Calavera Conferencia Rails 2007
102. class ServicesController < ApplicationController
acts_as_service_document
def index
render :xml => service_document
end
end
David Calavera Conferencia Rails 2007
103. the ape
http://www.tbray.org/ape
๏ the atom publishing exerciser
104. the ape
http://www.tbray.org/ape
• the atom publishing exerciser
๏ introspección!!!
David Calavera Conferencia Rails 2007
106. the ape
http://www.tbray.org/ape
• the atom publishing exerciser
• introspección!!!
๏ varios sistemas de autenticación
David Calavera Conferencia Rails 2007
108. the ape
http://www.tbray.org/ape
• the atom publishing exerciser
• introspección!!!
• varios sistemas de autenticación
๏ no es muy fácil de instalar (de momento)
David Calavera Conferencia Rails 2007
109. the ape
http://www.tbray.org/ape
• the atom publishing exerciser
• introspección!!!
• varios sistemas de autenticación
• no es muy fácil de instalar (de momento)
๏ no es muy fácil de configurar (de momento)
David Calavera Conferencia Rails 2007
117. más allá de atomPub
• sintaxis
๏ autenticación
David Calavera Conferencia Rails 2007
118. más allá de atomPub
• sintaxis
๏ autenticación
➡ identificar aplicaciones
David Calavera Conferencia Rails 2007
119. Net::HTTP.start( '11870.com' ) do |http|
req = Net::HTTP::Get.new('/api/v1')
req['appToken'] = 'el app token que 11870 te ha asignado'
digest = Digest::MD5.hexdigest(quot;#{req['appToken']}#{la clave secreta}quot;)
req['authSign'] = digest
http.request req
end
David Calavera Conferencia Rails 2007
120. más allá de atomPub
• sintaxis
๏ autenticación
➡ identificar aplicaciones
➡ autenticar usuarios
David Calavera Conferencia Rails 2007
121. request['Authorization'] = 'WSSE profile=quot;UsernameTokenquot;'
request['X-WSSE'] = wsse!
def wsse!
nonce = Array.new(10){ rand(0x1000000) }.pack('I*')
nonce_b64 = [nonce].pack(quot;mquot;).chomp
now = Time.now.gmtime.strftime(quot;%FT%TZquot;)
digest = [Digest::SHA1.digest(nonce_b64 + now + @password)].pack(quot;mquot;).chomp
%Q<UsernameToken Username=quot;#{@username}quot;,
PasswordDigest=quot;#{digest}quot;, Nonce=quot;#{nonce_b64}quot;, Created=quot;#{now}quot;>
end
David Calavera Conferencia Rails 2007
122. más allá de atomPub
• sintaxis
๏ autenticación
➡ identificar aplicaciones
➡ autenticar usuarios
➡ evolucionará a OAuth (http://oauth.net)
David Calavera Conferencia Rails 2007
123. más allá de atomPub
• sintaxis
• autenticación
๏ múltiples representaciones
David Calavera Conferencia Rails 2007
124. {
quot;idquot;:quot;/api/v1/sites/calaveraquot;,
quot;titlequot;:quot;Sitesquot;,
quot;updatedquot;:quot;2007-09-28T07:53:46.000Zquot;,
quot;authorsquot;:[{
quot;namequot;:quot;calaveraquot;
}
],
quot;linksquot;:[{
quot;hrefquot;:quot;http://11870.com/api/v1/sites/calaveraquot;,
quot;relquot;:quot;selfquot;
},{
quot;hrefquot;:quot;http://11870.com/api/v1/sites/calavera?page=2quot;,
quot;relquot;:quot;nextquot;
}
],
quot;entriesquot;:[{
quot;langquot;:quot;esquot;,
quot;idquot;:quot;http://11870.com/pro/23474/calaveraquot;,
quot;titlequot;:quot;Apple Store Fifth Avenuequot;,
quot;summaryquot;:quot;en directoquot;,
quot;contentquot;:quot;estoy ahora mismo en esta...
David Calavera Conferencia Rails 2007
125. más allá de atomPub
• sintaxis
• autenticación
• múltiples representaciones
๏ control de versiones
David Calavera Conferencia Rails 2007
126. ๏ ahora
Net::HTTP.start( '11870.com' ) do |http|
http.request Net::HTTP::Get.new('/api/v1')
end
David Calavera Conferencia Rails 2007
127. • ahora
Net::HTTP.start( '11870.com' ) do |http|
http.request Net::HTTP::Get.new('/api/v1')
end
๏ en un futuro
Net::HTTP.start( '11870.com' ) do |http|
http.request Net::HTTP::Get.new('/api/v1.5')
end
David Calavera Conferencia Rails 2007
128. más allá de atomPub
• sintaxis
• autenticación
• múltiples representaciones
• control de versiones
๏ soporte de librerías
David Calavera Conferencia Rails 2007
130. más allá de atomPub
• sintaxis
• autenticación
• múltiples representaciones
• control de versiones
• soporte de librerías
๏ ¡documentación!
David Calavera Conferencia Rails 2007