Skip to main content
JSON-LD and
  MongoDB
Powering Linked Web Apps



    Gregg Kellogg
  gregg@greggkellogg.net
        @gkellogg
JSON-LD and Mongo

• JSON-LD – graph expression in JSON
• MongoDB – easily query JSON documents
• Together – efficient graph query optimized
  for client-side processing
Use Case
• WebApps: Single Page Applications (SPAS)
  • Use JSON as native object representation
  • REST access to web service mirroring
    objects
  • MongoDB document store maintaining
    equivalent object representations
• Data is linked, internally and externally (RDF)
JSON-LD
                                         @graph
   @context
                         @id

    JSON-based syntax to express linked data

                                        @language
        @value

                               @list
                                       @vocab
@type             @set
JSON, as expected
{
    "@context": "/contexts/wikia.jsonld",
    "@id": "500f1a1b6e7f1827ba000001",
    "@type": "wikia:VideoGame",
    "contentRating": [
       "ESRB: Mature (DS version is Teen)",
       "PEGI: 18+ (DS version is 16+) ",
       "USK: 18 CERO: Z OFLC: MA15+ (DS version is M)"
    ],
    "datePublished": "2011-11-09",
    "description": "Primary game entry point",
    "genre": ["First-person shooter"],
    "name": "Call of Duty: Black Ops",
    "publisher": [
       {"@id": "501067246e7f184553000001"},
       {"@id": "5010675a6e7f18464d000001"}
    ],
    "event": [
       "500f28856e7f187196000001",
       "500f44556e7f18f7ef000001",
       "500f449e6e7f18f94b000001",
       "500f44e26e7f18fa75000001"
    ],
    "wikia:platform": ["Xbox 360","PS3","PC","Wii","DS"]
}
JSON, as expected
{
    "@context": "/contexts/wikia.jsonld",                  Context defines terms
    "@id": "500f1a1b6e7f1827ba000001",
    "@type": "wikia:VideoGame",
    "contentRating": [
       "ESRB: Mature (DS version is Teen)",
       "PEGI: 18+ (DS version is 16+) ",
       "USK: 18 CERO: Z OFLC: MA15+ (DS version is M)"
    ],
    "datePublished": "2011-11-09",
    "description": "Primary game entry point",
    "genre": ["First-person shooter"],
    "name": "Call of Duty: Black Ops",
    "publisher": [
       {"@id": "501067246e7f184553000001"},
       {"@id": "5010675a6e7f18464d000001"}
    ],
    "event": [
       "500f28856e7f187196000001",
       "500f44556e7f18f7ef000001",
       "500f449e6e7f18f94b000001",
       "500f44e26e7f18fa75000001"
    ],
    "wikia:platform": ["Xbox 360","PS3","PC","Wii","DS"]
}
JSON, as expected
{
    "@context": "/contexts/wikia.jsonld",                  Context defines terms
    "@id": "500f1a1b6e7f1827ba000001",
    "@type": "wikia:VideoGame",                            Identifier treated as IRI
    "contentRating": [
       "ESRB: Mature (DS version is Teen)",
       "PEGI: 18+ (DS version is 16+) ",
       "USK: 18 CERO: Z OFLC: MA15+ (DS version is M)"
    ],
    "datePublished": "2011-11-09",
    "description": "Primary game entry point",
    "genre": ["First-person shooter"],
    "name": "Call of Duty: Black Ops",
    "publisher": [
       {"@id": "501067246e7f184553000001"},
       {"@id": "5010675a6e7f18464d000001"}
    ],
    "event": [
       "500f28856e7f187196000001",
       "500f44556e7f18f7ef000001",
       "500f449e6e7f18f94b000001",
       "500f44e26e7f18fa75000001"
    ],
    "wikia:platform": ["Xbox 360","PS3","PC","Wii","DS"]
}
JSON, as expected
{
    "@context": "/contexts/wikia.jsonld",                  Context defines terms
    "@id": "500f1a1b6e7f1827ba000001",
    "@type": "wikia:VideoGame",                            Identifier treated as IRI
    "contentRating": [
       "ESRB: Mature (DS version is Teen)",
       "PEGI: 18+ (DS version is 16+) ",                   Type same as rdf:type
       "USK: 18 CERO: Z OFLC: MA15+ (DS version is M)"
    ],
    "datePublished": "2011-11-09",
    "description": "Primary game entry point",
    "genre": ["First-person shooter"],
    "name": "Call of Duty: Black Ops",
    "publisher": [
       {"@id": "501067246e7f184553000001"},
       {"@id": "5010675a6e7f18464d000001"}
    ],
    "event": [
       "500f28856e7f187196000001",
       "500f44556e7f18f7ef000001",
       "500f449e6e7f18f94b000001",
       "500f44e26e7f18fa75000001"
    ],
    "wikia:platform": ["Xbox 360","PS3","PC","Wii","DS"]
}
JSON, as expected
{
    "@context": "/contexts/wikia.jsonld",                  Context defines terms
    "@id": "500f1a1b6e7f1827ba000001",
    "@type": "wikia:VideoGame",                            Identifier treated as IRI
    "contentRating": [
       "ESRB: Mature (DS version is Teen)",
       "PEGI: 18+ (DS version is 16+) ",                   Type same as rdf:type
       "USK: 18 CERO: Z OFLC: MA15+ (DS version is M)"
    ],                                                       Data-typed values
    "datePublished": "2011-11-09",
    "description": "Primary game entry point",
    "genre": ["First-person shooter"],
    "name": "Call of Duty: Black Ops",
    "publisher": [
       {"@id": "501067246e7f184553000001"},
       {"@id": "5010675a6e7f18464d000001"}
    ],
    "event": [
       "500f28856e7f187196000001",
       "500f44556e7f18f7ef000001",
       "500f449e6e7f18f94b000001",
       "500f44e26e7f18fa75000001"
    ],
    "wikia:platform": ["Xbox 360","PS3","PC","Wii","DS"]
}
JSON, as expected
{
    "@context": "/contexts/wikia.jsonld",                  Context defines terms
    "@id": "500f1a1b6e7f1827ba000001",
    "@type": "wikia:VideoGame",                            Identifier treated as IRI
    "contentRating": [
       "ESRB: Mature (DS version is Teen)",
       "PEGI: 18+ (DS version is 16+) ",                   Type same as rdf:type
       "USK: 18 CERO: Z OFLC: MA15+ (DS version is M)"
    ],                                                       Data-typed values
    "datePublished": "2011-11-09",
    "description": "Primary game entry point",
    "genre": ["First-person shooter"],                      Simple string values
    "name": "Call of Duty: Black Ops",
    "publisher": [
       {"@id": "501067246e7f184553000001"},
       {"@id": "5010675a6e7f18464d000001"}
    ],
    "event": [
       "500f28856e7f187196000001",
       "500f44556e7f18f7ef000001",
       "500f449e6e7f18f94b000001",
       "500f44e26e7f18fa75000001"
    ],
    "wikia:platform": ["Xbox 360","PS3","PC","Wii","DS"]
}
JSON, as expected
{
    "@context": "/contexts/wikia.jsonld",                    Context defines terms
    "@id": "500f1a1b6e7f1827ba000001",
    "@type": "wikia:VideoGame",                              Identifier treated as IRI
    "contentRating": [
       "ESRB: Mature (DS version is Teen)",
       "PEGI: 18+ (DS version is 16+) ",                      Type same as rdf:type
       "USK: 18 CERO: Z OFLC: MA15+ (DS version is M)"
    ],                                                         Data-typed values
    "datePublished": "2011-11-09",
    "description": "Primary game entry point",
    "genre": ["First-person shooter"],                        Simple string values
    "name": "Call of Duty: Black Ops",
    "publisher": [                                         (unordered) arrays of values
       {"@id": "501067246e7f184553000001"},
       {"@id": "5010675a6e7f18464d000001"}
    ],
    "event": [
       "500f28856e7f187196000001",
       "500f44556e7f18f7ef000001",
       "500f449e6e7f18f94b000001",
       "500f44e26e7f18fa75000001"
    ],
    "wikia:platform": ["Xbox 360","PS3","PC","Wii","DS"]
}
JSON, as expected
{
    "@context": "/contexts/wikia.jsonld",                          Context defines terms
    "@id": "500f1a1b6e7f1827ba000001",
    "@type": "wikia:VideoGame",                                    Identifier treated as IRI
    "contentRating": [
       "ESRB: Mature (DS version is Teen)",
       "PEGI: 18+ (DS version is 16+) ",                            Type same as rdf:type
       "USK: 18 CERO: Z OFLC: MA15+ (DS version is M)"
    ],                                                                Data-typed values
    "datePublished": "2011-11-09",
    "description": "Primary game entry point",
    "genre": ["First-person shooter"],                               Simple string values
    "name": "Call of Duty: Black Ops",
    "publisher": [                                               (unordered) arrays of values
       {"@id": "501067246e7f184553000001"},
       {"@id": "5010675a6e7f18464d000001"}
    ],                                                     subject reference links to other resources
    "event": [
       "500f28856e7f187196000001",
       "500f44556e7f18f7ef000001",
       "500f449e6e7f18f94b000001",
       "500f44e26e7f18fa75000001"
    ],
    "wikia:platform": ["Xbox 360","PS3","PC","Wii","DS"]
}
JSON, as expected
{
    "@context": "/contexts/wikia.jsonld",                          Context defines terms
    "@id": "500f1a1b6e7f1827ba000001",
    "@type": "wikia:VideoGame",                                    Identifier treated as IRI
    "contentRating": [
       "ESRB: Mature (DS version is Teen)",
       "PEGI: 18+ (DS version is 16+) ",                            Type same as rdf:type
       "USK: 18 CERO: Z OFLC: MA15+ (DS version is M)"
    ],                                                                Data-typed values
    "datePublished": "2011-11-09",
    "description": "Primary game entry point",
    "genre": ["First-person shooter"],                               Simple string values
    "name": "Call of Duty: Black Ops",
    "publisher": [                                               (unordered) arrays of values
       {"@id": "501067246e7f184553000001"},
       {"@id": "5010675a6e7f18464d000001"}
    ],                                                     subject reference links to other resources
    "event": [
       "500f28856e7f187196000001",
       "500f44556e7f18f7ef000001",                           Arrays may be ordered in @context
       "500f449e6e7f18f94b000001",
       "500f44e26e7f18fa75000001"
    ],
    "wikia:platform": ["Xbox 360","PS3","PC","Wii","DS"]
}
JSON-LD context
{
    "@context": "/contexts/wikia.jsonld",                  {
    "@id": "500f1a1b6e7f1827ba000001",                         "@context": {
    "@type": "wikia:VideoGame",                                 "wikia":     "http://data.wikia.com/terms#",
    "contentRating": [                                          "xsd":      "http://www.w3.org/2001/XMLSchema#",
       "ESRB: Mature (DS version is Teen)",                     "@vocab":      "http://schema.org/",
       "PEGI: 18+ (DS version is 16+) ",                        "@language": "en",
       "USK: 18 CERO: Z OFLC: MA15+ (DS version is M)"
    ],                                                             "dateCreated": {"@type": "xsd:dateTime"},
    "datePublished": "2011-11-09",                                 "dateModified": {"@type": "xsd:dateTime"},
    "description": "Primary game entry point",                     "event":       {"@id": "wikia:event",
    "genre": ["First-person shooter"],                                             "@type": "@id",
    "name": "Call of Duty: Black Ops",                                             "@container": "@list"},
    "publisher": [                                                 "startDate":   {"@type": "xsd:dateTime"},
       {"@id": "501067246e7f184553000001"},                        "width":       {"@type": "xsd:integer"}
       {"@id": "5010675a6e7f18464d000001"}                     }
    ],                                                     }
    "event": [
       "500f28856e7f187196000001",
       "500f44556e7f18f7ef000001",
       "500f449e6e7f18f94b000001",
       "500f44e26e7f18fa75000001"
    ],
    "wikia:platform": ["Xbox 360","PS3","PC","Wii","DS"]
}
Syntactic Conventions

