Status

Author

Mike Amundsen, mca@amundsen.com

Status

Working Draft — Only experimental and ‘proof-of-concept’ apps should be built on this unstable draft.

Proposed IANA Registrations

application/prs.wstl+json

Repository

https://github.com/RWCBook/wstl-spec

Last Updated

2016-12-28

General

This document contains the specifications for the WeSTL format used in the book RESTful Web Clients [RWCBook] by Mike Amundsen. This format is used to drive the server-side representor pattern. The WeSTL format exists in two different ‘states’. In its design-time state, it contains the list of all possible state transitions for a Web service. In its runtime state, it contains the list of the selected transitions for the current resource along with any data assocaited with that resource. The design-time document can be used to define all possible transitions including possible arugments for querying or writing data. The runtime document can be passed to a module that can turn the WeSTL document into a representation format (e.g. HTML, Collection+JSON, HAL, etc.).

Design Goals

This format was designed to make it easier for service developers to focus on the state transition details of a Web service instead of the resource details. To that end, a minimal WeSTL document contains a list of possible state transitions.

The design-time version of the document contains nothing more than a list of possible state transitions. Each transition contains meta-data about the transition including possible arguments to be used to executing queries or writing data. There is no indication of which resource to which these transitions belong. In fact, many of the transitions will occur on several resouces. For example the home transition (that leads to the home page of the service) might appear on every resource.

The runtime version of the document contains a filtered list of the state transitions — the ones that apply to the current resource request — along with a collection of data associated with that same resource request. In this case, the WeSTL document represents all the applicable state transitions for the current runtime context. Since this document has a standardized format, it can be populated and then passed to a module designed to convert the WeSTL document into a registered media type format such as HTML, HAL, Collection+JSON, etc.

Thus, there are two goals for the WeSTL format:

  1. Provide an easy way for service developers to focus on state transitions

  2. Provide a standard format for representor programmers to convert internal service state into registered media type representations.

Sample Document

Below is a sample WeSTL document (in its runtime mode). It contains a list of all the appropriate state transitions for a running Web service in a specific state.

{
  "wstl": {
    "actions": [
      {
        "name": "homeLink",
        "description" : "View the home page",
        "type": "safe",
        "action": "read",
        "kind": "",
        "target": "list menu",
        "prompt": "Home",
      },
      {
        "name": "searchForm",
        "description" : "Search for content",
        "type": "safe",
        "action": "read",
        "kind": "search",
        "target": "list form",
        "prompt": "Search",
        "inputs": [
          {
            "name": "text",
            "prompt": "Search Text",
            "value": "Danny",
            "required" : true
          },
          {
            "name": "external",
            "prompt": "External Search?",
            "value": "",
            "required: true,
            "suggest": [{"value":"true"},{"value":"false"}]
          }
        }
      }
    ],
    "data": [
      {
        "id": "1a14qx7qc81",
        "title": "Danny Boy"
      },
      {
        "id": "1q2w3e43r",
        "title": "Danny Tremane"
      },
      {
        "id": "azsxdcfvgb",
        "title": "Danny Two-Shoes"
      },

    ]
  }
}

See the Sample WeSTL Documents section for details on this and other WeSTL examples.

Updates

There is an open source repository [REPO] for this specification. Readers are encouraged to submit updates via the repository any time.

Compliance

An implementation is not compliant if it fails to satisfy one or more of the MUST or REQUIRED elements. An implementation that satisfies all the MUST and REQUIRED elements as well as all the SHOULD and RECOMMENDED elements is said to be "unconditionally compliant"; one that satisfies all the MUST and REQUIRED elements but not all the SHOULD and RECOMMENDED elements is said to be "conditionally compliant."

Note

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC [RFC2119].

Media Type Identifier

The WeSTL document format is primarily designed to be used as an internal message model for aiding in the sharing of Web-like transition information and related data. However, it is possible to expose WeSTL documents directly on the Web.

