14 DOMAIN OBJECT RESOURCE & REPRESENTATION

The domain object resource can be used to obtain the summary domain object representation §C14.4 for a particular domain object, and can also be used to update or delete individual persisted domain object instances (where allowed).

The endpoint URL (using templated URI syntax) for this resource is:

/objects/{domainType}/{instanceId}

where:

  • {domainType} uniquely identifies the object’s domain type, and

  • {instanceId} uniquely identifies an object instance of that type

Together the {domainType}/{instanceId} may be referred to as the object identifier, or oid.

The specification does not mandate the format of either the domainType or the instanceId; the following are all potentially valid forms:

  • /objects/customers/123

  • /objects/myApp.Customer/123

  • /objects/CUS/123

  • /objects/ORD/123-456

  • /objects/countries/USA

14.1 HTTP GET

Obtain a summary representation of a domain object §C14.4. The intention is that enough information is provided to render the object in the client’s UI.

14.1.1 Request

14.1.1.1 Query String

  • x-ro-domain-model (optional, §A3.1)

    • "simple"

    • "formal"

14.1.1.2 Headers

  • Accept

    • application/json

    • application/json;profile="…​/object"

If the "profile" parameter is specified to any value other than "…/object", then a 406 response code should be returned §C13.9.

14.1.1.3 Body

  • N/A

14.1.2 Success Response

As per §C13.1 (200), returning a domain object representation §C14.4.

14.2 HTTP PUT

Update multiple properties of the object at the same time, or alternatively validate the proposed values but do not modify the object.

14.2.1 Request

The request can either be to update the properties, or to request validation of the proposed values using the x-ro-validate-only query param §A3.2.

14.2.1.1 Query String

  • None

14.2.1.2 Headers

  • If-Match

    • timestamp digest

      • obtained from ETag header of representation

14.2.1.3 Body

The body is the map of new properties, as per §A2.9.2.3. Note that any blob/clob properties must be in-lined within this map. (Contrast this to updating of individual properties where the value of a blob/clob can be PUT in its native media type, §C16.2). In addition, it may include the reserved query parameters:

  • x-ro-domain-model (optional, §A3.1)

    • "simple"

    • "formal"

  • x-ro-validate-only (optional, §A3.2)

    • "true"

      • only validate the request, do not modify the property

For example:

{
  "firstName": {
    "value": ...
  },
  "lastName": {
    "value": ...
  }, ...
}

14.2.2 Success Response

As per §C13.3 (200), returning a domain object representation §C14.4. Because the resource has mutated the state, there will be no self link (so that it cannot be bookmarked by clients).

14.3 HTTP DELETE

Deletes an object. This is an optional capability §B8 because implementing a generic ‘delete object’ capability - which includes managing any references to the deleted object throughout the system - is potentially complex, and not necessarily practicable for many implementations.

If the implementation does support the capability then it must also determine that it is safe to delete the object. A 405 ("method not allowed") error will be returned otherwise.

14.3.1 DELETE Request

14.3.1.1 Query String

  • none

14.3.1.2 Headers

  • If-Match

    • timestamp digest

      • obtained from ETag header of representation

14.3.1.3 Body

  • N/A

14.3.2 DELETE Success Response

As per §C13.3 (204), returning no representation.

14.4 Representation

The domain object representation provides summary information about a single domain object instance, along with links to other sub-resources by which the domain object may be interacted with, or mutated. As such, it the single most important representation defined by Restful Objects.

The Content-Type for the representation is:

application/json;profile=".../object";x-ro-domain-type="yyy"

where yyy identifies the domain type identifier:

  • the domain type id of the returned object (simple scheme)

  • the URI to the domain type of the returned object (formal scheme).

The representation is typically generated from the Domain Object resource §C14.1, though it can also be generated by the Domain Service resource §C15 (since Restful Objects regards a domain service as being just a well-known domain object). It may also be obtained as the result updating multiple properties §C14.2, or of persisting a proto-persistent object §B9.

The links from the domain object representation to other resources are as shown in the diagram below:

Slide8
Figure 1. DOMAIN OBJECT REPRESENTATION

For example, the representation of a (persistent domain entity) Order might be:

{
  "domainType": "ORD",
  "instanceId": " 123",
  "title": "Joe Blogg's Order #1",
  "members": {
    ...
  },
  "links": [ {
      "rel": "self",
      "href": "http://~/objects/ORD/123",
      "type": "application/json;profile=\".../object\"",
      "method": "GET"
    }, ...
  ], "extensions": { ... }
}

where:

JSON-Property Description

links

list of links to resources.

links[rel=self]

(optional); link to a resource that can obtain this representation. Note that the href for a service will be http://~/services/{serviceId}. Discussed further below.

domainType

(optional) the domain type to use when building template URIs. Discussed further below.

instanceId

(optional) the instance identifier, to use when building template URIs. Discussed further below.

serviceId

(optional) the service Id. Present only if the object is a domain service §C15.

title

a string identifier of the object, suitable for rendering in a UI.

members

map of object members (properties, collections, actions). Discussed further below.