• Keys represent unique properties
• Values may be singular or multiple
 • May use strings for most value
    representations, with typing information
    maintained in a context.
Unique properties
                 {
Expanded Form:       "http://schema.org/publisher": [
                       {"@id": "501067246e7f184553000001"},
                       {"@id": "5010675a6e7f18464d000001"}
                     ]
                 }


                 {

Compact Form:        "publisher": [
                       "501067246e7f184553000001",
                       "5010675a6e7f18464d000001"
                     ]
                 }
Context:
                 {
                     "@context": {
                       "@vocab": "http://schema.org/",
                       "publisher":{"@type": "@id"},
                       ...
                     }
                 }
Language tagged values
                 {
Expanded Form:       "http://schema.org/name": {
                       "@value": "Call of Duty: Black Ops",
                       "@language": "en"
                     }
                 }




Compact Form:    { "name": "Call of Duty: Black Ops" }




Context:         {
                     "@context": {
                       "@vocab": "http://schema.org/",
                       "@language": "en",
                       ...
                     }
                 }
Typed values
                 {
Expanded Form:       "http://schema.org/datePublished": {
                       "@value": "2011-11-09",
                       "@type": "xsd:dateTime"
                     }
                 }




Compact Form:    { "datePublished": "2011-11-09" }



                 {
Context:             "@context": {
                       "@vocab": "http://schema.org/",
                       "xsd": "http://www.w3.org/2001/XMLSchema#",
                       "datePublished":{"@type": "xsd:dateTime"},
                       ...
                     }
                 }
