HTTP GET com.mycompany.myapp.Order|123

The representation shows all members of the object, along with some special 'reserved' attributes

Outline
{
  "_self": { 
    "link": { ... },
    "title": "Joe Blogg's Order #1",
    "icon": { ... },
    "type": { ... },
  },

  "createdOn": { ... },
  "placedOn": { ... },
  "deliveryOptions": { ... },
  "orderStatus": { ... },
  "paymentMethod": { ... },

  "items": { ... },

  "placeOrder": { ... },
  "cancelOrder": { ... }
}

Notes:

  • The "_self" elements is 'reserved', see Building Blocks
    • represents details about this object.
  • properties will return values (more below)
  • collections (eg 'items') just return a placeholder, no value of type info
  • actions also rendered (since can be invoked)
  • hidden members are not returned
  • members are returned in the order that they should be rendered

In addition, the HTTP Last-Modified should return the timestamp of the last modified (used for optimistic locking checks)

Object Summary

Every representation includes a "_self" attribute, which acts as a summary of the objects:

{
  "_self": {
    "link": {
      "rel": "_self.link",
      "href": "http://localhost:8080/com.mycompany.myapp.Order|123",
      "method": "get",
    },
    "title": "Joe Blogg's Order #1",
    "icon": {
       "rel": "_self.icon",
       "href": "http://localhost:8080/images/Order.png",
       "method": "get",
    },
    "type": {
      "rel": "_self.type",
      "href": "http://localhost:8080/types/application/vnd+com.mycompany.myapp.Order"
      "method": "get"
    },
  },
  ...
}

Notes:

  • the 'rel' attribute for the self's type should be "_self.type".
Properties

The object representation has an JSON attribute for every (visible) property.

The contents of this attribute is a subset of the information shown in the detailed representation, but the intention is to
provide enough information to render the property without having to make additional requests.

The format of this attribute is:

{
  ...
  "createdOn": {
    "value": ...,
    "type": { ... },
    "details": { ... }
  },
  ...
}

where:

  • 'value' holds the current value of the property
    • the format will depend upon whether this is a value or reference property
  • the 'type' is a link to the type of the property
    • the 'rel' should be a concatenation of the property name and the literal 'type'
      • see below for an example
  • the 'details' is a link to a more detailed representation of the property
    • specifically, this detailed representation returns choices and defaults
Property values vs reference

Properties for both value types (eg String, date, int, @Value-annotated classes) and reference types (eg Customer, OrderStatus)
are supported; what varies is the format of the value attribute.

For value types, the value is the actual string-parseable representation, eg:

{
  ...
  "createdOn": {
    "value": "2011-06-14",
    "type": {
      "rel": "createdOn.type",
      "href": "http://localhost:8080/types/application/vnd+date"
      "method": "get"
    },
    ...
  },
  ...
}

Reference properties are similar:

{
  ...
  "orderStatus": {
    "value": {
      "rel": "orderStatus.value",
      "href": "http://localhost:8080/com.mycompany.myapp.OrderStatus|IN_PROGRESS"
      "titleHint": "In Progress",
      "method": "get"
    }
    "type": {
      "rel": "orderStatus.type",
      "href": "http://localhost:8080/types/application/vnd+com.mycompany.myapp.OrderStatus"
      "method": "get"
    },
    ...
  },
  ...
}

Note that:

  • for both value properties and reference properties the type corresponds to the 'compile-time' type of the property, not the runtime type of the reference resource. As such, it maps nicely to the concept of an 'Accept-Type' header for requests
  • the 'rel' for the value reference and type reference is a concatenation of the property name, plus the literal 'type'
Property details

The 'details' attribute provides a link to additional details about the property (the example below also shows the '_self' link to see the relationship between the two links):