For cases where the WeSTL document will be sent as a document over the WWW, the proper media type identifier string to use is: application/prs.wstl+json. This value SHOULD be used by the client application when requesting a WeSTL document and SHOULD be used by the server when responding with a WeSTL document.

The WeSTL Document Model

The WeSTL document MUST be a valid JSON document per [RFC4627]. A WeSTL document has a very simple format. However, it is also easily extended to fit a local Web service implementor’s needs. Below is a top-down survey of the WeSTL document model.

The wstl Object

The wstl object is the root object of every WeSTL document. It has a small set of child properties and MAY be extended with custom properties.

Quick View

The wstl object looks like this:

{
  "wstl" : {
    "title" : "...",
    "actions" : [],
    "content" : {},
    "data" : [],
    "related" : {}
  }
}

Details

Here are the details:

wstl

The top-level element in every WeSTL document. This is a REQUIRED element.

actions

A RECOMMENDED child property of the wstl element. If it exists, it MUST be an array of action objects (see below). Parsers MUST continue to process this document even when this element is missing.

content

An OPTIONAL child property of the wstl element. If it exists, it MUST be a valid content object (see below). Parsers MAY use this element to render content for display. Parsers MUST ontinue to process this document even when this element is missing.

data

A RECOMMENDED child property of the wstl element. If it exists, it MUST be an array of JSON objects that represent the data associated with the runtime request. The data element is an open format and MAY contain any other valid JSON content.

related

An OPTIONAL child property of the wstl element. If it exists, it MUST be an object populated by one or more named arrays (see below).

title

An OPTIONAL child property of the wstl element. It SHOULD be set to the title string of the runtime resource. Document parsers MUST continue to process the document even when this element is missing.

The action Object

The action object is an anonymous JSON object that contains meta-data information about each state transition. This object contains a number of properties. The only one that is REQUIRED is the name property. All others are OPTIONAL.

Quick View

The action object looks like this:

{
  "name" : "",
  "description" : "",
  "type" : "safe|unsafe",
  "action" : "read|append|update|remove|diff",
  "target" : "",
  "prompt" : "",
  "href" : "",
  "rel" : [],
  "inputs" : []
}

Details

Here are the details:

name

The internal name of the transition. This is a REQUIRED property.

description

A string that describes this transition. This is an OPTIONAL property. Parsers MAY use this as additional information when rendering the input for users.

type

Indicates the network request type for the transition. It MUST be set to one of the following values: safe or unsafe.

action

Indicates the application request type for the transition. It MUST be set to one of the following values: read, append, replace, remove, diff.

target

Contains a space-separated list of string values. These values can be used to tag the transition for later search/retrieval.

prompt

Contains a string that represents the human prompt for this transition. This value can be used as labels for links and forms.

href

Contains the URL associated with the transition. This value SHOULD only be populated in the runtime version of WeSTL documents but MAY be set at design-time. If populated, this value MUST comply with the rules of [RFC3986]

rel

Contains an array of link relation values for the transition. This value MUST comply with the rules of [RFC5988]

inputs

Contains an array of anonymous input objects (see below).

The content Object

The content object is an anonymous JSON object that contains information and data for rendering content for viewing. This object contains only two OPTIONAL properties (type and text). If no properties are present, the content element SHOULD be ignored.

Quick View

The content object looks like this:

{
  "type" : "html|markdown|text",
  "text" : "..."
}

Details

Here are the details:

text

A string representing the complete content to be rendered. This content MAY require additional parsing based on the value of the type property. If the type property is missing or is an unrecognized value, the contents of text SHOULD be treated as plain text. This is an OPTIONAL property.

type

A string representing the type of text that appears in the text property. Valid values are "html", "markdown", "text". This is an OPTIONAL property. Parsers SHOULD use this value as a guide on processing the contents of the text property (e.g. treat the content as "html", etc.). If this property is missing or contains an unrecognized value, the property SHOULD be treated as if it was set to "text".

The related object contains a set of one or more named arrays. Each array is a list of anonymous objects that represent shared, related data for this document. The lists in the related object are used by the suggest processing when rendering input options (see below).

Quick View