Subject references
                 {
Expanded Form:       "http://schema.org/publisher": [
                       {"@id": "501067246e7f184553000001"},
                       {"@id": "5010675a6e7f18464d000001"}
                     ]
                 }


                 {

Compact Form:        "publisher": [
                       "501067246e7f184553000001",
                       "5010675a6e7f18464d000001"
                     ]
                 }
Context:
                 {
                     "@context": {
                       "@vocab": "http://schema.org/",
                       "publisher":{"@type": "@id"},
                       ...
                     }
                 }
Nesting
     Flattened Form                                                    Nested Form:
{                                                               {
    "@context": "/contexts/wikia.jsonld",                           "@context": "/contexts/wikia.jsonld",
    "@graph": [                                                     "@id": "500f1a1b6e7f1827ba000001",
      {                                                             "@type": "wikia:VideoGame",
        "@id": "500f1a1b6e7f1827ba000001",                          "name": "Call of Duty: Black Ops",
        "@type": "wikia:VideoGame",                                 "publisher": [
        "name": "Call of Duty: Black Ops",                            {
        "publisher": [                                                  "@id": "501067246e7f184553000001",
           "501067246e7f184553000001",                                  "name": "Activision",
           "5010675a6e7f18464d000001"                                   "url": "http://callofduty.wikia.com/wiki/Activision",
        ]                                                               "@type": "schema:Corporation"
      }, {                                                            }, {
        "@id": "501067246e7f184553000001",                              "@id": "5010675a6e7f18464d000001",
        "name": "Activision",                                           "@type": "schema:Corporation",
        "url": "http://callofduty.wikia.com/wiki/Activision",           "name": "Square Enix (Japan)"
        "@type": "schema:Corporation"                                 }
      }, {                                                          ]
        "@id": "5010675a6e7f18464d000001",                      }
        "@type": "schema:Corporation",
        "name": "Square Enix (Japan)"
      }
    ]
}
Nesting
     Flattened Form                                                    Nested Form:
{                                                               {
    "@context": "/contexts/wikia.jsonld",                           "@context": "/contexts/wikia.jsonld",
    "@graph": [                                                     "@id": "500f1a1b6e7f1827ba000001",
      {                                                             "@type": "wikia:VideoGame",
        "@id": "500f1a1b6e7f1827ba000001",                          "name": "Call of Duty: Black Ops",
        "@type": "wikia:VideoGame",                                 "publisher": [
        "name": "Call of Duty: Black Ops",                            {
        "publisher": [                                                  "@id": "501067246e7f184553000001",
           "501067246e7f184553000001",                                  "name": "Activision",
           "5010675a6e7f18464d000001"                                   "url": "http://callofduty.wikia.com/wiki/Activision",
        ]                                                               "@type": "schema:Corporation"
      }, {                                                            }, {
        "@id": "501067246e7f184553000001",                              "@id": "5010675a6e7f18464d000001",
        "name": "Activision",                                           "@type": "schema:Corporation",
        "url": "http://callofduty.wikia.com/wiki/Activision",           "name": "Square Enix (Japan)"
        "@type": "schema:Corporation"                                 }
      }, {                                                          ]
        "@id": "5010675a6e7f18464d000001",                      }
        "@type": "schema:Corporation",
        "name": "Square Enix (Japan)"
      }
    ]
}
Nesting
     Flattened Form                                                    Nested Form:
{                                                               {
    "@context": "/contexts/wikia.jsonld",                           "@context": "/contexts/wikia.jsonld",
    "@graph": [                                                     "@id": "500f1a1b6e7f1827ba000001",
      {                                                             "@type": "wikia:VideoGame",
        "@id": "500f1a1b6e7f1827ba000001",                          "name": "Call of Duty: Black Ops",
        "@type": "wikia:VideoGame",                                 "publisher": [
        "name": "Call of Duty: Black Ops",                            {
        "publisher": [                                                  "@id": "501067246e7f184553000001",
           "501067246e7f184553000001",                                  "name": "Activision",
           "5010675a6e7f18464d000001"                                   "url": "http://callofduty.wikia.com/wiki/Activision",
        ]                                                               "@type": "schema:Corporation"
      }, {                                                            }, {
        "@id": "501067246e7f184553000001",                              "@id": "5010675a6e7f18464d000001",
        "name": "Activision",                                           "@type": "schema:Corporation",
        "url": "http://callofduty.wikia.com/wiki/Activision",           "name": "Square Enix (Japan)"
        "@type": "schema:Corporation"                                 }
      }, {                                                          ]
        "@id": "5010675a6e7f18464d000001",                      }
        "@type": "schema:Corporation",
        "name": "Square Enix (Japan)"
      }
    ]
}
In-memory linking
     Flattened Form                                 Linked Form:
{
     "@id": "500f1a1b6e7f1827ba000001",          @id         500f1a1b6e7f1827ba000001
     "type": "wikia:VideoGame",
     "schema:name": "Call of Duty: Black Ops",   type        wikia:VideoGame
     "wikia:event": [
       {"@id": "500f28856e7f187196000001"},      name        "Call of Duty: Black Ops"
       {"@id": "500f44556e7f18f7ef000001"},      event       500f28856e7f187196000001
       {"@id": "500f449e6e7f18f94b000001"},
       {"@id": "500f44e26e7f18fa75000001"}
     ]
},
{                                                @id         500f28856e7f187196000001
     "@id": "500f28856e7f187196000001",
                                                 type        cod:Mission
     "type": "cod:Mission",
     "schema:name": "Operation 40",              name        "Operation 40"
     "schema:startDate": "1961-04-17",           startDate   "1961-04-17"
     "wikia:eventIn": [
       {"@id": "500f1a1b6e7f1827ba000001"}       event       500f1a1b6e7f1827ba000001
     ]
}
Turtle Mapping
{                                                        @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
    "@context": "/contexts/wikia.jsonld",                @prefix schema: <http://schema.org/> .
    "@id": "500f1a1b6e7f1827ba000001",                   @prefix wikia: <http://data.wikia.com/terms#> .
    "@type": "wikia:VideoGame",                          @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
    "contentRating": [
       "ESRB: Mature (DS version is Teen)",              <500f1a1b6e7f1827ba000001> a wikia:VideoGame;
       "PEGI: 18+ (DS version is 16+) ",                    schema:contentRating "ESRB: Mature (DS version is Teen)"@en,
       "USK: 18 CERO: Z OFLC: MA15+ (DS version is M)"       "PEGI: 18+ (DS version is 16+) "@en,
    ],                                                       "USK: 18 CERO: Z OFLC: MA15+ (DS version is M)"@en;
    "datePublished": "2011-11-09",                          schema:datePublished: "2011-11-09"^^xsd:dateTime;
    "name": "Call of Duty: Black Ops",                      schema:name "Call of Duty: Black Ops"@en;
    "publisher": [                                          schema:publisher <501067246e7f184553000001>,
       {"@id": "501067246e7f184553000001"},                  <5010675a6e7f18464d000001> .
       {"@id": "5010675a6e7f18464d000001"}                  wikia:event <500f28856e7f187196000001>,
    ],                                                       ...;
    "wikia:event": [                                      .
       {"@id": "500f28856e7f187196000001"},
       ...
    ]
}
More JSON-LD Features*

  • @set, @list,                                  • Embedded
        Compact IRIs,                              @context
        Unlabeled Nodes                            definitions

  • Language maps                                 • Named Graphs
  • Property generators


