SURF

Simple URF Format

JSON replacement for rich, readable data interchange.

The Simple URF (SURF) format aims to be a replacement for JSON that meets modern needs by providing types such as dates, IRIs, UUIDs, binary data, and decimal numbers. SURF maintains JSON's spirit of simplicity while transparently building on the Uniform Resource Framework (URF) for robust, consistent semantics.

SURF TURF JSON RDF/XML / Turtle
Types
Objects Yes Yes Yes JSON objects are really maps with keys restricted to strings. Yes resource descriptions
String, Number, Boolean Yes Yes Yes Yes
Date Yes Yes No Yes
IRI / URI Yes Yes No Yes
UUID, Regular Expression, Telephone Number, Email Address Yes Yes Yes No
Binary Yes Yes No Yes
Collections: List, Set, Map Yes Yes List-like array. No set. JSON objects are really maps, but keys are restricted to strings. Containers (open): sequence, bag, alternative. List (closed). No map.
Tables Yes Yes No No
Null Read but ignored. Read but ignored. Yes No
Data Model
Object Identifiers Yes Yes No Yes
Repeated Object Properties No Yes No Yes
Graph References Yes Yes No Yes
Ontology Yes Yes No Yes
Reification No Yes No Yes
Serialization
Comments Yes Yes No Yes
Human Readable Yes Yes Yes RDF/XML: verbose. RDF/Turtle: cryptic.
Document Metadata No Yes No No
JSON Backwards Compatible Yes Yes Yes No

Quick Start

JSON

SURF is simple, like JSON. In fact all JSON documents are also SURF documents. Here is a typical JSON document that is valid SURF—but SURF provides many improvements.

User information serialized in JSON.
{
  "authenticated" : true,
  "sort" : "d",
  "name" : "Jane Doe",
  "id" : "bb8e7dbe-f0b4-4d94-a1cf-46ed0e920832",
  "email" : "jane_doe@example.com",
  "phone" : "+12015550123",
  "aliases" : ["jdoe", "janed"],
  "homePage" : "http://www.example.com/jdoe/",
  "salt" : "Zm9vYmFy",
  "joined" : "2016-01-23",
  "credits" : 123
}

Dates

Why should you have to add another layer of programming to parse and serialize dates manually? SURF includes dates out of the box: timestamps, dates, times, time zones, local dates/times, birthdays, durations—you name it!

Ditch the string type and add an initial at-sign @ symbol for real dates in SURF.

One of many SURF date types.
{
  "authenticated" : true,
  "sort" : "d",
  "name" : "Jane Doe",
  "id" : "bb8e7dbe-f0b4-4d94-a1cf-46ed0e920832",
  "email" : "jane_doe@example.com",
  "phone" : "+12015550123",
  "aliases" : ["jdoe", "janed"],
  "homePage" : "http://www.example.com/jdoe/",
  "salt" : "Zm9vYmFy",
  "joined" : @2016-01-23,
  "credits" : 123
}

More Types… and Comments

Characters, IRIs, UUIDs, email addresses, telephone numbers, binary values—all those are included, and more.

You might have forgotten to ask for comments, since JSON doesn't have them. SURF supports them with the exclamation ! mark.

SURF literals and comments.
{
  "authenticated" : true,
  "sort" : 'd', !character literal
  "name" : "Jane Doe"
  "id" : &bb8e7dbe-f0b4-4d94-a1cf-46ed0e920832, !UUID literal
  "email" : ^jane_doe@example.com, !email address literal
  "phone" : +12015550123, !telephone number literal
  "aliases" : ["jdoe", "janed"],
  "homePage" : <http://www.example.com/jdoe/>, !IRI literal
  "salt" : %Zm9vYmFy, !binary literal
  "joined" : @2016-01-23,
  "credits" : 123
}

Human Friendly

How many times have you left out a comma in JSON? In SURF you don't need them when newlines are present. You're still free to use commas if you want a compact, almost binary-like SURF document with no whitespace.

SURF without commas.
{
  "authenticated" : true
  "sort" : 'd'
  "name" : "Jane Doe"
  "id" : &bb8e7dbe-f0b4-4d94-a1cf-46ed0e920832
  "email" : ^jane_doe@example.com
  "phone" : +12015550123
  "aliases" : [
    "jdoe"
    "janed"
  ]
  "homePage" : <http://www.example.com/jdoe/>
  "salt" : %Zm9vYmFy
  "joined" : @2016-01-23,
  "credits" : 123
}