Here is a quick view of the related object.

"related" : {
  "NAME" : []
}

The "NAME" in the above example is set to a specific value in document. For example, if the list contained a set of users, related object might look like this:

"related" : {
  "userList" : []
}

The value of each array is an open format and MAY contain any other valid JSON content.

The input Object

The input object is an anonymous JSON object that contains meta-data information about each input argument for a state stransition. This object contains a number of properties. The only one that is REQUIRED is the name property. All others are OPTIONAL.

Quick View

Here is a quick view of the input object.

{
  "name" : "",
  "prompt" : "",
  "value" : "",
  "readOnly" : true|false,
  "required" : true|false,
  "pattern" : "",
  "type" : "textarea"|"select",
  "suggest" : []|{}
}

Details

Here are the details.

name

The name of the input argument.

prompt

The human-readable prompt associated with the argument.

value

The value for this argument. This MAY be left blank and filled in at runtime. It MAY contain a placeholder that complies with the [RFC6570] specification and may be resolved at runtime.

readOnly

A flag to indicate this value is to be rendered as read-only at runtime. If it exists, its value MUST be set to true or false. If this property is missing or is set to an unknown value, it SHOULD be treated as if it is set to false.

required

A flag to indicate this value is an required input. If it exists, its value MUST be set to true or false. If this property is missing or is set to ann unknown value, it SHOULD be treated as if it is set to false.

pattern

A regex value to be used as an input validator at runtime. If it exists, its value MUST comply with the [HTMLPattern] specification.

type

An OPTIONAL property indicating the display type used when rendering the input. Valid values are textarea (render as a multiline input) and select (render as a list of input options). If this property is missing or set of an unknown value, the input SHOULD be rendered as a simple text input (e.g. type="text").

suggest

An OPTIONAL property indicated the values to use when rendering a select-type input of options. The suggest object somes in two forms: 1) an array of values (see Suggest Arrays) or 2) a reference to related data (see Suggest Related Data). It is up to the rendering engine to decide how to handle each form of suggest information — including ignoring it completely.

Suggest Arrays

The suggest array is an OPTIONAL collection of anonyous name-value pair objects for use when rendering a select-type input of options.

Quick View

Here is a quick view of the suggest array object.

"suggest" : [
  {"value" : "S", "text" : "Small"},
  {"value" : "M", "text" : "Medium"},
  {"value" : "L", "text" : "Large"}
]

Details

The suggest array contains one or more anonymous name-value pair objects. Rendering engines SHOULD be prepared for only one of the properties (value or text) to appear at runtime. When this happens, the value of the existing property SHOULD be used for both properties. For example, if only a set of value properties are supplied, the rendering engine SHOULD assume the missing text property is set to the same value as the value property.

The suggest related data object is an OPTIONAL object with three properties for use when rendering a select-type input of options. The properties (related, value, and text) are used to lookup data in the related section of the document and render as input options.

Quick View

Here is a quick view of the suggest related data object.

"suggest" : {
  "related" : "userList",
  "value" : "id",
  "text" : "userName"
}

Details

The suggest related data object is an OPTIONAL object with three properties for use when rendering a select-type input of options.

related

The value of related is the name of a list in the related section of the document. This is a REQUIRED property. If this property is missing or set to a value that does not match a named list in the related section of the document, then this suggest object SHOULD be ingored.

value

This contains the property-name of the items in the list pointed to by the related property. This is a REQUIRED property. This will be used as the selected value when rendering input options. If this property is missing or set to a value that does not match a property name in the related section list, then this suggest object SHOULD be ingored.

text

This contains the property-name of the items in the list pointed to by the related property. This is a REQUIRED property. This will be used as the display value when rendering input options. If this property is missing or set to a value that does not match a property name in the related section list, then this suggest object SHOULD be ingored.

Sample WeSTL Documents

Below are sample WeSTL documents for reference.

A Design-Time WeSTL Document

Below is a WeSTL document in its design-time mode. It conatins a list of all the possible state transitions for a Web service offering a seach service.