{
  "_self": {
    "link": {
      "rel": "_self.link",
      "href": "http://localhost:8080/com.mycompany.myapp.Order|123",
      "method": "get",
    },
  ...
  "paymentMethod": {
    "value": ...,
    "type": { ... },
    "details": {
      "rel": "paymentMethod.details",
      "href": "http://localhost:8080/com.mycompany.myapp.Order|123/paymentMethod",
      "method": "get",
    },
    ...
  },
  ...
}

The detailed representation is a superset of the property attribute within (this) object representation. In addition, it
includes defaults and choices (which are potentially expensive to compute, and are optional).

Property modification

Properties that can be modified provide links to the resources used to change their state.

{
  ...
  "deliveryTime": {
    "value": ...,
    "type": { ... },
    "details": { ... },
    ...
    "modify": {
      "rel": "deliveryTime.modify",
      "href": "http://localhost:8080/com.mycompany.myapp.Order|123/deliveryTime",
      "method": "put"
    },
    "clear": {
      "rel": "deliveryTime.clear",
      "href": "http://localhost:8080/com.mycompany.myapp.Order|123/deliveryTime",
      "method": "delete"
    },
  },
  ...
}

The new value (for the modify) is sent in the body request (HTTP PUT).

Validation of properties occurs when the modify is made; there is no specific resource to just validate a property value. However, it is possible to set a header to request that validation is performed without the actual modification; see PUT on a Property for further details.

Collections

The object representation has an JSON attribute for every (visible) collection.

The contents of this attribute is a subset of the information shown in the detailed representation, but the intention is to
provide enough information to render the collection without having to make additional requests.

Like properties, they have a type, a details link, and links to the state. Unlike properties, though, they do not show a value (to obtain the contents of a collection, the 'details' link must be followed).

The format of this attribute is:

{
  ...
  "items": {
    "type": {
      "rel": "items.type",
      "href": "http://localhost:8080/types/application/vnd+com.mycompany.myapp.OrderItem"
      "method": "get"
    },
    "details": {
      "rel": "items.type",
      "href": "http://localhost:8080/com.mycompany.myapp.Order|123/items"
      "method": "get"
    },
    "addTo": {
      "rel": "items.addTo",
      "href": "http://localhost:8080/com.mycompany.myapp.Order|123/items"
      "method": "put"
    },
    "removeFrom": {
      "rel": "items.removeFrom",
      "href": "http://localhost:8080/com.mycompany.myapp.Order|123/items"
      "method": "delete"
    }
  },
  ...
}

Note:

  • if the collection has set semantics, then a put is used to add to the collection (see example representation above)
  • if the collection has list semantics, then a post can be used to add to the collection

Validation of adding or removing from collections occurs when the modify is made; there is no specific resource to just validate the value. However, it is possible to set a header to request that validation is performed without the actual modification; see PUT on a Collection and POST on a Collection for further details.

Actions

The object representation has an JSON attribute for every (visible) action.

The contents of this attribute is a subset of the information shown in the detailed representation, but the intention is to
provide enough information to render the action without having to make additional requests.

Like properties and collection, they have a link to 'details' which allows additional information (specifically, choices and defaults on parameters) to be obtained that might otherwise be expensive to compute. They also indicate the link to follow to invoke the action.

{
  ...
  "placeOrder": {
    "details": {
      "rel": placeOrder.details",
      "href": "http://localhost:8080/com.mycompany.myapp.Order|123/placeOrder",
      "method": "get",
    },
    "type": {
      "rel": "placeOrder.type",
      "href": "http://localhost:8080/types/application/vnd+com.mycompany.myapp.DeliveryConfirmation"
      "method": "get"
    },
    "numParameters": 3,
    "validateArg": {
      "rel": "placeOrder.validateArg",
      "href": "http://localhost:8080/com.mycompany.myapp.Order|123/placeOrder",
      "method": "put",
    },
    "invoke": {
      "rel": "placeOrder.invoke",
      "href": "http://localhost:8080/com.mycompany.myapp.Order|123/placeOrder/invoke",
      "method": "post",
    },
    "invokeIdempotent": {
      "rel": "placeOrder.invokeIdempotent",
      "href": "http://localhost:8080/com.mycompany.myapp.Order|123/placeOrder/invoke",
      "method": "get",
    },
    ...
  }
  ...
}

Where:

  • the 'hasParameters' indicates whether the action has parameters
  • the 'type' indicates the returned type of the action.
  • the 'invokeIdempotent' link is only rendered if the action is idempotent (the means by which this is specified will vary between Isis and NOF).

Whereas validation of is performed by invoking the modify, validation of action parameters is slightly different:

In common with the properties and collections, the validation of action arguments will occur when when the action is invoked, and it is possible to set a header to request that validation is performed without the actual invocation. In addition, the PUT resource on the action can be used to validate individual arguments if required.

Contributed Actions

It is also possible for an action to be contributed from a domain service. In this case the URL is includes the details of the service that contributed the action.

For example, supposing that the CustomerRepository has an action "placedBy(Order)" which is used to locate the customer that placed a particular Order. This would be represented as follows:

{
  "placedBy": { 
    "contributedFrom": {
      "rel": "_self.object",
      "href": "http://localhost:8080/com.mycompany.myapp.CustomerRepository|1",
      "method": "get",
    },
    "type": {
      "rel": "type",
      "href": "http://localhost:8080/types/application/vnd+com.mycompany.myapp.Customer"
      "method": "get"
    },
    "details": {
      "rel": "details",
      "href": "com.mycompany.myapp.Order|123/com.mycompany.myapp.CustomerRepository/placedBy",
      "method": "get"
    }
    "numParameters": 1,
    ...
  },
  ...
}

Note:

  • the "contributedFrom" attribute indicates that this is a contributed action
  • the "details" href URL is a slightly different format, encoding the domain object that has been contributed to.
Disabled Members

Hidden members (properties, collections or actions) should not be returned in the object representation.

Disabled members should be rendered with a 'disabled' attribute:

{
  ...
  "createdOn": {
    "value": ...,
    "type": { ... },
    "disabled": true
  },
  ...
}

Notes:

  • the "self.
  • the "_self.object" refers to the domain service that contributed, not the domain object
Additional Isis/NOF metadata on members

Object members can be extended with standard Isis/NOF attributes:

{
  ...
  "deliveryOptions": {
    "value": ...,
    "type": { ... },
    "details": { ... },
    "name": "pay by",
    "description": "yada yada",
    "helpText": "yada yada",
    "disabled": false,
  },
  "comments": {
    "value": ...,
    "type": { ... },
    "details": { ... },
    "name": "comments/remarks/special instructions",
    "description": "yada yada",
    "helpText": "yada yada",
    "maxLength": 1024,
    "regex": "[\w\s]*"
  },
  "paymentMethod": {
    "value": ...,
    "type": { ... },
    "details": { ... },
  },
  ...
}
  • No labels