RMX : RDF Message Exchange
Introduction
RMX is a new way to do push-style messaging. The concept is simple and based
on the REST architectural style. Fundamentally, RMX works the following way:
- All messages are identifiable by a URI. This means that anything with a URI
could be a "message".
- In order for someone to "send" a message to a recipient, a
notification is sent, not the message itself.
That's it. With this simple pattern, one can implement "e-mail",
"mailing" lists, forums, etc.
Examples
The following examples illustrate various "common" ways that RMX
could be used.
NOTE: All URIs in these examples (except the RDF and DC
namespace declarations) are ficticious!
Example 1: Sending an "E-mail"
- Message is created and stored at http://seairth.com/rmx/msg/1234.
- Notification is POSTed to http://myrmx.com/users/bob.
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns="http://purl.org/rmx/1.0/">
<notification rdf:nodeID="bNodeNotification">
<dc:creator rdf:resource="http://seairth.com/rmx" />
<dc:publisher>MyRMX Agent 1.0</dc:publisher>
<dc:title>All about RMX</dc:title>
<message rdf:resource="http://seairth.com/rmx/msg/1234" />
</notification>
<message rdf:about="http://seairth.com/rmx/msg/1234">
<dc:creator rdf:resource="http://seairth.com/rmx" />
<dc:format>text/html</dc:format>
<dc:format>text/xhtml+xml</dc:format>
</message>
</rdf:RDF>
- Query is POSTed to http://seairth.com/rmx.
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns="http://purl.org/rmx/1.0/">
<query rdf:nodeID="bNodeQuery">
<dc:creator rdf:resource="http://myrmx.com/users/bob" />
<message rdf:resource="http://seairth.com/rmx/msg/1234" />
</query>
</rdf:RDF>
- The sender server examines the RDF, determines that the query is true and
returns a 200 with the original Notification RDF. This confirms to the
recipient that the notification is authentic.
- A matching notification is created and stored at
http://myrmx.com/users/bob/in/4534.
- Recipient server chooses to copy the actual message to
http://myrmx.com/users/bob/in/4534/msg. The RDF at
http://myrmx.com/users/bob/in/4534 is changed slighly.
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns="http://purl.org/rmx/1.0/">
<notification rdf:nodeID="bNodeNotification">
<dc:creator rdf:resource="http://seairth.com/rmx" />
<dc:publisher>MyRMX Agent 1.0</dc:publisher>
<dc:title>All about RMX</dc:title>
<message rdf:resource="http://seairth.com/rmx/msg/1234" />
</notification>
<message rdf:about="http://seairth.com/rmx/msg/1234">
<copy rdf:resource="http://myrmx.com/users/bob/in/4534/msg" />
<dc:creator rdf:resource="http://seairth.com/rmx" />
<dc:format>text/html</dc:format>
<dc:format>text/xhtml+xml</dc:format>
</message>
</rdf:RDF>
- Recipient client then GETs http://myrmx.com/users/bob, which returns the
list of RDF notification URIs (possibly as an RDF document itself). Client then
uses the list to retrieve notifications, then messages. Notifications can be
organized, deleted, etc as the recipient feels is appropriate.
Notes:
- The <MESSAGE> element in the notification is optional. This element
should only be added if additional information is to be associated to the
message. In this case, it was used to give a hint at possible content formats,
as well as to indicate who the creator of the message was. However, had the
message URL been something like "http://www.cnn.com", there wouldn't
necessarily be a known creator (see next example). As for the content formats,
it should be pointed out that this (and more) information could also be
retrieved by performing a HEAD request (if supported) on the message itself.
- Steps 3 and 4 are optional. The idea here is to allow a recipient to
confirm that a message notification actually came from the sender stated in the
notification. You can think of this as a "callback" feature. If
someone else had tried to impersonate the sender, then the supposed sender
would deny the validity of the query. However, there are times when this may
not be necessary. For instance, additional information provided may give
sufficient information to determine validity. This capability is here in case
no other method is available. Obviously, this cannot protect you from someone
malicious who has taken control of a sender's URI.
- Step 1 and steps 5 through 7 are not part of the RMX specification. Again,
what happens with the notification before it's sent and after it's received is
up to the server implementations. In this case, steps 5 through 7 show how the
message can be retrieved ahead of time, indicated by the <copy> element.
While this element is part of the specification, it is used in ways other than
this (thought this is a legitimate use as well).
For those of you who think this isn't very RESTful (making a copy of a resource
for the client to access instead of the original), I agree. However, the Web is
not perfect. Servers go down. Resource get deleted. Things happen. As a result,
this allows for a certain degree of assurance that the message will be
retrievable. Suggested practice is to always attempt to retrieve the original
resource first, then fall back to the <copy> (of which there could be
more than one) if the original is not retrievable.
Example 2: Sending a link
The process could be as above, but the notification may look like:
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns="http://purl.org/rmx/1.0/">
<notification rdf:nodeID="bNodeNotification">
<dc:creator rdf:resource="http://seairth.com/rmx" />
<dc:publisher>MyRMX Agent 1.0</dc:publisher>
<dc:title>CNN War Headlines</dc:title>
<message rdf:resource="http://www.cnn.com/" />
</notification>
</rdf:RDF>
Notes:
- Notice that there is no <message> element here. In this case, no
additional information is provided about the "message" itself.
- There is no reason that a message must be created by the sender of the
notification. Another way of looking at this is that a notification can be
about anything with a URI.
Example 3: "Replying" to a notification
Suppose http://myrmx.com/users/bob wants to reply to the message from
http://seairth.com/rmx.
- Message is created at http://myrmx.com/users/bob/msg/3395.
- Notification is sent to http://seairth.com/rmx.
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/">
xmlns="http://purl.org/rmx/1.0/">
<notification rdf:nodeID="bNodeNotification">
<dc:creator rdf:resource="http://myrmx.com/users/bob" />
<dc:publisher>RMX+ 3.0</dc:publisher>
<dc:title>Re: All about RMX</dc:title>
<message rdf:resource="http://myrmx.com/users/bob/msg/3395" />
</notification>
<message rdf:about="http://myrmx.com/users/bob/msg/3395">
<dcterms:References rdf:resource="http://seairth.com/rmx/msg/1234" />
</message>
</rdf:RDF>
- (steps 3+ repeated from from Example 1)
Notes:
- The only significant change here it the use of the DC
"References" qualifier to point back to the original message. This
allows relationships to be set up between messages. For instance, messages are
effectively threaded by following the trail of references.
- "Replying" is just a convenient view of the process. In reality,
the sender is doing nothing more than attaching a reference to another message.
This same process could also be viewed as "forwarding". It is all
just a matter of your point of view.
Example 4: "Mailing" list
Suppose http://seairth.com/rmx wants to post to a mailing list at
http://rmxlists.com/rmx-dev.
- Message is created and stored at http://seairth.com/rmx/msg/4567.
- Notification is POSTed to http://rmxlists.com/rmx-dev.
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns="http://purl.org/rmx/1.0/">
<notification rdf:nodeID="bNodeNotification">
<dc:creator rdf:resource="http://seairth.com/rmx" />
<dc:publisher>MyRMX Agent 1.0</dc:publisher>
<dc:title>All about RMX</dc:title>
<message rdf:resource="http://seairth.com/rmx/msg/4567" />
</notification>
<message rdf:about="http://seairth.com/rmx/msg/4567">
<dc:creator rdf:resource="http://seairth.com/rmx" />
</message>
</rdf:RDF>
- Optional query process between the list and the sender may be taken.
- A copy of the message is created at http://rmxlists.com/rmx-dev/msg/43492.
- A notification is created sent to each recipient in the list.
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns="http://purl.org/rmx/1.0/">
<notification rdf:nodeID="bNodeNotification">
<dc:creator rdf:resource="http://rmxlists.com/rmx-dev" />
<dc:publisher>RMX List Agent 1.1</dc:publisher>
<dc:title>[rmx-dev]All about RMX</dc:title>
<message rdf:resource="http://seairth.com/rmx/msg/4567" />
</notification>
<message rdf:about="http://seairth.com/rmx/msg/4567">
<copy rdf:resource="http://rmxlists.com/rmx-dev/msg/43492" />
<dc:creator rdf:resource="http://seairth.com/rmx" />
</message>
</rdf:RDF>
- From here on, recipients handle the notification like any other
notification (including the optional query process).
Notes:
- You will notice that the list server makes a copy of the
"message". Again, due to the unreliability of the Web, this allows
the list to make a copy in case the original resource becomes unavailable. This
may be particularly important if the list maintains an "archive"
which could outlast the existance of the resource.
- The notification sent by the list is not the same notification sent by the
sender. The first notification was to the list, not its members. The list
generated its own notification. Notice that from the lists perspective, it is
sending a notification of a message it did not create. This is no different
than in Example 2, where a link to "http://www.cnn.com" was sent.