Object model

Documents

The main model object handled by Carbon LDP™ is called a Document. A Document begins as a normal JavaScript object containing any number of data attributes (key/value pairs) that you care to define. Typically, a Document represents a data entity of a given type (e.g. Person, Project, Product, Invoice). It can have literal datatype properties (e.g. string, date, number) and pointers that link to other resources. When a normal JavaScript object is saved to Carbon, it receives a URI that uniquely identifies it on a network or the web. That URI can then be used to retrieve the document or to query for specific data attributes within it. Of course, queries can also be used to find data across multiple documents.

URIs as identifiers

Using a numerical value as an ID would be prone to collisions. Using a UUID would solve the collision problem but would make the ID relative to the application (making the ID hard to resolve without knowing where it came from). That’s why Carbon uses Unique Resource Identifiers (or URIs).

URIs are strings that identify resources in a network. Any URL you can think of is also considered a URI, but not all URIs are URLs. The main difference is that a URL can change the resource it is pointing at, while URIs can also belong to a resource forever (in which case they would be URNs (Unique Resource Names).

Basically, URI = URL + URN

URIs follow a scheme. Carbon document’ URIs, follow the http or https scheme (depending on the platform’s configuration).

Using URIs as identifiers allow Carbon documents to be uniqueresolvable and relative to the network.

Properties

Like any JavaScript object, Carbon documents store data in properties. Properties can be named and contain whatever data values your application needs, but there are reserved properties that you should be aware of:

  • id: URI of the document.
  • slug: Holds the last part of the URI the document is identified with. For example the URI: https://example.com/resource-1/ would have as a slug resource-1. This property can be useful when used as a relative URI when retrieving a child Document from a parent.
  • types: An array holding one or more named classes that describe the type of the document (e.g. Person, Project, Product, Invoice).
  • created: Date when the document was created.
  • modified: Date when the document was last modified.
  • hasMemberRelation: Configures the property that will hold the array of Document members.
  • isMemberOfRelation: Specifies the property that a member Document will acquire that links back to its container Document.

Fragments and named fragments

Documents may also contain nested objects. There are two types of nested objects, fragments and named fragments:

var document = {                                        // =================== Document
    id: "https://.../projects/project-x/",
    name: "Project X",
    description: {                                      // -------- Fragment
        format: "html",
        content: "<div>Some content</div>"
    },                                                  // -------- End: Fragment
    sow: {                                              // -------- Named Fragment
        id: "#sow",
        signedOn: new Date( "2016-04-03" ),
        clauses: [ // ... ]
    }                                                   // -------- End: Named Fragment
};                                                      // =================== End: Document

Fragments are identified by an ID, just like documents, but the key difference is that their ID is not a URI. Instead fragments use IDs of the form _:RANDOM-STRING. These IDs are local to the document, making it impossible to link to fragments from outside of the document.

Named fragments on the other hand, are identified by a URI relative to the document. This means, named fragments ARE referenceable from outside the document. Their URIs have the form DOCUMENT-URI#NAMED-FRAGMENT-SLUG, but there are times (as shown in the example) where they can be written relative to the document like #NAMED-FRAGMENT-SLUG.

 

In a Nutshell

You can save JavaScript objects with simple key/value pairs (Carbon documents). The value of a given key may be a nested object which, in turn, becomes either a fragment or a named fragment.

If it doesn’t make sense to reference the inner object outside of the containing document, you can save the inner object as a fragment. If it is an essential part of the document, but it makes sense to reference it from outside, you can create a named fragment.

Object types

Any object stored in Carbon (documents, fragments or named fragments), can be marked with “types”. These types can be thought of as classes or classifications that describe the type of the object.

You can classify an object as any custom type, but be aware that Carbon also automatically assigns certain system types when an object is saved.

The property types will contain an array of types. To determine whether a document represents an object of a given type, you can use the document’s hasType method:

 

// ... imports
let project;

// ... project retrieval

project.types.push( "project", "important-project" );

console.log( project.hasType( "project" ) ); // true
console.log( project.types.length !== 2 ); // true, remember Carbon may add more types to the document
// ... additional imports
import * as PersistedDocument from "carbonldp/PersistedDocument";

let project:Project & PersistedDocument.Class;

// ... project retrieval

project.types.push( "project", "important-project" );

console.log( project.hasType( "project" ) ); // true
console.log( project.types.length !== 2 ); // true, remember Carbon may add more types to the document
var project;

// ... project retrieval

project.types.push( "project", "important-project" );

console.log( project.hasType( "project" ) ); // true
console.log( project.types.length !== 2 ); // true, remember Carbon may add more types to the document

Conclusion

JavaScript objects can be defined with datatype properties, pointers (links) to other resources, fragments (inner-objects), and named fragments (externally referenceable inner-objects). These objects, once saved and/or retrieved using the JavaScript SDK are Document objects. Each Document object is uniquely identified by a URI, which can be used to link to, retrieve, update, or delete the Document. Persisted Documents will always be classified with certain system types, but can also be classified with custom types (e.g. Person, Project, Product, Invoice). Document objects are the main data objects you work with using the JavaScript SDK and the primary means by which you create, read, update, and delete data.