Objects

Did you think you were describing an object representing a user? JSON is a bit sly: you were really defining a JSON associative array or map.

SURF allows you to use identifiers to describe semantic property relationships to real object instances, denoted by the asterisk * character. You can even specify the object type!

Ditch the JSON map key quotes and upgrade to SURF objects. SURF objects use the equal = character for property assignments. The object type User in the example is optional, but really helpful if you want to indicate the type of a real object!

SURF objects.
*User:
  authenticated = true
  sort = 'd'
  name = "Jane Doe"
  id = &bb8e7dbe-f0b4-4d94-a1cf-46ed0e920832
  email = ^jane_doe@example.com
  phone = +12015550123
  aliases = [
    "jdoe"
    "janed"
  ]
  homePage = <http://www.example.com/jdoe/>
  salt = %Zm9vYmFy
  joined = @2016-01-23,
  credits = 123
;

Collections

You want maps anyway? You can have them! SURF maps don't restrict your map property keys to strings like JSON does. In addition to maps (backwards-compatible with JSON) and lists (compatible with JSON arrays), SURF also has sets.

Your programming language probably has all three of these collection types, so why shouldn't your serialization format?

SURF collections.
*User:
  authenticated = true
  sort = 'd'
  name = "Jane Doe"
  id = &bb8e7dbe-f0b4-4d94-a1cf-46ed0e920832
  email = ^jane_doe@example.com
  phone = +12015550123
  aliases = ( !the aliases have no order, so here a set has more appropriate semantics than a list
    "jdoe"
    "janed"
  )
  homePage = <http://www.example.com/jdoe/>
  salt = %Zm9vYmFy
  joined = @2016-01-23,
  credits = 123
  favoriteThings = {
    5 : "Users's favorite number." !a map can have keys of any type
    "aliquot" : "Users's favorite word."
  }
  !the list of colors said to make up the spectrum of a rainbow, in order
  rainbow = ["red", "orange", "yellow", "green", "blue", "indigo", "violet"]
;

Tags

Your id property is working just fine, but you are the only one who knows that the id value is used as your object's primary identifier. Why not encode that knowledge into the SURF document?

SURF allows you to declare a IRI identifier for each object. Place any IRI you choose between vertical line | characters to form a global tag. For short you can use |<&bb8e7dbe-f0b4-4d94-a1cf-46ed0e920832>|; it means the same thing as |<urn:uuid:bb8e7dbe-f0b4-4d94-a1cf-46ed0e920832>|. After declaring a tag in front of the initial object description, you can place that tag anywhere the original object would have appeared to form graph references.

If an object doesn't have a primary identifier, you can declare a local tag by using any valid SURF name instead of an IRI, for example |fooBar|. Local tags are syntax-only; they are not part of the defined object, and only exist within the SURF serialization.

SURF object IRI identifier tags.
*Config:
  users = [
    |<urn:uuid:bb8e7dbe-f0b4-4d94-a1cf-46ed0e920832>|*User:
      name = "Jane Doe"
    ;
    |<urn:uuid:d5207ff8-f64e-46b9-8fd9-d84ce8e0ff29>|*User:
      name = "John Doe"
    ;
  ]
  winner = |<urn:uuid:bb8e7dbe-f0b4-4d94-a1cf-46ed0e920832>|
;

Semantic Framework

SURF is not an arbitrary syntax; it is built on top of a semantic model named the Uniform Resource Framework (URF). Every piece of data in SURF is an URF resource which can be described. In URF even properties are resources which can be described by their own properties. SURF literals also represent resources that in URF have IRIs. If processed by an URF processor, a SURF document becomes a set of logical propositions related to the identified resources, allowing reasoning engines to make inferences to produce answers to new questions related to existing data sets. URF is like Resource Description Framework (RDF), if RDF were simple and consistent.

But you don't need to know anything about semantic frameworks in order to use SURF. You can just use SURF as a better JSON. Under the covers SURF hides a rigorous semantic description of your data, should you ever want to use it. But if you dont need it, you'll never know it's there. That's what puts the simple in Simple URF (SURF)

Learn more.

There are more features and types available in SURF, but it doesn't get much more difficult than what you've seen here. SURF keeps it simple.

You can learn more about SURF and serialization formats in general, as well as read the SURF specification.