* http://json-ld.org/spec/latest/json-ld-syntax
History

•   2009 – Started as a way to project from the RDFa API

    •   Developers want solutions to work within HTML
        applications

    •   Desire for JSON-idiomatic way of representing RDF
        (Linked Data)

    •   Adapt existing JSON APIs to Linked Data
History

• 2011 – W3C Community Group launched
 • Broad Participation
 • Separation of Syntax from API
 • Proposed to W3C RDF 1.1 Working
   Group
History
• 2012 – RDF WG abandons other JSON
  serialization efforts (RDF/JSON)
 • JSON-LD accepted as official work item
 • Community Group drafts final report
 • RDF WG publishes JSON-LD (Syntax and
    API) as FPWD
MongoDB
• JSON-like document store
 • BSON supports extra datatypes
 • Certain key patterns are restricted
    • e.g., “.” not allowed in a key
• Query on value = pattern or value includes
  pattern
Use Case
Wikia Structured Data API
Wikia Application
• Express Wiki content as structured data
  • Wiki markup doesn’t naturally include
    semantic cues (Semantic Media Wiki
    aside).
• Add semantic markup to HTML generated
  from Wikis in RDFa
• Aggregate structured content through
  JSON-LD/MongoDB powered data service
Service Architecture
• MongoDB persistence
• JSON document representation
 • JSON-LD describedby link header
