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.

Introduction

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.

This document is a work in progress

Protocol Overview

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]]].

Requests/Responses

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. Consumers are expected to be able to map the combinations of content type and content coding they understand to the corresponding CoAP content format IDs listed in the IANA CoAP Content-Formats registry. Producers are advised to only use combinations of content types and content codings in CoAP forms that have such a content format ID available.

Content Negotiation

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.

The ... can be used to provide a list of one or more content formats that the Thing is able to provide in a CoAP response for the operation. The Consumer selects the most suitable one and sets the Accept option in the request accordingly.

{
    ...
}

The ... can be used to provide a list of one or more content formats that the Thing is willing to accept in a CoAP request for the operation. The Consumer selects the most suitable one and sets the Content-Format option in the request accordingly.

{
    ...
}

Caching

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.

Observing Resources

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"]
            }]
        }
    }
}

Block-wise Transfers

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:block2SZX": 64
                }
            }]
        }
    }
}

Conditional Requests

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:

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.

Hop Limit

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
            }]
        }
    }
}

URI Schemes

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.

CoAP Vocabulary

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.

Form terms

Vocabulary term Description Assignment Type
cov:method Indicates the CoAP method to be used in the request optional string

(see the CoAP Method Codes registry for the set of possible values)

cov:blockwise Indicates that a block-wise transfer [[RFC7959]] is supported optional BlockWiseTransferParameters
cov:qblockwise Indicates that a quick block-wise transfer [[RFC9177]] is supported optional BlockWiseTransferParameters
cov:hopLimit Indicates that a CoAP Hop-Limit option [[RFC8768]] be included in the request optional unsignedByte

BlockWiseTransferParameters

Vocabulary term Description Assignment Type
cov:block2SZX 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, 1024)

cov:block1SZX 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, 1024)

Mappings

This section describes the strategies and default values to use protocol specific concepts within the WoT Interaction model.

Default mappings

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"

Possible mappings

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.