links[rel=…​/persist]

(optional) persist the (proto-persistent) domain object. Discussed further below

links[rel=…​/update]

(optional) link to modify multiple properties of the domain object (using §C14.2). The link is present only for persistent domain entities that have at least one modifiable property. Discussed further below.

links[rel=…​/delete]

(optional) delete the (persistent) domain object. Discussed further below.

links[rel=icon]

(optional) link to an image representing a scalable icon for this object

extensions

additional information about the resource.

"domainType"

The "domainType" json-property is only present for the simple scheme §A3.1.1; if the formal scheme §A3.1.2 is supported then the "domainType" can be obtained from the domain-type representation §D22.2.

Domain services do not have a "domainType" json-property.

"instanceId" , "serviceId" and "links[rel=self]"

The "instanceId" json-properties is present for persistent domain entities and for addressable view models §A2.2, and can (with the "domainType" json-property) be used to construct URLs to other resources for the domain object as required.

Proto-persistent domain objects and (non-addressable) view models §A2.2 do not have an "instanceId" because they do not correspond to any server-side state that can be directly addressed; nor do they have a ‘self’ link, for the same reasons.The "serviceId" json-property performs much the same function as "instanceId", allowing the URL for domain services to be constructed. The "serviceId" is present only for domain services. Domain services do not have a "instanceId" json-property.

"members"

The "members" map contains an entry for every (visible) member. It is described in more detail in the sections below §C14.4.1, §C14.4.2, §C14.4.3 .

"links[rel=…​/update]"

For persistent domain objects, there may optionally be a rel="…​/update" link to update all properties of the domain object.

This link is not guaranteed to be present, however; if none of the properties of an object are updatable then the update properties link will not be present.

Also, proto-persistent domain objects and view models will never have an update link.

"links[rel=…​/delete]"

For persistent domain objects, there may optionally be a rel="…​/delete" link to delete the domain object.

This links is not guaranteed to be present, however. Support for deleting objects is an optional capability §B8.2, and so is not guaranteed to be supported by every framework implementation. If it is supported, then the implementation should define its own mechanism to restrict which objects can be deleted, and which may not.

Also, proto-persistent domain objects and view models will never have a delete link.

"links[rel=…​/persist]"

For proto-persistent domain objects, a rel="…​/persist" link is provided.

The "arguments" map for this link is a subset of the object representation itself, containing a single "members" map for the (property) members of the domain object itself. The keys of the "members" map correspond to every mandatory property of the domain object (note: not just those that are visible to the user).

For example, the "persist" link for an Order might look like:

"links": [
  {
    "rel": ".../persist",
    "href": "http://~/objects/ORD",
    "type": "application/json;profile=\".../object\"",
    "method": "POST",
    "arguments": {
      "members": {
        "placedBy": {
          "value": ...
        },
        "placedOn": {
          "value": ...
        },
        ...
      }
    }
  },
  ...
]

Note that there is no need to specify the domain type within the "arguments" map because it can be inferred from the href being posted to.

Domain model information about the type is available through either the "links" or the "extensions" json-properties. This is discussed separately in §C14.4.4.

Implementations are free to add to their own links/properties to "links" and "extensions" as they require.

14.4.1 Properties

The "members" map contains an entry for every (visible) property. This entry contains a subset of the information shown in the detailed property representation §C16.4.The intention is to provide enough information to render the property value in a user interface without having to make additional requests.

For example, the "createdOn" property would look something like:

"members": {
  "createdOn": {
    "memberType": "property",
    "value": ...,
    "disabledReason": ...,
    "links": [ {
        "rel": ".../details;property=\"createdOn\"",
        "href": "http://~/objects/ORD/123/properties/createdOn",
        "type": "application/json;profile=\".../object-property\"",
        "method": "GET"
      }, ...
    ],
    "extensions": { ... }
  }, ...
}

where the member’s id ("createdOn" in the example above) is used as a unique key in the "members" map, and its value being the following map:

JSON-Property Description

memberType

the constant value "property"

value

(optional) the current value of the property, either a scalar, a (link representing a) reference, or null. Discussed further below.

disabledReason

(optional) if populated then indicates the reason why the property cannot be modified.

links

list of links to resources.

links[rel=…/details]

(optional) link to the detailed representation of the property, §C16.4 (e.g. to access defaults and choices).

links[rel=…/attachment]

(optional) link to the property value if it is an attachment. Discussed further below.

extensions

map of additional information about the resource.

"value" and "links[rel=…/attachment;…​]"

The "value" json-property holds the in-lined value of the property, though depending on the nature of the domain object and the type of the property, it may or may not be present:

  • if the property value is null, then the "value" json-property will be present and set to the JSON null value

  • for proto-persistent domain objects and (non-addressable) view models (§A2.2), the "value" is always present.

  • for persistent domain objects and addressable view models (with server-side state §A2.2), the "value" is always present for non-blobs/clobs §A2.5

  • for blobs/clobs in implementations that do not support attachments §A-46, again the "value" is present

  • however, for persistent domain objects which support attachments the "value" is omitted. Instead a link to the attachment will be available. This link serves up the property value directly with the correct media type (e.g. as an image/jpg).