• Ruby/Sinatra web service
 • Content-negotiated access to data
    • JSON-LD, HTML, Turtle, ...
Document Model

                               {
•   Use aliases for @id and        "id": "500f1a1b6e7f1827ba000001",
                                   "type": "wikia:VideoGame",
    @type keywords                 "name": "Call of Duty: Black Ops",
                                   "publisher": [

    •   Simplifies use within          "501067246e7f184553000001",
                                      "5010675a6e7f18464d000001"
        client-side MVC            ],
                                   "wikia:event": [
        frameworks (e.g.             "500f28856e7f187196000001"
        backbone.js)               ]
                               }
Document Model

                         {
                             "id": "500f1a1b6e7f1827ba000001",
                             "type": "wikia:VideoGame",
                             "name": "Call of Duty: Black Ops",
•   Individual subject       "publisher": [
                                "501067246e7f184553000001",
    definition as Mongo          "5010675a6e7f18464d000001"
    document                 ],
                             "wikia:event": [
                                "500f28856e7f187196000001"
                             ]
                         }
Document Model

                               {
                                   "id": "500f1a1b6e7f1827ba000001",

•   Use expanded subject           "type": "wikia:VideoGame",
                                   "name": "Call of Duty: Black Ops",
    references                     "publisher": [
                                      {"id": "501067246e7f184553000001"},
                                      {"id": "5010675a6e7f18464d000001"}
    ➡This allows simple            ],
                                   "wikia:event": [
      traversal for graphify          {"id": "500f28856e7f187196000001"}
                                   ]
                               }
