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
- 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:
-
Provide an easy way for service developers to focus on state transitions
-
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 ofaction
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 validcontent
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. Thedata
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
orunsafe
. -
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 oftext
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 thetext
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
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
orfalse
. If this property is missing or is set to an unknown value, it SHOULD be treated as if it is set tofalse
. -
required
-
A flag to indicate this value is an required input. If it exists, its value MUST be set to
true
orfalse
. If this property is missing or is set to ann unknown value, it SHOULD be treated as if it is set tofalse
. -
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) andselect
(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. Thesuggest
object somes in two forms: 1) an array of values (see Suggest Arrays) or 2) a reference torelated
data (see Suggest Related Data). It is up to the rendering engine to decide how to handle each form ofsuggest
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.
Suggest Related Data
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 therelated
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 therelated
section of the document, then thissuggest
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 therelated
section list, then thissuggest
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 therelated
section list, then thissuggest
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:
-
The one that leads to the home page (
homeLink
) -
The one that leads to the search form (
searchLink
) -
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:
-
You MUST NOT remove any existing properties or objects listed in the WeSTL specification.
-
You MUST NOT change the meaning or use of any existing properties or objects listed in the WeSTL specification.
-
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.
-
[RWCBook] Amundsen, M., "RESTful Web Clients", January 2017, http://g.mamund.com/rwcbook
-
[REPO] Github, "Web Service Transition Language", https://github.com/RWCBook/wstl-spec
-
[RFC2119] Bradner, S.,"Key words for use in RFCs to Indicate Requirement Levels", March 1997, http://tools.ietf.org/html/rfc2119
-
[RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter,"Uniform Resource Identifier (URI): Generic Syntax", January 2005, http://tools.ietf.org/html/rfc3986
-
[RFC4627] D. Crockford, "The application/json Media Type for JavaScript Object Notation (JSON)", July 2006, http://tools.ietf.org/html/rfc4627
-
[RFC5988] Nottingham, M., "Web Linking", October 2010, http://tools.ietf.org/html/rfc5988
-
[RFC6570] Gregorio, J., Fielding, R., Hadley, M., Nottingham, M., Orchard, D., "URI Template", March 2012, http://tools.ietf.org/html/rfc6570
-
[HTMLPattern] WHATWG & W3C et. al., "HTML5 - The
pattern
Attribute", http://www.w3.org/TR/html5/forms.html#the-pattern-attribute
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.