From the client’s perspective, this means that there is always either a "value" json-property or a "links[rel=…/attachment;…]" json-property.

Other domain model information about the property is available through either the "links" or the "extensions" json-properties.

The information provided through these json-properties is the same as provided in the domain object property representation, see §C16.4.3.

Implementations are free to add to their own links/json-properties to "links" and "extensions" as they require.

14.4.2 Collections

The "members" map also contains an entry for every (visible) collection, which provides a link to the corresponding Object Collection resource.

The member entry may also provide summary information about the collection (for example, its size) so that the client can render the collection without having to make additional requests to the server.

However, if the domain object being represented has no corresponding server-side state (§A2.2), then the collection’s representation also in-lines the collection representation §C17.5.

As for (object) properties, the json-property representing a collection has a type, a details link, and links to the state.

For example, the Order’s items collection would look something like:

"members": {
  ...,
  "items": {
    "memberType": "collection",
    "disabledReason": ...,
    "value": [ ... ],
    "size": ...,
    "links": [ {
        "rel": ".../details;collection=\"items\"",
        "href": "http://~/objects/ORD/123/collections/items",
        "type": "application/json;profile=\".../object-collection\"",
        "method": "GET"
      }, ... ],
    "extensions": { ... }
  },
  ...
]

where the member’s id is used as a unique key in the "members" map, and its value being the following map:

JSON-Property Description

memberType

the constant value "collection" disabledReason (optional) if populated then indicates the reason why it is not possible to add to or remove from the collection.

value

(optional) contains a representation of the contents of the collection. Discussed further below.

size

(optional) contains a count of the elements in the collection. Discussed further below.

links

links to other resources.

links[rel=…​/details]

(optional) link to the detailed representation of the collection, §C17.5, which includes such information as defaults and choices. Discussed further below.

extensions

additional information about the resource.

"links[rel=…​/details]", "value" and "size"

As noted above, representations of domain objects without corresponding server-side state (§A2.2) will in-line the "value" of the collection.

For these domain objects, there is no "size" json-property and there is no "links[rel=…/details;…​]" link.

Domain objects with server-side state, however, need not provide a "value". Instead, they may provide a "links[rel=…​/details]" which when followed will return the value in the collection’s detailed representation §C17.5.

This behaviour allows implementations to load only the object and not all of its related references (in other words, lazy loading).

Other domain model information about the collection is available through either the "links" or the "extensions" json-properties. The information provided through these json-properties is the same as provided in the domain object collection representation, see §C17.5.3.

Implementations are free to add to their own links/json-properties to "links" and "extensions" as they require

14.4.3 Actions

The "members" map also contains an entry for every (visible) action. Note however that only domain objects with corresponding server-side state (§A2.2) will have actions.

The information provided is a subset of the information shown in the detailed action representation §C18.2 (obtainable from the GET Action resource §C18). The intention is to provide enough information to render the action without having to make additional requests.

Like a property or a collection, an action has a link to 'details' which allows additional information (specifically, choices and defaults on parameters) to be obtained that might otherwise be expensive to compute. It also includes a link to follow in order to invoke the action.

For example, the Order’s submit() action might be represented as:

"members": { ...
  "submit": {
    "memberType": "action",
    "disabledReason": ...,
    "links": [ {
        "rel": ".../details;action=\"submit\"",
        "href": "http://~/objects/ORD/101/actions/submit",
        "type": "application/json;profile=\".../object-action\"",
        "method": "GET"
      } ... ],
    "extensions": { ... }
  }, ...
}

where the member’s id is used as a unique key in the "members" map, and its value being the following map:

JSON-Property Description

memberType

the constant value "action" disabledReason (optional) if populated then indicates the reason why the action may not be invoked.

links

list of links to other resources.

links[rel=…​/details]

link to the detailed representation of the action, §C18.2

extensions

additional metadata about the resource

Other domain model information about the action is available through either the "links" or the "extensions" json-properties.

The information provided through these json-properties is the same as provided in the domain object action representation, see §C18.2.3.

Restful Objects defines no further standard links/json-properties for "links" or "extensions". However, implementations are free to add to their own links/json-properties as they require.

14.4.4 Domain model information

Domain model information is available through either the "links" or the "extensions" json-properties.

Simple scheme

Implementations that support the simple scheme provide extra data in the "extensions" json-properties.

For example:

"extensions": {
    "domainType": "ORD",
    "friendlyName": "Order",
    "pluralName": "Orders",
    "description": "An order that has been placed by a customer",
    "isService": false,
    "memberOrder": 1
}

See §A3.1.1 for the full definitions of these json-properties.

Formal scheme

Implementations that support the formal scheme §A3.1.2 provide an additional link in the "links" json-property:

"links": [ {
    "rel": "describedby",
    "href": "http://~/domain-types/ORD",
    "type": "application/json;profile=\".../domain-type\"",
    "method": "GET"
  }, ...
]

which links to the domain type resource §D22 corresponding to this domain object.