In the context of the Web of Things (WoT), a Binding Template is a blueprint that gives guidance on how to implement a specific IoT protocol, data format or IoT platform. The Core Binding Templates specification explains the overall mechanism and requirements for any binding to follow. This document gives implementation guidelines regarding the Constrained Application Protocol (CoAP), which is a specialized web transfer protocol for use with constrained nodes and constrained (e.g., low-power, lossy) networks.
More specifically, this document defines a set of vocabulary terms that can be used inside a Thing Description document, and associated rules which allow to describe WoT operations using CoAP over the network. Additionally, relevant examples are provided to showcase different vocabulary terms and the associated behavior.
This document is a work in progress
The Constrained Application Protocol (CoAP) [[RFC7252]] is a specialized web transfer protocol for use with constrained nodes and constrained (e.g., low-power, lossy) networks. The nodes often have 8-bit microcontrollers with small amounts of ROM and RAM, while constrained networks such as IPv6 over Low-Power Wireless Personal Area Networks (6LoWPANs) often have high packet error rates and a typical throughput of 10s of kbit/s. The protocol is designed for machine-to-machine (M2M) applications such as smart energy and building automation.
This document describes how to present devices that use CoAP in a Thing Description. In particular, the document explain how to create valid Forms for the different operations that CoAP can perform.
Forms of a Thing Description instance with CoAP Binding complies with this specification if it follows the normative statements in and .
A JSON Schema [[?JSON-SCHEMA]] to validate Thing Description instances containing CoAP Binding is provided in the GitHub repository.
The interaction model of CoAP [[RFC7252]] is similar to the client/server model of HTTP [[RFC7230]]: A CoAP client sends requests to a CoAP server and receives responses. Requests indicate the action to be performed (e.g., GET, POST, PUT, DELETE) by means of a CoAP method code. Responses carry a CoAP status code that indicates success or failure. Requests and response may carry a representation in a CoAP content format (i.e., content type with optional content coding).
The parameters and metadata of requests and responses are carried in CoAP options.
CoAP defines a set of common options (e.g., URI path and query components, Accept and Content-Format) and allows new options to be defined.
Options are generally set when using certain CoAP features, such as the Observe
option being set when Observing Resources in CoAP [[RFC7641]].
The following sections provide an overview of the CoAP features defined at the time of writing and give examples of a how these can be used in a [[[WOT-THING-DESCRIPTION]]]. The vocabulary terms used in these examples are defined in section [[[#vocabulary]]].
Things accessible via CoAP provide interaction affordances that direct Consumers to send CoAP requests to a CoAP endpoint. The Thing processes these requests and sends appropriate CoAP responses.
The target resource is specified in the Thing Description by the href
member of a form, using one of the CoAP URI schemes (see section [[[#url]]]).
The request method (e.g., "GET"
, "PUT"
, "POST"
, or "DELETE"
) is specified using the cov:method
member of a form.
{ "@context": "https://www.w3.org/2022/wot/td/v1.1", ... "properties": { "status": { "type": "string", "readOnly": true, "forms": [{ "cov:method": "GET", "href": "coap://[2001:DB8::1]/status", "contentType": "text/plain;charset=utf-8", "op": ["readproperty"] }] } } }
The cov:method
member may be omitted if the request method is the default for the operation (see section [[[#default-mappings]]]).
{ "@context": "https://www.w3.org/2022/wot/td/v1.1", ... "properties": { "status": { "type": "string", "readOnly": true, "forms": [{ "href": "coap://[2001:DB8::1]/status", "contentType": "text/plain;charset=utf-8" }] } } }
The contentType
and contentCoding
members of a form specify the CoAP content format of the request and/or response.
In CoAP, combinations of content type and content coding are encoded using standardized values listed in the IANA CoAP Content-Formats registry.
Therefore, not every combination of content type and content coding can be used with CoAP.
Furthermore, even parameters are included in the mapping: in [[[#example-request-defaults]]], the content type text/plain;charset=utf-8
would be mapped to Content-Format ID 0.
Omitting the charset
parameter, for instance, would break a literal mapping from content type to Content-Format in this case.
Section [[[#content-negotiation]]] introduces the additional vocabulary terms cov:contentFormat
and cov:accept
to deal with ambiguities of content types and content codings in the context of CoAP, and to give Consumers guidance for the content negotiation process.
Content negotiation in CoAP is used to negotiate the representation of CoAP resources that may have different representations available.
Content negotiation is accomplished through the use of CoAP Accept
and Content-Format
options.
The CoAP Accept option is used by clients to request a particular content format, while the Content-Format
option is used by clients and servers to indicate the content format of the representation in requests and responses, respectively.
Mapping the string-based contentType
and contentCoding
fields to a numeric Content-Format can be difficult for a Consumer for a number of reasons:
First, a Consumer needs to be aware of all potential mappings between the string-based and the numerical representations.
Furthermore, since there is no well-defined algorithm for converting a combination of contentType
and contentCoding
to a CoAP Content-Format, the process might be prone to error.
Therefore, this document introduces the vocabulary term cov:contentFormat
for providing a hint to simplify the conversion for a Consumer.
It can be used in all Thing Description classes that contain the contentType
and contentCoding
fields.
If the field cov:contentFormat
is present, it must match the string representation expressed by contentType
and contentCoding
.
Corresponding with the default contentType
value application/json
, Consumers are supposed to assume a Content-Format value 50 if cov:contentFormat
and application/json
is not present.
Forms may contain a cov:accept
field to explicitly require a Consumer to provide an Accept option.
If a cov:accept
member is present in a Form, then the Consumer must use the contained value in an Accept option when requesting the described resource.
In the case of the following example, a Consumer trying to invoke the start
Action would include a Content-Format
option with value 50 (application/json
) and an Accept
option with value 60 (application/cbor
) in its request when choosing the first Form provided.
Since both forms have the same href
, use of Accept
option allows the Consumer to choose the correct form.
{ "@context": "https://www.w3.org/2022/wot/td/v1.1", ... "actions": { "start": { "input": { "type": "integer" }, "output": { "type": "string" }, "forms": [ { "href": "coap://[2001:DB8::1]/start", "cov:accept": 60, "response": { "contentType": "application/cbor", "cov:contentFormat": 60 } }, { "href": "coap://[2001:DB8::1]/start", "contentType": "application/cbor", "cov:contentFormat": 60, "cov:accept": 50, "response": { "contentType": "application/json", "cov:contentFormat": 50 } } ] } } }
CoAP features two mechanisms to make efficient use of network resources and minimize the number of required transmissions. First, a CoAP client may store responses to requests in order to satisfy future requests without sending a new request. A stored response may be used if it is still valid, i.e., if the response's Max-Age value has not been exceeded. Second, a CoAP client may validate a stored response by sending a new request with the ETag from the stored response. This allows the server to quickly respond with a 2.03 (Valid) response if the stored response is still valid.
Consumers are generally is expected to make use of both mechanisms to minimize the number of required CoAP transmissions.
CoAP provides a mechanism for clients to "observe" resources [[RFC7641]], i.e., to request notifications from the server whenever the resource changes. This is especially useful in the Web of Things where many Things are expected to have resources that change over time, such as sensor readings.
A resource can be observed by sending a GET request with the Observe option set. The server will then respond with the current representation of the resource, as well as send notifications to the client. A server is not required to support the Observe option for all resources; in this case, a resource can still be observed by polling it at regular intervals.
Support for observing resources can be indicating by including a subprotocol
value of cov:observe
in a form.
However, a consumer can always fall back to polling a resource if observing a resource is permanently or temporarily not possible.
{ "@context": "https://www.w3.org/2022/wot/td/v1.1", ... "properties": { "status": { "type": "string", "readOnly": true, "forms": [{ "cov:method": "GET", "href": "coap://[2001:DB8::1]/status", "contentType": "text/plain;charset=utf-8", "subprotocol": "cov:observe", "op": ["observeproperty"] }] } } }
CoAP supports block-wise transfers to allow large resource representations to be transferred between clients and servers. This feature enables clients and servers to request or provide resource representations in smaller blocks, which can be useful when constrained network conditions make it undesirable to transfer large amounts of data at once.
At the time of writing, CoAP supports two mechanisms for block-wise transfers:
Block-Wise Transfers [[RFC7959]] and Block-Wise Transfer Options Supporting Robust Transmission [[RFC9177]].
In a form, support for these can be indicated by a cov:blockwise
or cov:quickblockwise
member, respectively.
{ "@context": "https://www.w3.org/2022/wot/td/v1.1", ... "properties": { "status": { "type": "string", "readOnly": true, "forms": [{ "href": "coap://[2001:DB8::1]/status", "contentType": "text/plain;charset=utf-8", "cov:blockwise": { } }] } } }
Additionally, a cov:blockwise
or cov:quickblockwise
member may indicate relevant parameters, such as the largest block size that may be used in a Block2
Option.
{ "@context": "https://www.w3.org/2022/wot/td/v1.1", ... "properties": { "status": { "type": "string", "readOnly": true, "forms": [{ "href": "coap://[2001:DB8::1]/status", "contentType": "text/plain;charset=utf-8", "cov:blockwise": { "cov:block2Size": 64 } }] } } }
With conditional requests, a CoAP client can include conditions in a request that specify how the server should process the request. If the server cannot satisfy the conditions, it returns a 4.12 (Precondition Failed) response.
At the time of writing, CoAP supports three types of conditional requests:
If-Match
option with an ETag: "only process the request if the target resource exists and has a representation with this ETag"If-Match
option without an ETag: "only process the request if the target resource exists"If-None-Match
option without an ETag: "only process the request if the target resource does not exist"Conditional requests are typically used in the context of larger, multi-step workflows. For example, a CoAP client might want to make sure that a resource has not been modified before it performs some action on it. Therefore, no vocabulary is provided for driving conditional requests from the Thing Description. Instead, consumers are expected to be familiar with the specifics of the workflows in which they are participating and to use conditional requests accordingly.
The CoAP Hop-Limit
option [[RFC8768]] limits the number of hops a CoAP message can take before it is considered undeliverable. This prevents infinite message loops in CoAP networks.
In a form, the cov:hopLimit
member can be used to set the desired hop limit for a particular CoAP request.
{ "@context": "https://www.w3.org/2022/wot/td/v1.1", ... "properties": { "status": { "type": "string", "readOnly": true, "forms": [{ "href": "coap://[2001:DB8::1]/status", "contentType": "text/plain;charset=utf-8", "cov:hopLimit": 5 }] } } }
CoAP uses the following Uniform Resource Identifier (URI) schemes for identifying CoAP resources and providing a means of locating the resource:
URI Scheme | Reference |
---|---|
coap | [[RFC7252]] |
coap+tcp | [[RFC8323]] |
coap+ws | [[RFC8323]] |
coaps | [[RFC7252]] |
coaps+tcp | [[RFC8323]] |
coaps+ws | [[RFC8323]] |
See the Uniform Resource Identifier (URI) Schemes registry for the complete list of CoAP URI schemes.
This section describes the vocabulary used in CoAP. A protocol binding implementation should use the vocabulary defined in this section to describe the different configuration that can be used to exchanged data between Web of Things.
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
cov:method |
Indicates the CoAP method to be used in the request. | optional |
string (e.g., GET , PUT , POST , DELETE , FETCH , iPATCH , or PATCH )(See the CoAP Method Codes registry for the set of possible values.) |
cov:blockwise |
Indicates that block-wise transfer [[RFC7959]] is supported. | optional | BlockWiseTransferParameters |
cov:qblockwise |
Indicates that quick block-wise transfer [[RFC9177]] is supported. | optional | BlockWiseTransferParameters |
cov:hopLimit |
Indicates that a CoAP Hop-Limit option [[RFC8768]] should be included in the request. | optional | unsignedByte |
cov:contentFormat |
Specifies the Content-Format to be used by a client for input data and the Content-Format to be used by a server for output data (where applicable). The value must be the numeric Content-Format ID registered with IANA for the combination of the contentType and contentCoding specified in the same form.
|
optional | unsignedShort |
cov:accept |
Indicates that a Consumer must include an Accept option [[RFC7252]] with the given value when requesting the resource associated with this Form. | optional | unsignedShort |
The following vocabulary terms are usable in the ExpectedResponse
and AdditionalExpectedResponse
classes.
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
cov:contentFormat |
Specifies the Content-Format to be used by a client for input data and the Content-Format to be used by a server for output data (where applicable). The value must be the numeric Content-Format ID registered with IANA for the combination of the contentType and contentCoding specified in the same form.
|
optional | unsignedShort |
Vocabulary term | Description | Assignment | Type |
---|---|---|---|
cov:block2Size
|
Indicates the largest block size that may be used in a Block2 or Q-Block2 Option | optional |
unsignedShort (one of 16 , 32 , 64 , 128 , 256 , 512 , or 1024 )
|
cov:block1Size
|
Indicates the largest block size that may be used in a Block1 or Q-Block1 Option | optional |
unsignedShort (one of 16 , 32 , 64 , 128 , 256 , 512 , or 1024 )
|
This section describes the strategies and default values to use protocol specific concepts within the WoT Interaction model.
Operation | Default Binding |
---|---|
readproperty |
"cov:method": "GET" |
writeproperty |
"cov:method": "PUT" |
observeproperty |
"cov:method": "GET" , "subprotocol": "cov:observe" |
unobserveproperty |
"cov:method": "GET" , "subprotocol": "cov:observe" |
readmultipleproperties |
"cov:method": "GET" |
writemultipleproperties |
"cov:method": "PUT" |
readallproperties |
"cov:method": "GET" |
writeallproperties |
"cov:method": "PUT" |
observeallproperties |
"cov:method": "GET" , "subprotocol": "cov:observe" |
unobserveallproperties |
"cov:method": "GET" , "subprotocol": "cov:observe" |
invokeaction |
"cov:method": "POST" |
queryaction |
"cov:method": "GET" |
cancelaction |
"cov:method": "POST" |
queryallactions |
"cov:method": "GET" |
subscribeevent |
"cov:method": "GET" , "subprotocol": "cov:observe" |
unsubscribeevent |
"cov:method": "GET" , "subprotocol": "cov:observe" |
subscribeallevents |
"cov:method": "GET" , "subprotocol": "cov:observe" |
unsubscribeallevents |
"cov:method": "GET" , "subprotocol": "cov:observe" |
TODO: This section should describe other mappings that can be used by TD designers. It is meant to be informative but it provides guidelines for implementers.