RDF/POST is a syntax for encoding an RDF graph as HTTP GET URL query string or POST form-urlencoded request body. It can be used for building RDF editing interfaces with plain HTML forms (no JavaScript required).

This document is based on the original RDF/POST draft by Sergei Egorov.

Introduction

The Resource Description Framework (RDF) is the basic knowledge representation model for the W3C Semantic Web initiative. RDF/POST is an encoding method allowing the transfer of RDF data via the traditional HTTP GET and HTTP POST mechanism, facilitating the creation of RDF-in/RDF-out web services with dual interfaces (direct programmatic access and human-friendly entry and result pages).

The W3C HTML 4 Forms recommendation specifies the behavior of HTTP user agents and includes a short description of the format used for submission of form data (MIME type "application/x-www-form-urlencoded"). The format is rather simple; its data model is an ordered list of key/value pairs, where keys and values are just strings. As implemented in modern browsers, the format has its limitations, but there is nothing preventing one from using (a profile of) it to serialize any RDF graph.

The proposed serialization is straightforward and rather concise, which makes it suitable for use with HTTP GET (URLs over 2K in length run a risk of causing 414 Request URL Too Long reply from the server). It inherits the abbreviated tree form from [[Turtle]], using different keys for subject, predicate, and object to eliminate the need for punctuation.

RDF/POST Grammar

This EBNF is defined in XML 1.0 second edition [[XML]].

rdf::='rdf=' def_ns_decl? ns_decl* triples*
def_ns_decl::='&v=' uri_prefix
ns_decl::='&n=' name '&v=' uri_prefix
triples::=subj property*
subj::=blank_subj | uri_subj | def_ns_subj | ns_subj
blank_subj::='&sb=' name
uri_subj::='&su=' uri
def_ns_subj::='&sv=' uri_suffix
ns_subj::='&sn=' name '&sv=' uri_suffix
property::=pred obj*
pred::=uri_pred | def_ns_pred | ns_pred
uri_pred::='&pu=' uri
def_ns_pred::='&pv=' uri_suffix
ns_pred::='&pn=' name '&pv=' uri_suffix
obj::=blank_obj | uri_obj | def_ns_obj | ns_obj | literal_obj
blank_obj::='&ob=' name
uri_obj::='&ou=' uri
def_ns_obj::='&ov=' uri_suffix
ns_obj::='&on=' name '&ov=' uri_suffix
literal_obj::='&ol=' string type_or_lang? | type_or_lang '&ol=' string
type_or_lang::=type | lang
type::='&lt=' uri
lang::='&ll=' lang_id
uri::=string    /* URI as defined in RFC3986 */
uri_prefix::=uri    /* any valid URI prefix */
uri_suffix::=uri    /* any valid URI suffix */
lang_id::=string    /* see xml:lang */
name::=[A-Za-z][A-Za-z0-9]*     /* same as in N-Triples */
string::=(schar | plus | echar)*     /* unreserved or urlencoded */
schar::=[A-Za-z0-9.,;:'/?!$@()*~_-]     /* safe as per RFC3986 */
plus::='+'     /* encodes single space (#x20) */
echar::='%'[0-9A-Fa-f][0-9A-Fa-f]   /* encodes one octet */

Parsing

The use of this format in HTML pages relies on the fields are listed in the order they appear requirement of the HTML Forms specification. Since HTML user agents are not required to send fields with null values (browsers are free to ignore them), such fields should not be used to send pairs which are important for correct decoding of the format (e.g. a pair defining the subject of a triple). Remember that hidden fields are always sent if they have value attributes present.

To handle data submitted from HTML forms, the decoder should allow for some missing pairs, skipping to the next sync point (if any) and silently ignoring the affected triples:

Strings can contain any Unicode character encoded in UTF-8 and, if the resulting octets fall outside of US_ASCII, urlencoded as described in Form content types - application/x-www-form-urlencoded [[HTML401]]. The simplest way to ensure that browsers send form data in UTF-8 is to encode form pages in UTF-8.

Examples

Here is a simple RDF/POST document encoded in a simple HTML form:

Someone called titled

The HTML code of this form looks like this:

<form>
    <p>
        <input type="hidden" name="rdf" value=""/>

        <!-- namespace declarations -->
        <input type="hidden" name="v" value="http://xmlns.com/foaf/0.1/"/>
        <input type="hidden" name="n" value="rdf"/>
        <input type="hidden" name="v" value="http://www.w3.org/1999/02/22-rdf-syntax-ns#"/>
        <input type="hidden" name="n" value="dc"/>
        <input type="hidden" name="v" value="http://purl.org/dc/elements/1.1/"/>

        <!-- triples -->
        <span>Someone called</span>
        <input type="hidden" name="sb" value="o"/>
        <input type="hidden" name="pv" value="givenName"/>
        <input type="text" name="ol" value="Ora" size="10"/>

        <input type="hidden" name="pv" value="familyName"/>
        <input type="text" name="ol" value="Lasilla" size="10"/>

        <input type="hidden" name="pn" value="dc"/>
        <input type="hidden" name="pv" value="creator"/>
        <input type="hidden" name="ob" value="b"/>

        <input type="hidden" name="sb" value="b"/>
        <input type="hidden" name="pn" value="rdf"/>
        <input type="hidden" name="pv" value="type"/>
        <select name="ov">
            <option selected="selected" value="Document">wrote a book</option>
            <option value="Image">painted a picture</option>
        </select>

        <span>titled</span>
        <input type="hidden" name="pn" value="dc"/>
        <input type="hidden" name="pv" value="title"/>
        <input type="text" name="ol" value="Moby Dick" size="20"/>

        <button type="submit">Post</button>
    </p>
</form>

During form submission, the browser constructs the following query string (spaces and indentation are added for presentation purposes):

rdf=
&v=http://xmlns.com/foaf/0.1/
&n=rdf &v=http://www.w3.org/1999/02/22-rdf-syntax-ns%23
&n=dc &v=http://purl.org/dc/elements/1.1/
&sb=o
 &pv=givenName
  &ol=Ora
 &pv=familyName
  &ol=Lasilla
 &pn=dc &pv=creator
  &ob=b
&sb=b
 &pn=rdf &pv=type
  &ov=Document
 &pn=dc &pv=title
  &ol=Moby+Dick

It can be compared line-by-line with the equivalent Turtle description:

@prefix : <http://xmlns.com/foaf/0.1/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns%23> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
_:o
 :givenName
  "Ora" ;
 :familyName
  "Lasilla" ;
 dc:creator
  _:b .
_:b
 rdf:type
  :Document ;
 dc:title
  "Moby Dick" .

If one wants to make sure that submitted data conforms to RDF datatype requirements, e.g. does not contain unexpected empty string values and incorrectly formatted dates, the forms can be validated with Javascript code.

Internet Media Type, File Extension and Macintosh File Type

As a rule, RDF/POST data is sent with "application/x-www-form-urlencoded" media type; if one needs to distinguish RDF/POSTs from regular posts, a more specific "application/rdf+x-www-form-urlencoded" media type can be used (not yet registered with IANA). Encoding considerations are the same in both cases; RDF/POSTs can be distinguished by the rdf= prefix.

Recommended file extension is ".rpo"