Document Model
                             {
                                 "id": "500f1a1b6e7f1827ba000001",

•
                                 "type": "wikia:VideoGame",
    Gather subject               "name": "Call of Duty: Black Ops",
                                 "publisher": [
    references under a              {"id": "501067246e7f184553000001"},
    hidden key                      {"id": "5010675a6e7f18464d000001"}
                                 ],
                                 "wikia:event": [
    ➡This allows easy            ],
                                    {"id": "500f28856e7f187196000001"}
      querying for objects       "_references": [
      referencing another           "501067246e7f184553000001",
                                    "5010675a6e7f18464d000001",
      object                        "500f28856e7f187196000001"
                                 ]
                             }
Document Model
                             GET http://example.com/collection/
                             500f1a1b6e7f1827ba000001

                             HTTP/1.1 200 OK
                             Content-Type: application/json;charset=utf-8
                             Link: </contexts/wikia.jsonld>; rel="describedby";
                             type="application/ld+json"

•   Return context as HTTP   {
    Link Header                  "id": "500f1a1b6e7f1827ba000001",
                                 "type": "wikia:VideoGame",
                                 "name": "Call of Duty: Black Ops",
                                 "publisher": [
                                    {"id": "501067246e7f184553000001"},
                                    {"id": "5010675a6e7f18464d000001"}
                                 ],
                                 "wikia:event": [
                                    {"id": "500f28856e7f187196000001"}
                                 ]
                             }