{
  "wstl": {
    "actions": [
      {
        "name": "homeLink",
        "description" : "View the home page",
        "type": "safe",
        "action": "read",
        "kind": "",
        "target": "list menu",
        "prompt": "Home",
      },
      {
        "name": "searchLink",
        "description" : "Search page",
        "type": "safe",
        "action": "read",
        "kind": "search",
        "target": "list menu",
        "prompt": "Search",
      },
      {
        "name": "searchForm",
        "description" : "Search for content",
        "type": "safe",
        "action": "read",
        "kind": "search",
        "target": "list form",
        "prompt": "Search",
        "inputs": [
          {
            "name": "text",
            "prompt": "Search Text",
            "value": "",
            "required" : true
          },
          {
            "name": "external",
            "prompt": "External Search?",
            "value": "",
            "required: true,
            "suggest": [{"value":"true"},{"value":"false"}]
          }
        }
      }
    ]
  }
}

Note that this document contains three state transitions:

  1. The one that leads to the home page (homeLink)

  2. The one that leads to the search form (searchLink)

  3. The one that leads to the search results (searchForm)

A Run-Time WeSTL Document

Below is a WeSTL document in its runtime mode. It conatins a list of all the appropriate state transitions for a running Web service in a specific state. In this case, this document represents the state of the service once it has executed a search and is ready for the next inputs.

{
  "wstl": {
    "actions": [
      {
        "name": "homeLink",
        "description" : "View the home page",
        "type": "safe",
        "action": "read",
        "kind": "",
        "target": "list menu",
        "prompt": "Home",
      },
      {
        "name": "searchForm",
        "description" : "Search for content",
        "type": "safe",
        "action": "read",
        "kind": "search",
        "target": "list form",
        "prompt": "Search",
        "inputs": [
          {
            "name": "text",
            "prompt": "Search Text",
            "value": "Danny",
            "required" : true
          },
          {
            "name": "external",
            "prompt": "External Search?",
            "value": "",
            "required: true,
            "suggest": [{"value":"true"},{"value":"false"}]
          }
        }
      }
    ],
    "data": [
      {
        "id": "1a14qx7qc81",
        "title": "Danny Boy"
      },
      {
        "id": "1q2w3e43r",
        "title": "Danny Tremane"
      },
      {
        "id": "azsxdcfvgb",
        "title": "Danny Two-Shoes"
      },

    ]
  }
}

Note the transition that represents the execute-able FORM contains the last search value (this is not a requirement, just a nice touch). Also note the data section that represents the data records found in the last search execution. Finally, you may notice that the searchLink transition is missing in this runtime instance of the WeSTL document. The service has apparently decided that there is no need for this link since the current resouce context includes an instance of the search form already.

Extending WeSTL Documents

Any WeSTL document can be extended in both the design-time and runtime modes. The only rules that MUST be followed are:

  1. You MUST NOT remove any existing properties or objects listed in the WeSTL specification.

  2. You MUST NOT change the meaning or use of any existing properties or objects listed in the WeSTL specification.

  3. You MAY add new properties and objects as long as they do not cause existing compliant WeSTL document parsers to fail.

Enclosing Your Extensions

You SHOULD add new features in WeSTL documents in a way that reduces the likelihood that future changes to the standard format as well as extensions from other document authors will cause a conflict with your extensions. Typically, this means using a unique name for an enclosing object to hold all your extensions.

For example, the following shows how to safely add the rolloverText extension by enclosing it in a unique identifying object named "amundsen":

"actions": [
  {
    "name": "homeLink",
    "type": "safe",
    "action": "read",
    "kind": "",
    "target": "list menu",
    "prompt": "Home",
    "amundsen" : {
      "rolloverText" : "Go to the Home page."
    }
  },

This opens a wide set of possibilities for extending WeSTL documents.

References

Below are the references used in this document.

Acknowledgements

The authors would like to thank everyone who commented upon, encouraged, and gave feedback to this specification, especially Ronnie Mitra, Stephen Mizell, Iralki Nadareishvili.