Restful Endpoints
                               GET http://example.com/collection/?
                               withType="schema:Corporation"
                               Accept: application/json

                               HTTP/1.1 200 OK
•   index – query collection   Content-Type: application/json;charset=utf-8
                               Link: </contexts/wikia.jsonld>; rel="describedby";
                               type="application/ld+json"
    •   by type – return       [
        objects having (or         {
        containing) a type           "id": "501067246e7f184553000001",
                                     "type": "schema:Corporation",
                                     "name": "Activision",
                                     "url": "http://callofduty.wikia.com/wiki/Activision"
                                   }, {
                                     "id": "5010675a6e7f18464d000001",
                                     "type": "schema:Corporation",
                                     "name": "Square Enix (Japan)"
                                   }
                               ]
Restful Endpoints
•
                               GET http://example.com/collection/?
    index – query collection   referencing="500f1a1b6e7f1827ba000001"
                               Accept: application/json

    •   by referencing –       HTTP/1.1 200 OK
        return objects         Content-Type: application/json;charset=utf-8
                               Link: </contexts/wikia.jsonld>; rel="describedby";
        referencing another    type="application/ld+json"
        object                 [{
                                 "id": "500f28856e7f187196000001",

    •   Build out space          "cod:game": {"id": "500f1a1b6e7f1827ba000001"},
                                 "schema:name": "Operation 40",
        around an object         "schema:startDate": "1961-04-17T00:00:00",
                                 "wikia:eventIn": [{"id": "500f1a1b6e7f1827ba000001"}],
                                 "wikia:next": {"id": "500f44556e7f18f7ef000001"},

    •   Similar to SPARQL        "wikia:objective": [
                                    {"id": "501445266e7f1847c6000001"},
        describe                    {"id": "50143e1e6e7f18256d000001"},
                                    ...
                                 ],
                               }, ...]
Restful Endpoints
                          GET http://example.com/collection/
                          500f1a1b6e7f1827ba000001
                          Accept: application/json

                          HTTP/1.1 200 OK
                          Content-Type: application/json;charset=utf-8
                          Link: </contexts/wikia.jsonld>; rel="describedby";

•
                          type="application/ld+json"
    GET – return single
                          {
    object                    "id": "500f1a1b6e7f1827ba000001",
                              "type": "wikia:VideoGame",
                              "name": "Call of Duty: Black Ops",
                              "publisher": [
                                {"id": "501067246e7f184553000001"},
                                {"id": "5010675a6e7f18464d000001"}
                              ]
                          }
Restful Endpoints
                               POST http://example.com/collection/
                               Accept: application/json
                               Content-Type: application/json

                               {

•   POST – Create new              "type": "wikia:VideoGame",
                                   "name": "Call of Duty: Black Ops"
    object                     }
                               HTTP/1.1 201 Created

    •
                               Content-Type: application/json;charset=utf-8
        Good practice to       Link: </contexts/wikia.jsonld>; rel="describedby";
                               type="application/ld+json"
        maintain dateCreated   Location: http://example.com/collection/
        and dateModified        500f1a1b6e7f1827ba000001

        equivalents            {
                                   "id": "500f1a1b6e7f1827ba000001",
                                   "type": "wikia:VideoGame",
                                   "name": "Call of Duty: Black Ops",
                                   "dateCreated": "2012-08-23T14:00:00-08:00",
                                   "dateModified": "2012-08-23T14:00:00-08:00",
                               }
Restful Endpoints
                             PUT http://example.com/collection/
                             500f1a1b6e7f1827ba000001
                             Accept: application/json
                             Content-Type: application/json

                             HTTP/1.1 200 OK
                             Content-Type: application/json;charset=utf-8
•   PUT – Update object      Link: </contexts/wikia.jsonld>; rel="describedby";
                             type="application/ld+json"


    •   Good practice to     {
                                 "id": "500f1a1b6e7f1827ba000001",
        update dateModified       "type": "wikia:VideoGame",
                                 "name": "Call of Duty: Black Ops",
        equivalent               "publisher": [
                                    {"id": "501067246e7f184553000001"},
                                    {"id": "5010675a6e7f18464d000001"}
                                 ],
                                 "dateCreated": "2012-08-23T14:00:00-08:00",
                                 "dateModified": "2012-08-23T14:15:00-08:00",
                             }
Restful Endpoints


                       DELETE http://example.com/collection/
•   DELETE – Destroy   500f1a1b6e7f1827ba000001

    object             HTTP/1.1 204 No Content
Restful Endpoints
                                GET http://example.com/collection/
                                500f1a1b6e7f1827ba000001/publisher/
                                Accept: application/json

                                HTTP/1.1 200 OK

•   path – relational query     Content-Type: application/json;charset=utf-8
                                Link: </contexts/wikia.jsonld>; rel="describedby";
                                type="application/ld+json"

    •   Return objects having   [
        a property                  {
                                    "id": "501067246e7f184553000001",
        relationship with           "type": "schema:Corporation",
        another object              "name": "Activision",
                                    "url": "http://callofduty.wikia.com/wiki/
                                Activision"
                                  }, {
                                    "id": "5010675a6e7f18464d000001",
                                    "type": "schema:Corporation",
                                    "name": "Square Enix (Japan)"
                                  }
                                ]
Restful Endpoints
                              GET http://example.com/collection/
                              500f1a1b6e7f1827ba000001
                              Accept: application/ld+json

                              HTTP/1.1 200 OK
                              Content-Type: application/ld+json;charset=utf-8


•   GET – as explicit JSON-   {
                                  "@context": "/contexts/wikia.jsonld",
    LD                            "id": "500f1a1b6e7f1827ba000001",
                                  "type": "wikia:VideoGame",
                                  "name": "Call of Duty: Black Ops",
                                  "publisher": [
                                    {"id": "501067246e7f184553000001"},
                                    {"id": "5010675a6e7f18464d000001"}
                                  ]
                              }
Working with data
•   Application Structure

    •   Ruby/Sinatra REST
        service

    •   JavaScript/Backbone.js
        client
                                 {
•   Alias JSON-LD                    "@context": {
                                       "id":     "@id",
    keywords for
                                       "type":     "@type"
    convenience
                                     }
                                 }
MVC Client
      • Natural access from client-side MVC (e.g.,
            backbone.js)

                                          Collection
// Object collection, handles objects constructed from OWL classes and properties.
// Initial fetch is only for VideoGame types, as referenced objects are
// fetched, they are added to the collection.
Wikia.ObjectCollection = Backbone.Collection.extend({
  initialize: function() { this.model = Wikia.ObjectModel; },
  url: function() { return "/api/#{@vers}/#{@name}"; },
  comparator: function(model) { return model.get('schema:name') }
  ...
}
MVC Client
       • Natural access from client-side MVC (e.g.,
             backbone.js)

                                                  Model
// OWL model class and sub-classes for dealing with owl:Class,
// owl:DatatypeProperty, owl:ObjectProperty and owl:Datatype
Wikia.ObjectModel Backbone.Model.extend({
  referencedObjects: function() { return this.resolve(_.flatten(_.toArray(this.attributes))); },
  getModel: function(key, options) { return this._resolve this.get(key)) },
  setModel: function(key, value) {...},
  _resolve: function(value) {...},
  ...
}
Summary
•   JSON-LD is a light-weight layer for representing
    linked data in JSON
•   The MongoDB document model is a natural fit for
    JSON-LD
    •   Not optimized for SPARQL; consider alternatives
•   Single Page Applications benefit from linked data
    principles
    •   RDF with OWL can be powerful when used
        appropriately in the client
Resources
•   JSON-LD Syntax
    •   http://w3.org/TR/json-ld-syntax
•   JSON-LD API
    •   http://w3.org/TR/json-ld-api
•   Git Repo
    •   https://github.com/json-ld/json-ld.org
•   Information/Playground
    •   http://json-ld.org/
•   IRC
    •   #json-ld on Freenode
More Information

   json-ld.org              JavaScript
                               Ruby
rdf-comments@w3.org             Python
                                  PHP
                                     Java
 Gregg Kellogg
 gregg@greggkellogg.net
 http://greggkellogg.net/
 @gkellogg