RFC 8040
RESTCONF Protocol
RFC 8040: RESTCONF Protocol 🎀
bestie, this one is the RESTCONF Protocol spec, and it's giving "HTTP meets YANG" ✨. It was published in January 2017 as a Standards Track document, which means it's an official Internet standard, not just an opinion piece 💅. The IETF put it out, and it's ISSN 2070-1721 🌸.
The authors are A. Bierman (YumaWorks), M. Bjorklund (Tail-f Systems), and K. Watsen (Juniper Networks) 🫶. They're the squad that made it 💖.
Abstract 📖
okay so the big idea is this: RESTCONF is an HTTP-based protocol that gives you a programmatic interface for reaching data that's defined in YANG 🦋. It borrows the datastore concepts from NETCONF (the Network Configuration Protocol), so if you already know NETCONF, you'll feel right at home 🏡. Main character energy 👑.
Status of This Memo 🗂️
this part is the official paperwork, but it's still cute 🙈. It's an Internet Standards Track document 🌈.
It's a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community, meaning lots of people agreed on it 🍓. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG) ✨. If you want more info about Internet Standards, check Section 2 of RFC 7841 📚.
Info about the current status, any errata, and how to send feedback lives at http://www.rfc-editor.org/info/rfc8040 💌.
Copyright Notice ©️
the legal bit, served with a little sparkle 💅. It's Copyright (c) 2017 IETF Trust and the persons identified as the document authors, and all rights reserved 🔒.
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents, which you can find at http://trustee.ietf.org/license-info as they stood on the publication date 📜. Please actually read those, because they explain your rights and restrictions for this document 🙏.
One important catch: any Code Components you pull out of this document have to include the Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions, and they come with no warranty, as described in the Simplified BSD License 🧾.
Table of Contents 🧭
this is the full map of the whole spec, so you can see where everything lives 🗺️.
1. Introduction ....................................................5
1.1. Terminology ................................................5
1.1.1. NETCONF .............................................6
1.1.2. HTTP ................................................6
1.1.3. YANG ................................................7
1.1.4. NETCONF Notifications ...............................7
1.1.5. Terms ...............................................8
1.1.6. URI Template and Examples ..........................10
1.1.7. Tree Diagrams ......................................11
1.2. Subset of NETCONF Functionality ...........................11
1.3. Data-Model-Driven API .....................................12
1.4. Coexistence with NETCONF ..................................13
1.5. RESTCONF Extensibility ....................................14
2. Transport Protocol .............................................15
2.1. Integrity and Confidentiality .............................15
2.2. HTTPS with X.509v3 Certificates ...........................16
2.3. Certificate Validation ....................................16
2.4. Authenticated Server Identity .............................16
2.5. Authenticated Client Identity .............................16
3. Resources ......................................................17
3.1. Root Resource Discovery ...................................18
3.2. RESTCONF Media Types ......................................20
3.3. API Resource ..............................................20
3.3.1. {+restconf}/data ...................................21
3.3.2. {+restconf}/operations .............................22
3.3.3. {+restconf}/yang-library-version ...................22
3.4. Datastore Resource ........................................23
3.4.1. Edit Collision Prevention ..........................23
3.5. Data Resource .............................................24
3.5.1. Timestamp ..........................................25
3.5.2. Entity-Tag .........................................25
3.5.3. Encoding Data Resource Identifiers in the
Request URI ........................................26
3.5.4. Default Handling ...................................29
3.6. Operation Resource ........................................30
3.6.1. Encoding Operation Resource Input Parameters .......31
3.6.2. Encoding Operation Resource Output Parameters ......36
3.6.3. Encoding Operation Resource Errors .................38
3.7. Schema Resource ...........................................40
3.8. Event Stream Resource .....................................41
3.9. "errors" YANG Data Template ...............................41
4. RESTCONF Methods ...............................................42
4.1. OPTIONS ...................................................43
4.2. HEAD ......................................................43
4.3. GET .......................................................43
4.4. POST ......................................................45
4.4.1. Create Resource Mode ...............................45
4.4.2. Invoke Operation Mode ..............................47
4.5. PUT .......................................................48
4.6. PATCH .....................................................50
4.6.1. Plain Patch ........................................50
4.7. DELETE ....................................................51
4.8. Query Parameters ..........................................52
4.8.1. The "content" Query Parameter ......................54
4.8.2. The "depth" Query Parameter ........................54
4.8.3. The "fields" Query Parameter .......................55
4.8.4. The "filter" Query Parameter .......................56
4.8.5. The "insert" Query Parameter .......................57
4.8.6. The "point" Query Parameter ........................57
4.8.7. The "start-time" Query Parameter ...................58
4.8.8. The "stop-time" Query Parameter ....................58
4.8.9. The "with-defaults" Query Parameter ................59
5. Messages .......................................................60
5.1. Request URI Structure .....................................61
5.2. Message Encoding ..........................................62
5.3. RESTCONF Metadata .........................................63
5.3.1. XML Metadata Encoding Example ......................64
5.3.2. JSON Metadata Encoding Example .....................65
5.4. Return Status .............................................65
5.5. Message Caching ...........................................66
6. Notifications ..................................................66
6.1. Server Support ............................................66
6.2. Event Streams .............................................67
6.3. Subscribing to Receive Notifications ......................68
6.3.1. NETCONF Event Stream ...............................70
6.4. Receiving Event Notifications .............................70
7. Error Reporting ................................................73
7.1. Error Response Message ....................................75
8. RESTCONF Module ................................................79
9. RESTCONF Monitoring ............................................85
9.1. restconf-state/capabilities ...............................86
9.1.1. Query Parameter URIs ...............................87
9.1.2. The "defaults" Protocol Capability URI .............87
9.2. restconf-state/streams ....................................88
9.3. RESTCONF Monitoring Module ................................89
10. YANG Module Library ...........................................93
10.1. modules-state/module .....................................93
11. IANA Considerations ...........................................94
11.1. The "restconf" Relation Type .............................94
11.2. Registrations for New URIs and YANG Modules ..............94
11.3. Media Types ..............................................95
11.3.1. Media Type "application/yang-data+xml" ............95
11.3.2. Media Type "application/yang-data+json" ...........96
11.4. RESTCONF Capability URNs .................................97
11.5. Registration of "restconf" URN Sub-namespace .............98
12. Security Considerations .......................................99
13. References ...................................................100
13.1. Normative References ....................................100
13.2. Informative References ..................................104
Appendix A. Example YANG Module ..................................105
A.1. "example-jukebox" YANG Module .............................106
Appendix B. RESTCONF Message Examples ............................112
B.1. Resource Retrieval Examples ...............................112
B.1.1. Retrieve the Top-Level API Resource ...................112
B.1.2. Retrieve the Server Module Information ................114
B.1.3. Retrieve the Server Capability Information ............117
B.2. Data Resource and Datastore Resource Examples .............118
B.2.1. Create New Data Resources .............................118
B.2.2. Detect Datastore Resource Entity-Tag Change ...........119
B.2.3. Edit a Datastore Resource .............................121
B.2.4. Replace a Datastore Resource ..........................122
B.2.5. Edit a Data Resource ..................................122
B.3. Query Parameter Examples ..................................123
B.3.1. "content" Parameter ...................................123
B.3.2. "depth" Parameter .....................................126
B.3.3. "fields" Parameter ....................................130
B.3.4. "insert" Parameter ....................................132
B.3.5. "point" Parameter .....................................133
B.3.6. "filter" Parameter ....................................134
B.3.7. "start-time" Parameter ................................134
B.3.8. "stop-time" Parameter .................................135
B.3.9. "with-defaults" Parameter .............................135
Acknowledgements .................................................137
Authors' Addresses ...............................................137
1. Introduction ✨
okay bestie, so the big problem is that Web apps need a standard way to poke at a networking device's configuration data, its state data, its data-model-specific RPC operations, and its event notifications. It has to be modular and extensible too, no messy one-off hacks 💅
This document defines a protocol called "RESTCONF" 🎀 It's built on top of HTTP [RFC7230] and it's for configuring data defined in YANG version 1 [RFC6020] or YANG version 1.1 [RFC7950]. It borrows the datastore concepts from the Network Configuration Protocol (NETCONF) [RFC6241], so the vibes are very consistent with NETCONF 🧚
NETCONF gives you configuration datastores and a set of Create, Read, Update, Delete (CRUD) operations for getting at them. It also has its own way of invoking those operations. YANG is the language that describes the syntax and semantics of datastore content, configuration, state data, RPC operations, and event notifications. So YANG is basically the rulebook 📖
RESTCONF uses HTTP methods to do CRUD operations on a conceptual datastore full of YANG-defined data. It's designed to be compatible with a server that already implements NETCONF datastores, which is honestly so smart 🌸
If a RESTCONF server lives alongside a NETCONF server, then the two talk to each other. Those interactions are described in Section 1.4 🫶 The RESTCONF server MAY expose specific datastores through operation resources, as described in Section 3.6. RESTCONF doesn't require any operation resources, so none of them are mandatory. What an operation resource does, and whether it touches datastores at all, is decided by its own semantics 🦋
Configuration data and state data show up as resources you can fetch with the GET method. Resources that hold configuration data can be changed with the DELETE, PATCH, POST, and PUT methods. The data itself is encoded as either XML [W3C.REC-xml-20081126] or JSON [RFC7159] 💜
YANG-defined RPC operations (the ones declared with the "rpc" or "action" statements) get invoked with POST. YANG-defined event notifications (declared with the "notification" statement) can be accessed too ✨
1.1. Terminology
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 [RFC2119]. 🧠
1.1.1. NETCONF
These terms are defined in [RFC6241] 💖
- candidate configuration datastore
- configuration data
- datastore
- configuration datastore
- running configuration datastore
- startup configuration datastore
- state data
- user
1.1.2. HTTP
These terms are defined in [RFC3986] 🌈
- fragment
- path
- query
These terms are defined in [RFC7230] 🍓
- header field
- message-body
- request-line
- request URI
- status-line
These terms are defined in [RFC7231] 🌸
- method
- request
- resource
This term is defined in [RFC7232] 🦋
- entity-tag
1.1.3. YANG
These terms are defined in [RFC7950] 👑
- action
- container
- data node
- key leaf
- leaf
- leaf-list
- list
- mandatory node
- ordered-by user
- presence container
- RPC operation
- top-level data node
1.1.4. NETCONF Notifications
This term is defined in [RFC5277] 🔥
- notification replay
1.1.5. Terms
These terms are used throughout this document, so let's get them straight 💅
- API resource: the resource that models the RESTCONF root resource and the sub-resources used to access YANG-defined content. It is defined with the YANG data template named
yang-apiin theietf-restconfmodule. - client: a RESTCONF client.
- data resource: a resource that models a YANG data node. It is defined with YANG data definition statements.
- datastore resource: the resource that models a programmatic interface using NETCONF datastore concepts. By default, RESTCONF methods access a unified view of the underlying datastore implementation on the server. It is defined as a sub-resource within the API resource.
- edit operation: a RESTCONF operation on a data resource using either a POST, PUT, PATCH, or DELETE method. This is NOT the same thing as the NETCONF edit operation, which is one of the values for the
nc:operationattribute:create,replace,merge,delete, orremove. Easy to mix up, so watch out 👀 - event stream resource: a resource that represents an SSE (Server-Sent Events) event stream. The content is text using the media type
text/event-stream, as defined by the SSE specification [W3C.REC-eventsource-20150203]. Event stream contents are described in Section 3.8. - media type: HTTP uses Internet media types [RFC2046] in the
Content-TypeandAcceptheader fields, which gives you open, extensible data typing and type negotiation 🎀 - NETCONF client: a client that implements the NETCONF protocol. Called "client" in [RFC6241].
- NETCONF server: a server that implements the NETCONF protocol. Called "server" in [RFC6241].
- operation: the conceptual RESTCONF operation for a message. It's derived from the HTTP method, request URI, header fields, and message-body.
- operation resource: a resource that models a data-model-specific operation, which is itself defined with a YANG
rpcoractionstatement. It's invoked with the POST method. - patch: a PATCH method on the target datastore or data resource. The media type of the message-body content tells you which patch type is in use.
- plain patch: a specific media type for use with the PATCH method; see Section 4.6.1. It can be used for simple
mergeedit operations. It's specified by a requestContent-Typeofapplication/yang-data+xmlorapplication/yang-data+json🍓 - query parameter: a parameter (and its value, if it has one), encoded within the query component of the request URI.
- resource type: one of the RESTCONF resource classes defined in this document. The options are
api,datastore,data,operation,schema, orevent stream. - RESTCONF capability: an optional RESTCONF protocol feature that a particular server advertises if it supports that feature. The feature is identified by an IANA-registered NETCONF Capability URI and advertised with an entry in the
capabilityleaf-list defined in Section 9.3. - RESTCONF client: a client that implements the RESTCONF protocol.
- RESTCONF server: a server that implements the RESTCONF protocol.
- retrieval request: a request using the GET or HEAD methods.
- schema resource: a resource the client uses to retrieve a YANG schema with the GET method. It has a representation with the media type
application/yang. - server: a RESTCONF server.
streamlist: the set of data resource instances that describe the event stream resources available from the server. This info is defined in theietf-restconf-monitoringmodule as thestreamlist. You can retrieve it using the target resource{+restconf}/data/ietf-restconf-monitoring:restconf-state/streams/stream. Thestreamlist has details about each stream, like the URL you use to grab the event stream data 🌈- stream resource: an event stream resource.
- target resource: the resource associated with a particular message, identified by the
pathcomponent of the request URI. - yang-data extension: a YANG external statement that conforms to the
yang-dataextension statement, found in Section 8. The yang-data extension is used to define YANG data structures meant to be used as YANG data templates. These structures are NOT meant to be implemented as part of a configuration datastore or as operational state within the server, which is why normal YANG data definition statements can't be used for them 🙈 - YANG data template: a schema for modeling protocol message components as conceptual data structures using YANG. This lets the messages be defined in an encoding-independent way. Each YANG data template is defined with the
yang-dataextension, found in Section 8. Representations of instances that conform to a particular YANG data template can be defined for YANG. The XML representation is defined in YANG version 1.1 [RFC7950] and supported with theapplication/yang-data+xmlmedia type. The JSON representation is defined in "JSON Encoding of Data Modeled with YANG" [RFC7951] and supported with theapplication/yang-data+jsonmedia type 💜
1.1.6. URI Template and Examples
Throughout this document, the URI template [RFC6570] syntax {+restconf} is used to refer to the RESTCONF root resource outside of an example. See Section 3.1 for details 🦋
For simplicity, every example in this document uses /restconf as the discovered RESTCONF API root path. A lot of the examples are based on the example-jukebox YANG module defined in Appendix A.1 🎶
A lot of protocol header lines and message-body text in the examples are split across multiple lines purely for display. When a line ends with a backslash (\) as its last character, that line was wrapped just for display. You treat it as joined to the next line by deleting the backslash, the line break after it, and the leading whitespace on the next line 🧩
Heads up: that backslash rule only applies to the wrapped examples, so don't go deleting backslashes out of the actual content.
1.1.7. Tree Diagrams
This document uses a simplified graphical view of the data model. Here's what the symbols mean 🌸
- Brackets
[and]enclose list keys. - Abbreviations before data node names:
rwmeans configuration data (read-write),romeans state data (read-only), andxmeans operation resource (executable). - Symbols after data node names:
?means an optional node,!means a presence container, and*denotes a list and leaf-list. - Parentheses enclose choice and case nodes, and case nodes are also marked with a colon (
:). - An ellipsis (
...) stands for the contents of subtrees that aren't shown.
1.2. Subset of NETCONF Functionality
RESTCONF doesn't need to copy every single bit of NETCONF, but it DOES need to stay compatible with it 🫶 The trick is that RESTCONF only implements a subset of NETCONF's interaction capabilities. For example, it drops datastores and explicit locking entirely 🔐
RESTCONF uses HTTP methods to implement the equivalent of NETCONF operations, so you get basic CRUD operations on a hierarchy of conceptual resources. It's giving organized 🗂️
The HTTP POST, PUT, PATCH, and DELETE methods are used to edit data resources modeled by YANG data models. These basic edit operations let a RESTCONF client change the running configuration 🍓
RESTCONF is NOT meant to replace NETCONF. Instead, it gives you an HTTP interface that follows Representational State Transfer (REST) principles [REST-Dissertation] and stays compatible with the NETCONF datastore model. Main character energy for sure 👑
1.3. Data-Model-Driven API ✨
okay so RESTCONF is giving the best of both worlds 🧚 It has the simplicity of HTTP plus the predictability and automation potential of a schema-driven API. If you know the YANG modules the server uses, you can work out every management resource URL and the exact structure of every RESTCONF request and response 💅 That means the server doesn't need to stuff its responses with HATEOAS links (Hypermedia as the Engine of Application State, the idea from Roy Fielding's doctoral dissertation [REST-Dissertation]), because the client can figure out the links it needs straight from the YANG modules. no cap, so iconic 😭
RESTCONF uses the YANG library [RFC7895] so a client can discover the YANG module conformance information for the server, if it wants to 🎀
The server can optionally support retrieving the YANG modules it uses, as listed in its YANG library. See Section 3.7 for details 🌸
The URIs for data-model-specific RPC operations and datastore content are predictable, since they're based on the YANG module definitions 🦋
Now the datastore. RESTCONF works on a conceptual datastore defined with the YANG data modeling language. The server lists each YANG module it supports using the ietf-yang-library module defined in [RFC7895]. The server MUST implement the ietf-yang-library module, which MUST identify all of the YANG modules used by the server, in the modules-state/module list. The conceptual datastore contents, data-model-specific RPC operations, and event notifications are all identified by this set of YANG modules 👑
Config vs. state: whether data counts as configuration data or non-configuration data comes from the YANG config statement. How data is ordered comes from the YANG ordered-by statement. Non-configuration data is also called "state data" 🍓
The editing model is simple and direct, kinda like the :writable-running capability in NETCONF. Every RESTCONF edit of a data resource inside the datastore resource gets activated as soon as it finishes successfully ✨
1.4. Coexistence with NETCONF 🫶
RESTCONF can run on a device that already supports the NETCONF protocol.
Here's the setup when a RESTCONF server is co-located with a NETCONF server:
+-----------+ +-----------------+
| Web app | <-------> | |
+-----------+ RESTCONF | network device |
| |
+-----------+ | +-----------+ |
| NETCONF | <-------> | | datastore | |
| Client | NETCONF | | | |
+-----------+ | +-----------+ |
+-----------------+
And here's the setup when the RESTCONF server lives on a device that doesn't have a NETCONF server at all:
+-----------+ +-----------------+
| Web app | <-------> | |
+-----------+ RESTCONF | network device |
| |
+-----------------+
There are interactions between NETCONF and RESTCONF around edit operations 👀 Locks might be in use on a RESTCONF server even though RESTCONF can't manipulate locks. In that case, the RESTCONF protocol will not be granted write access to data resources within a datastore 🔒
If the NETCONF server supports :writable-running, all edits to configuration nodes in {+restconf}/data are performed in the running configuration datastore. The URI template {+restconf} is defined in Section 1.1.6.
Otherwise, if the device supports :candidate, all edits to configuration nodes in {+restconf}/data are performed in the candidate configuration datastore. The candidate MUST be automatically committed to running immediately after each successful edit. Any edits from other sources that are in the candidate datastore will also be committed. If a confirmed commit procedure is in progress by any NETCONF client, then any new commit will act as the confirming commit. If the NETCONF server is expecting a persist-id parameter to complete the confirmed commit procedure, then the RESTCONF edit operation MUST fail with a 409 Conflict status-line. The error-tag in-use is used in this case.
If the NETCONF server supports :startup, the RESTCONF server MUST automatically update the non-volatile startup configuration datastore, after the running datastore has been altered as a consequence of a RESTCONF edit operation ⭐
If a datastore that would be modified by a RESTCONF operation has an active lock from a NETCONF client, the RESTCONF edit operation MUST fail with a 409 Conflict status-line. The error-tag value in-use is returned in this case.
the status is409 Conflictand the error-tag isin-usefor both of those lock and commit situations, so remember it 💀
1.5. RESTCONF Extensibility 🌈
There are two extensibility mechanisms built into RESTCONF:
- protocol version
- optional capabilities
This document defines version 1 of the RESTCONF protocol. If a future version of this protocol is defined, then that document will specify how the new version of RESTCONF is identified. It is expected that a different RESTCONF root resource will be used, which will be located using a different link relation (see Section 3.1).
The server will advertise all protocol versions that it supports in its host-meta data.
In this example, the server supports both RESTCONF version 1 and a fictitious version 2.
The client might send the following:
GET /.well-known/host-meta HTTP/1.1
Host: example.com
Accept: application/xrd+xml
The server might respond as follows:
HTTP/1.1 200 OK
Content-Type: application/xrd+xml
Content-Length: nnn
<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>
<Link rel='restconf' href='/restconf'/>
<Link rel='restconf2' href='/restconf2'/>
</XRD>
RESTCONF also supports a server-defined list of optional capabilities 🦄 A server lists them using the ietf-restconf-monitoring module defined in Section 9.3. This document defines several query parameters in Section 4.8. Each optional parameter has a corresponding capability URI, defined in Section 9.1.1, that is advertised by the server if supported.
The capability leaf-list can identify any sort of server extension. Right now, this extension mechanism is used to identify optional query parameters that are supported, but it isn't limited to that purpose. For example, the defaults URI defined in Section 9.1.2 specifies a mandatory URI identifying server default-handling behavior.
A new sub-resource type could be identified with a capability if it is optional to implement. Mandatory protocol features and new resource types require a new revision of the RESTCONF protocol.
2. Transport Protocol 🚚
2.1. Integrity and Confidentiality 🔐
HTTP [RFC7230] is an application-layer protocol that may be layered on any reliable transport-layer protocol. RESTCONF is defined on top of HTTP, but because of how sensitive the information it carries is, RESTCONF requires that the transport-layer protocol provide both data integrity and confidentiality. A RESTCONF server MUST support the Transport Layer Security (TLS) protocol [RFC5246] and SHOULD adhere to [RFC7525]. The RESTCONF protocol MUST NOT be used over HTTP without using the TLS protocol 🚫
RESTCONF doesn't require a specific version of HTTP. However, it is RECOMMENDED that at least HTTP/1.1 [RFC7230] be supported by all implementations.
2.2. HTTPS with X.509v3 Certificates 🎀
Given the nearly ubiquitous support for HTTP over TLS [RFC7230], RESTCONF implementations MUST support the https URI scheme, which has the IANA-assigned default port 443.
RESTCONF servers MUST present an X.509v3-based certificate when establishing a TLS connection with a RESTCONF client. Using X.509v3-based certificates is consistent with NETCONF over TLS [RFC7589].
2.3. Certificate Validation 🧐
The RESTCONF client MUST either (1) use X.509 certificate path validation [RFC5280] to verify the integrity of the RESTCONF server's TLS certificate or (2) match the server's TLS certificate with a certificate obtained by a trusted mechanism (e.g., a pinned certificate). If X.509 certificate path validation fails and the presented X.509 certificate does not match a certificate obtained by a trusted mechanism, the connection MUST be terminated, as described in Section 7.2.1 of [RFC5246].
2.4. Authenticated Server Identity 🪪
The RESTCONF client MUST check the identity of the server according to Section 3.1 of [RFC2818].
2.5. Authenticated Client Identity 🙈
The RESTCONF server MUST authenticate client access to any protected resource. If the RESTCONF client is not authenticated, the server SHOULD send an HTTP response with a 401 Unauthorized status-line, as defined in Section 3.1 of [RFC7235]. The error-tag value access-denied is used in this case.
To authenticate a client, a RESTCONF server SHOULD require authentication based on TLS client certificates (Section 7.4.6 of [RFC5246]). If certificate-based authentication isn't feasible (e.g., because one cannot build the required PKI for clients), then HTTP authentication MAY be used. In the latter case, one of the HTTP authentication schemes defined in the "Hypertext Transfer Protocol (HTTP) Authentication Scheme Registry" (Section 5.1 in [RFC7235]) MUST be used.
A server MAY also support the combination of both client certificates and an HTTP client authentication scheme, with the determination of how to process this combination left as an implementation decision.
The RESTCONF client identity derived from the authentication mechanism used is from here on known as the "RESTCONF username" and is subject to the NETCONF Access Control Model (NACM) [RFC6536]. When a client certificate is presented, the RESTCONF username MUST be derived using the algorithm defined in Section 7 of [RFC7589]. For all other cases, when HTTP authentication is used, the RESTCONF username MUST be provided by the HTTP authentication scheme used 💖
3. Resources 🎀
okay so RESTCONF runs on a whole hierarchy of resources, starting with the top-level API resource itself (Section 3.1) 🦋 Each resource is a manageable piece of the device.
A resource is basically a bundle of data plus the set of methods that are allowed on that data 💅 It can hold nested child resources, and the child types (and the methods that work on them) depend on the data model.
A resource has a representation tied to a media type identifier, which shows up in the Content-Type header field of the HTTP response. A resource can have one or more representations, each with its own media type. When a representation gets sent in an HTTP message, its media type goes in the Content-Type header. A resource can have zero or more nested resources, and it can be created and deleted on its own, separately from its parent, as long as the parent still exists 🌸
The RESTCONF resources are reached through a set of URIs defined in this document. The YANG modules the server supports decide which data-model-specific RPC operations, top-level data nodes, and event notification messages the server offers 🧚
Also, RESTCONF has no data resource discovery mechanism 🙈 Instead, the definitions in the YANG modules the server advertises are used to build an RPC operation or data resource identifier.
3.1. Root Resource Discovery
Following the best practices in [RFC7320], RESTCONF lets deployments say exactly where the RESTCONF API lives ✨ When a client first connects to a RESTCONF server, it MUST figure out the root of the RESTCONF API. There MUST be exactly one "restconf" link relation returned by the device.
The client finds this by fetching the "/.well-known/host-meta" resource ([RFC6415]) and reading the <Link> element that has the "restconf" attribute:
Example returning /restconf:
The client might send the following:
GET /.well-known/host-meta HTTP/1.1
Host: example.com
Accept: application/xrd+xml
The server might respond as follows:
HTTP/1.1 200 OK
Content-Type: application/xrd+xml
Content-Length: nnn
<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>
<Link rel='restconf' href='/restconf'/>
</XRD>
After discovering the RESTCONF API root, the client MUST use this value as the initial part of the path in the request URI, in any subsequent request for a RESTCONF resource.
In this example, the client would use the path "/restconf" as the RESTCONF root resource.
Example returning /top/restconf:
The client might send the following:
GET /.well-known/host-meta HTTP/1.1
Host: example.com
Accept: application/xrd+xml
The server might respond as follows:
HTTP/1.1 200 OK
Content-Type: application/xrd+xml
Content-Length: nnn
<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>
<Link rel='restconf' href='/top/restconf'/>
</XRD>
In this example, the client would use the path "/top/restconf" as the RESTCONF root resource.
The client can now check which operation resources the server supports. In this example, a custom "play" operation is supported:
The client might send the following:
GET /top/restconf/operations HTTP/1.1
Host: example.com
Accept: application/yang-data+json
The server might respond as follows:
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Cache-Control: no-cache
Last-Modified: Thu, 26 Jan 2017 16:00:14 GMT
Content-Type: application/yang-data+json
{ "operations" : { "example-jukebox:play" : [null] } }
If the Extensible Resource Descriptor (XRD) contains more than one link relation, then only the relation named "restconf" is relevant to this specification.
Note that any given endpoint (host:port) can only support one RESTCONF server, thanks to the root resource discovery mechanism 🍓 That caps how many RESTCONF servers can run at once on a host, since every server needs its own port.
3.2. RESTCONF Media Types
RESTCONF defines two application-specific media types for identifying representations of data that conforms to the schema for a particular YANG construct 💜
This document defines media types for XML and JSON serialization of YANG data. Other documents MAY define other media types for different serializations of YANG data. The "application/yang-data+xml" media type is defined in Section 11.3.1. The "application/yang-data+json" media type is defined in Section 11.3.2.
3.3. API Resource
The API resource holds the RESTCONF root resource for the RESTCONF datastore and operation resources. It's the top-level resource located at {+restconf} and has the media type "application/yang-data+xml" or "application/yang-data+json" ✨
YANG tree diagram for an API resource:
+---- {+restconf}
+---- data
| ...
+---- operations?
| ...
+--ro yang-library-version string
The "yang-api" YANG data template is defined using the "yang-data" extension in the "ietf-restconf" module, found in Section 8. It specifies the structure and syntax of the conceptual child resources within the API resource.
The API resource can be retrieved with the GET method.
The {+restconf} root resource name used in responses representing the root of the "ietf-restconf" module MUST identify the "ietf-restconf" YANG module. For example, a request to GET the root resource "/restconf" in JSON format will return a representation of the API resource named "ietf-restconf:restconf".
This resource has the following child resources:
+----------------------+---------------------------------+
| Child Resource | Description |
+----------------------+---------------------------------+
| data | Contains all data resources |
| operations | Data-model-specific operations |
| yang-library-version | "ietf-yang-library" module date |
+----------------------+---------------------------------+
RESTCONF API Resource
3.3.1. {+restconf}/data
This mandatory resource 🌟 represents the combined configuration and state data resources that a client can access. It cannot be created or deleted by the client. The datastore resource type is defined in Section 3.4.
Example:
This example request by the client would retrieve only the non-configuration data nodes that exist within the "library" resource, using the "content" query parameter (see Section 4.8.1).
GET /restconf/data/example-jukebox:jukebox/library\
?content=nonconfig HTTP/1.1
Host: example.com
Accept: application/yang-data+xml
The server might respond as follows:
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Cache-Control: no-cache
Content-Type: application/yang-data+xml
<library xmlns="https://example.com/ns/example-jukebox">
<artist-count>42</artist-count>
<album-count>59</album-count>
<song-count>374</song-count>
</library>
3.3.2. {+restconf}/operations
This optional resource is a container that gives access to the data-model-specific RPC operations the server supports 🎶 The server MAY omit this resource if no data-model-specific RPC operations are advertised.
Any data-model-specific RPC operations defined in the YANG modules advertised by the server MUST be available as child nodes of this resource.
The access point for each RPC operation is represented as an empty leaf. If an operation resource is retrieved, the server returns the empty leaf representation.
Operation resources are defined in Section 3.6.
3.3.3. {+restconf}/yang-library-version
This mandatory leaf identifies the revision date of the "ietf-yang-library" YANG module that is implemented by this server. In the example that follows, the revision date for the module version found in [RFC7895] is used.
Example:
GET /restconf/yang-library-version HTTP/1.1
Host: example.com
Accept: application/yang-data+xml
The server might respond as follows:
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Cache-Control: no-cache
Content-Type: application/yang-data+xml
<yang-library-version
xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf">\
2016-06-21\
</yang-library-version>
3.4. Datastore Resource
The {+restconf}/data subtree represents the datastore resource, which is a collection of configuration data and state data nodes 🫶
This resource type is an abstraction of the system's underlying datastore implementation. The client uses it to edit and retrieve data resources, as the conceptual root of all configuration and state data that is present on the device.
Configuration edit transaction management and configuration persistence are handled by the server, not the client 💅 A datastore resource can be written directly with the POST and PATCH methods. Each RESTCONF edit of a datastore resource is saved to non-volatile storage by the server if the server supports non-volatile storage of configuration data, as described in Section 1.4.
If the datastore resource represented by the {+restconf}/data subtree is retrieved, then the server returns the datastore and its contents. The datastore is represented by a node named "data" in the "ietf-restconf" module namespace.
3.4.1. Edit Collision Prevention
RESTCONF gives the datastore resource two edit collision detection and prevention mechanisms: a timestamp and an entity-tag 🔥 Any change to configuration data resources updates the timestamp and entity-tag of the datastore resource. On top of that, the RESTCONF server MUST return an error if the datastore is locked by an external source (e.g., NETCONF server). 🙅♀️
3.4.1.1. Timestamp
The last change time is maintained, and the Last-Modified header field (Section 2.2 of [RFC7232]) is returned in the response for a retrieval request. The If-Unmodified-Since header field (Section 3.4 of [RFC7232]) can be used in edit operation requests to make the server reject the request if the resource has been modified since the specified timestamp ⏰
The server SHOULD maintain a last-modified timestamp for the datastore resource, defined in Section 3.4. This timestamp is only affected by configuration child data resources and MUST NOT be updated for changes to non-configuration child data resources. Last-modified timestamps for data resources are discussed in Section 3.5.
If the RESTCONF server is co-located with a NETCONF server, then the last-modified timestamp MUST be for the "running" datastore. Note that other protocols can also cause the last-modified timestamp to be updated. Those mechanisms are out of scope for this document.
3.4.1.2. Entity-Tag 💖
okay so the server MUST keep a unique opaque entity-tag for the datastore resource, and it MUST send that tag back in the ETag header (see Section 2.3 of [RFC7232]) in the response to a retrieval request. the client MAY attach an If-Match header to edit requests, so the server can reject the request if the resource's entity-tag doesn't match the value the client sent 🫶
the server MUST also maintain an entity-tag for the top-level {+restconf}/data resource 🌸 this one only changes for configuration data resources, and it MUST NOT be updated for changes to non-configuration data. entity-tags for data resources are covered in Section 3.5. also, each representation (like XML vs. JSON) needs its own entity-tag, periodt ✨
if the RESTCONF server is co-located with a NETCONF server, this entity-tag MUST be for the running datastore. it's possible that other protocols can also update the entity-tag, but those mechanisms are out of scope for this document 🦋
3.4.1.3. Update Procedure 🎀
changes to configuration data resources affect the timestamp and entity-tag for that resource, any ancestor data resources, and the datastore resource. main character energy, the whole tree gets the update 🌈
for example, say you want to disable an interface. you'd set the leaf /interfaces/interface/enabled to "false". the enabled data node and its ancestors (one interface list instance and the interfaces container) are all considered changed. the datastore is considered changed whenever any top-level configuration data node changes, like interfaces 🧚
3.5. Data Resource 🌸
a data resource represents a YANG data node that is a descendant of a datastore resource. every YANG-defined data node can be uniquely targeted by the request-line of an HTTP method 💅 containers, leafs, leaf-list entries, list entries, anydata nodes, and anyxml nodes are all data resources ✨
the representation kept for each data resource is the YANG-defined subtree for that node. HTTP methods on a data resource affect both the targeted data node and all of its descendants, if it has any 🫶
you can retrieve a data resource with GET. data resources are accessed through {+restconf}/data, and that subtree is what you use to retrieve and edit them 🍓
3.5.1. Timestamp 💜
for configuration data resources, the server MAY maintain a last-modified timestamp for the resource and return the Last-Modified header field when the resource is retrieved with GET or HEAD 💜
a RESTCONF client can use Last-Modified in later requests, inside the If-Modified-Since and If-Unmodified-Since header fields 🦋
if the timestamp is maintained, the resource timestamp MUST be set to the current time whenever the resource or any configuration resource within it is altered. if it isn't maintained, the resource timestamp for the datastore MUST be used instead. if the RESTCONF server is co-located with a NETCONF server, the last-modified timestamp for a configuration data resource MUST represent the instance within the running datastore 🔥
this timestamp is only affected by configuration data resources, and it MUST NOT be updated for changes to non-configuration data 🙈
3.5.2. Entity-Tag 🧚
for configuration data resources, the server SHOULD maintain a resource entity-tag for each resource and return the ETag header field when the resource is retrieved as the target resource with GET or HEAD 🌈 if it's maintained, the resource entity-tag MUST be updated whenever the resource or any configuration resource within it is altered. if it isn't maintained, the resource entity-tag for the datastore MUST be used instead.
a RESTCONF client can use ETag in later requests, inside the If-Match and If-None-Match header fields 💖
this entity-tag is only affected by configuration data resources, and it MUST NOT be updated for changes to non-configuration data. if the RESTCONF server is co-located with a NETCONF server, the entity-tag for a configuration data resource MUST represent the instance within the running datastore 👑
3.5.3. Encoding Data Resource Identifiers in the Request URI 🫶
in YANG, data nodes can be identified with an absolute XPath expression, defined in [XPath], that starts at the document root and runs to the target resource. in RESTCONF, URI-encoded path expressions are used instead 🌸
a predictable location for a data resource is super important, since applications will code to the YANG data model module. that module uses static naming and defines an absolute path location for every data node 💅
a RESTCONF data resource identifier is encoded from left to right, starting with the top-level data node, following the api-path rule in Section 3.5.3.1. the node name of each ancestor of the target resource node is encoded in order, ending with the node name for the target resource. if a node in the path is defined in a module other than its parent node, or its parent is the datastore, then the module name followed by a colon character (:) MUST be prepended to the node name in the resource identifier. see Section 3.5.3.1 for details 🎀
if a data node in the path expression is a YANG leaf-list node, the leaf-list value MUST be encoded according to these rules:
- the identifier for the leaf-list MUST be encoded using one path segment [RFC3986].
- the path segment is built from the leaf-list name, then an
=character, then the leaf-list value (for example,/restconf/data/top-leaflist=fred). - the leaf-list value is specified as a string, using the canonical representation for the YANG data type. any reserved characters MUST be percent-encoded, according to Sections 2.1 and 2.5 of [RFC3986].
- YANG 1.1 allows duplicate leaf-list values for non-configuration data. in that case, there's no mechanism to specify the exact matching leaf-list instance 🙈
- the comma (
,) character is percent-encoded [RFC3986], even though multiple key values aren't possible for a leaf-list. this is more consistent and avoids special processing rules ✨
if a data node in the path expression is a YANG list node, the key values for the list (if any) MUST be encoded according to these rules:
- the key leaf values for a data resource representing a YANG list MUST be encoded using one path segment [RFC3986].
- if there is only one key leaf value, the path segment is built from the list name, then an
=character, then the single key leaf value. - if there are multiple key leaf values, the path segment is built from the list name, then the value of each leaf identified in the
keystatement, encoded in the order specified in the YANGkeystatement. each key leaf value except the last one is followed by a comma character. - the key value is specified as a string, using the canonical representation for the YANG data type. any reserved characters MUST be percent-encoded, according to Sections 2.1 and 2.5 of [RFC3986]. the comma (
,) character MUST be percent-encoded if it is present in the key value. - all of the components in the
keystatement MUST be encoded. partial instance identifiers are not supported. - missing key values are not allowed, so two consecutive commas are read as a comma, then a zero-length string, then a comma. for example,
list1=foo,,bazwould be read as a list namedlist1with three key values, and the second key value is a zero-length string 🌈 - non-configuration lists aren't required to define keys. in that case, a single list instance can't be accessed.
- the
list-instanceAugmented Backus-Naur Form (ABNF) [RFC5234] rule defined in Section 3.5.3.1 represents the syntax of a list instance identifier.
Examples:
container top {
list list1 {
key "key1 key2 key3";
...
list list2 {
key "key4 key5";
...
leaf X { type string; }
}
}
leaf-list Y {
type uint32;
}
}
for the YANG definition above, the container top is defined in the example-top YANG module, and a target resource URI for leaf X would be encoded like this:
/restconf/data/example-top:top/list1=key1,key2,key3/\
list2=key4,key5/X
for the same YANG definition, a target resource URI for leaf-list Y would be encoded like this:
/restconf/data/example-top:top/Y=instance-value
this example shows how reserved characters get percent-encoded inside a key value. the value of key1 contains a comma, single-quote, double-quote, colon, double-quote, space, and forward slash (,'":" /). double-quote isn't a reserved character, so it doesn't need percent-encoding. the value of key2 is the empty string, and the value of key3 is the string foo 💅
example URL:
/restconf/data/example-top:top/list1=%2C%27"%3A"%20%2F,,foo
3.5.3.1. ABNF for Data Resource Identifiers 📜
the api-path ABNF [RFC5234] syntax is used to build RESTCONF path identifiers. this syntax is used for all resources, and the API path starts with the RESTCONF root resource. data resources are required to be identified under the {+restconf}/data subtree 🫶
an identifier isn't allowed to start with the case-insensitive string XML, following YANG identifier rules. the syntax for api-identifier and key-value MUST conform to the JSON identifier encoding rules in Section 4 of [RFC7951]: the RESTCONF root resource path is required, and additional sub-resource identifiers are optional. the characters in a key value string are constrained, and some of them need percent-encoding, as described in Section 3.5.3 ✨
api-path = root *("/" (api-identifier / list-instance))
root = string ;; replacement string for {+restconf}
api-identifier = [module-name ":"] identifier
module-name = identifier
list-instance = api-identifier "=" key-value *("," key-value)
key-value = string ;; constrained chars are percent-encoded
string = <an unquoted string>
identifier = (ALPHA / "_")
*(ALPHA / DIGIT / "_" / "-" / ".")
3.5.4. Default Handling ✨
okay bestie, so RESTCONF needs a server to report its default-handling mode (peep Section 9.1.2 for the deets) 💅 and if the server supports the optional "with-defaults" query parameter, a client can use it to control how default values come back on retrieval (see Section 4.8.9 🎀).
here's the lowkey important part: if a leaf or leaf-list is missing from the configuration and there's a YANG-defined default for that data resource, the server MUST use the YANG-defined default as the configured value. no skipping, no vibes-based guessing 🫶
now for GETs. if the target of a GET is a data node for a leaf or leaf-list that has a default value and it hasn't been instantiated yet, the server MUST return the default value (or values) that are in use by the server 🔥 and in this case the server MUST ignore its "basic-mode" (described in Section 4.8.9) and return the default value anyway. main character energy, the default wins 👑
and if the target of a GET is a container or list with child resources that have default values, the server MAY return the defaults that are in use for the children that haven't been given values yet 🌸. it depends on its reported default-handling mode and whatever query parameters the client passed. so it's optional, not forced, periodt 💀
3.6. Operation Resource 🦋
an operation resource represents an RPC operation defined with the YANG "rpc" statement, or a data-model-specific action defined with a YANG "action" statement. you invoke it with a POST method on the operation resource 💖
an RPC operation gets invoked like this:
POST {+restconf}/operations/<operation>
the <operation> part identifies the module name and the rpc identifier string for the operation you want 🧚
for example, if "module-A" defined a "reset" RPC operation, invoking it looks like this:
POST /restconf/operations/module-A:reset HTTP/1.1
Server: example.com
an action gets invoked like this:
POST {+restconf}/data/<data-resource-identifier>/<action>
where <data-resource-identifier> holds the path to the data node where the action is defined, and <action> is the name of the action ✨
for example, if "module-A" defined a "reset-all" action in the container "interfaces", invoking that action looks like this:
POST /restconf/data/module-A:interfaces/reset-all HTTP/1.1
Server: example.com
if the RPC operation is invoked without errors AND the "rpc" or "action" statement has no "output" section, the response message MUST NOT include a message-body and MUST send a "204 No Content" status-line instead. no body, just the 204 🙈
all operation resources representing RPC operations the server supports MUST be identified in the "{+restconf}/operations" subtree, defined in Section 3.3.2 🌈. operation resources representing YANG actions are NOT listed in that subtree, since they get invoked through a URI inside the "{+restconf}/data" subtree instead 🍓
3.6.1. Encoding Operation Resource Input Parameters 💜
if the "rpc" or "action" statement has an "input" section, the instances of those input parameters get encoded in the module namespace where the "rpc" or "action" statement is defined. they go in an XML element or JSON object named "input", which is also in that module namespace 🎀
if the "rpc" or "action" statement has an "input" section AND the "input" object tree contains any child data nodes that are considered mandatory, then the client MUST send a message-body in the request 🔥
if the "rpc" or "action" statement has an "input" section but the "input" object tree has NO child nodes that are considered mandatory, then the client MAY send a message-body in the request 🫧
if the "rpc" or "action" statement has NO "input" section, the request message MUST NOT include a message-body 🙅
here come the examples! 🎉 the following YANG module is used for the RPC operation examples in this section:
module example-ops {
namespace "https://example.com/ns/example-ops";
prefix "ops";
organization "Example, Inc.";
contact "support at example.com";
description "Example Operations Data Model Module.";
revision "2016-07-07" {
description "Initial version.";
reference "example.com document 3-3373.";
}
rpc reboot {
description "Reboot operation.";
input {
leaf delay {
type uint32;
units "seconds";
default 0;
description
"Number of seconds to wait before initiating the
reboot operation.";
}
leaf message {
type string;
description
"Log message to display when reboot is started.";
}
leaf language {
type string;
description "Language identifier string.";
reference "RFC 5646.";
}
}
}
rpc get-reboot-info {
description
"Retrieve parameters used in the last reboot operation.";
output {
leaf reboot-time {
type uint32;
description
"The 'delay' parameter used in the last reboot
operation.";
}
leaf message {
type string;
description
"The 'message' parameter used in the last reboot
operation.";
}
leaf language {
type string;
description
"The 'language' parameter used in the last reboot
operation.";
}
}
}
}
and the following YANG module is used for the YANG action examples in this section:
module example-actions {
yang-version 1.1;
namespace "https://example.com/ns/example-actions";
prefix "act";
import ietf-yang-types { prefix yang; }
organization "Example, Inc.";
contact "support at example.com";
description "Example Actions Data Model Module.";
revision "2016-07-07" {
description "Initial version.";
reference "example.com document 2-9973.";
}
container interfaces {
description "System interfaces.";
list interface {
key name;
description "One interface entry.";
leaf name {
type string;
description "Interface name.";
}
action reset {
description "Reset an interface.";
input {
leaf delay {
type uint32;
units "seconds";
default 0;
description
"Number of seconds to wait before starting the
interface reset.";
}
}
}
action get-last-reset-time {
description
"Retrieve the last interface reset time.";
output {
leaf last-reset {
type yang:date-and-time;
mandatory true;
description
"Date and time of the last interface reset, or
the last reboot time of the device.";
}
}
}
}
}
}
RPC Input Example 🎀
the client might send this POST request to invoke the "reboot" RPC operation:
POST /restconf/operations/example-ops:reboot HTTP/1.1
Host: example.com
Content-Type: application/yang-data+xml
<input xmlns="https://example.com/ns/example-ops">
<delay>600</delay>
<message>Going down for system maintenance</message>
<language>en-US</language>
</input>
the server might respond like this:
HTTP/1.1 204 No Content
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
same example request, but in JSON encoding 💖:
POST /restconf/operations/example-ops:reboot HTTP/1.1
Host: example.com
Content-Type: application/yang-data+json
{
"example-ops:input" : {
"delay" : 600,
"message" : "Going down for system maintenance",
"language" : "en-US"
}
}
Action Input Example 🦋
the client might send this POST request to invoke the "reset" action:
POST /restconf/data/example-actions:interfaces/\
interface=eth0/reset HTTP/1.1
Host: example.com
Content-Type: application/yang-data+xml
<input xmlns="https://example.com/ns/example-actions">
<delay>600</delay>
</input>
the server might respond like this:
HTTP/1.1 204 No Content
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
same example request in JSON encoding 🌸:
POST /restconf/data/example-actions:interfaces/\
interface=eth0/reset HTTP/1.1
Host: example.com
Content-Type: application/yang-data+json
{ "example-actions:input" : {
"delay" : 600
}
}
that's the end of part 6, the operation resources are all served up! 🧚💜 keep going, more parts are coming 💅
3.6.2. Encoding Operation Resource Output Parameters
If the "rpc" or "action" statement has an "output" section, then instances of these output parameters are encoded in the module namespace where the "rpc" or "action" statement is defined, in an XML element or JSON object named "output", which is in the module namespace where the "rpc" or "action" statement is defined. 💖
If the RPC operation is invoked without errors, and if the "rpc" or "action" statement has an "output" section and the "output" object tree contains any child data nodes that are considered mandatory nodes, then a response message-body MUST be sent by the server in the response. 🎀 Translation: if there's a mandatory output node, the server absolutely MUST send a body back. No skipping!
If the RPC operation is invoked without errors, and if the "rpc" or "action" statement has an "output" section and the "output" object tree does not contain any child nodes that are considered mandatory nodes, then a response message-body MAY be sent by the server in the response. ✨ So here the server is allowed to send a body, but it's optional, totally its call.
The request URI is not returned in the response. Knowledge of the request URI may be needed to associate the output with the specific "rpc" or "action" statement used in the request. 🦋 The URI doesn't come back in the response, so you might need to remember which request you sent to match up the output. iykyk.
Examples:
RPC Output Example:
The "example-ops" YANG module defined in Section 3.6.1 is used for this example. 🌸
The client might send the following POST request message to invoke the "get-reboot-info" operation:
POST /restconf/operations/example-ops:get-reboot-info HTTP/1.1
Host: example.com
Accept: application/yang-data+json
The server might respond as follows:
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Content-Type: application/yang-data+json
{
"example-ops:output" : {
"reboot-time" : 30,
"message" : "Going down for system maintenance",
"language" : "en-US"
}
}
The same response is shown here using XML encoding:
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Content-Type: application/yang-data+xml
<output xmlns="https://example.com/ns/example-ops">
<reboot-time>30</reboot-time>
<message>Going down for system maintenance</message>
<language>en-US</language>
</output>
Action Output Example:
The "example-actions" YANG module defined in Section 3.6.1 is used for this example. 🧚
The client might send the following POST request message to invoke the "get-last-reset-time" action:
POST /restconf/data/example-actions:interfaces/\
interface=eth0/get-last-reset-time HTTP/1.1
Host: example.com
Accept: application/yang-data+json
The server might respond as follows:
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Content-Type: application/yang-data+json
{
"example-actions:output" : {
"last-reset" : "2015-10-10T02:14:11Z"
}
}
3.6.3. Encoding Operation Resource Errors
If any errors occur while attempting to invoke the operation or action, then an "errors" media type is returned with the appropriate error status. 🚨 Errors get their own media type, plus the right status code, so the client knows something went sideways.
If (1) the RPC operation input is not valid or (2) the RPC operation is invoked but errors occur, then a message-body containing an "errors" resource MUST be sent by the server, as defined in Section 3.9. 💅 Bad input or an error during the call? The server MUST send an "errors" body. No exceptions, bestie.
Using the "reboot" RPC operation from the example in Section 3.6.1, the client might send the following POST request message:
POST /restconf/operations/example-ops:reboot HTTP/1.1
Host: example.com
Content-Type: application/yang-data+xml
<input xmlns="https://example.com/ns/example-ops">
<delay>-33</delay>
<message>Going down for system maintenance</message>
<language>en-US</language>
</input>
The server might respond with an "invalid-value" error:
HTTP/1.1 400 Bad Request
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Content-Type: application/yang-data+xml
<errors xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf">
<error>
<error-type>protocol</error-type>
<error-tag>invalid-value</error-tag>
<error-path xmlns:ops="https://example.com/ns/example-ops">
/ops:input/ops:delay
</error-path>
<error-message>Invalid input parameter</error-message>
</error>
</errors>
The same response is shown here using JSON encoding:
HTTP/1.1 400 Bad Request
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Content-Type: application/yang-data+json
{ "ietf-restconf:errors" : {
"error" : [
{
"error-type" : "protocol",
"error-tag" : "invalid-value",
"error-path" : "/example-ops:input/delay",
"error-message" : "Invalid input parameter"
}
]
}
}
3.7. Schema Resource
The server can optionally support the retrieval of the YANG modules it uses. If retrieval is supported, then the "schema" leaf MUST be present in the associated "module" list entry, defined in [RFC7895]. 📚 Schema retrieval is optional for servers, but if a server does support it, the "schema" leaf is a must-have in the "module" list entry.
To retrieve a YANG module, a client first needs to get the URL for retrieving the schema, which is stored in the "schema" leaf. Note that there is no required structure for this URL. The URL value shown below is just an example. 🔗 The URL can look like anything, so don't assume a shape. The one below is just for show.
The client might send the following GET request message:
GET /restconf/data/ietf-yang-library:modules-state/\
module=example-jukebox,2016-08-15/schema HTTP/1.1
Host: example.com
Accept: application/yang-data+json
The server might respond as follows:
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Content-Type: application/yang-data+json
{
"ietf-yang-library:schema" :
"https://example.com/mymodules/example-jukebox/2016-08-15"
}
Next, the client needs to retrieve the actual YANG schema. 🌈
The client might send the following GET request message:
GET https://example.com/mymodules/example-jukebox/\
2016-08-15 HTTP/1.1
Host: example.com
Accept: application/yang
The server might respond as follows:
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Content-Type: application/yang
// entire YANG module contents deleted for this example...
3.8. Event Stream Resource
An event stream resource represents a source for system-generated event notifications. Each stream is created and modified by the server only. A client can retrieve a stream resource or initiate a long-poll server-sent event stream [W3C.REC-eventsource-20150203], using the procedure specified in Section 6.3. 🌊 Only the server creates and changes these streams. Clients can grab one or start a long-poll server-sent event stream, following Section 6.3.
An event stream functions according to the "NETCONF Event Notifications" specification [RFC5277]. The available streams can be retrieved from the "stream" list, which specifies the syntax and semantics of the stream resources. 🎀 It works just like the "NETCONF Event Notifications" spec [RFC5277] says, and you find the streams in the "stream" list.
3.9. "errors" YANG Data Template
The "errors" YANG data template models a collection of error information that is sent as the message-body in a server response message if an error occurs while processing a request message. It is not considered as a resource type because no instances can be retrieved with a GET request. 🙈 It's basically a box of error info the server sends back. You can't GET it, so it's not a resource type. Not me being confused by that at first lol.
The "ietf-restconf" YANG module contains the "yang-errors" YANG data template, which specifies the syntax and semantics of an "errors" container within a RESTCONF response. RESTCONF error-handling behavior is defined in Section 7. 💜
4. RESTCONF Methods ✨
The RESTCONF protocol uses HTTP methods to identify the CRUD operations requested for a particular resource. 🍓 Each HTTP method tells the server which CRUD operation you want.
The following table shows how the RESTCONF operations relate to NETCONF protocol operations.
+----------+-------------------------------------------------------+
| RESTCONF | NETCONF |
+----------+-------------------------------------------------------+
| OPTIONS | none |
| | |
| HEAD | <get-config>, <get> |
| | |
| GET | <get-config>, <get> |
| | |
| POST | <edit-config> (nc:operation="create") |
| | |
| POST | invoke an RPC operation |
| | |
| PUT | <copy-config> (PUT on datastore) |
| | |
| PUT | <edit-config> (nc:operation="create/replace") |
| | |
| PATCH | <edit-config> (nc:operation depends on PATCH content) |
| | |
| DELETE | <edit-config> (nc:operation="delete") |
+----------+-------------------------------------------------------+
CRUD Methods in RESTCONF
The "remove" edit operation attribute for the NETCONF <edit-config> RPC operation is not supported by the HTTP DELETE method. The resource must exist or the DELETE method will fail. The PATCH method is equivalent to a "merge" edit operation when using a plain patch (see Section 4.6.1); other media types may provide more granular control. 🧐 No "remove" over DELETE, and the resource has to already exist or DELETE fails. PATCH acts like "merge" with a plain patch, but other media types can be pickier.
Access control mechanisms are used to limit what CRUD operations can be used. In particular, RESTCONF is compatible with the NETCONF Access Control Model (NACM) [RFC6536], as there is a specific mapping between RESTCONF and NETCONF operations. The resource path needs to be converted internally by the server to the corresponding YANG instance identifier. Using this information, the server can apply the NACM access control rules to RESTCONF messages. 🔐 Access control decides which CRUD ops are allowed. RESTCONF plays nicely with NACM [RFC6536] because the mapping to NETCONF is clear, so the server can turn the path into a YANG instance identifier and apply those rules.
The server MUST NOT allow any RESTCONF operation for any resources that the client is not authorized to access. 🚫 Hard no: if the client isn't authorized for a resource, the server MUST NOT allow any operation on it.
The implementation of all methods (except PATCH [RFC5789]) is defined in [RFC7231]. This section defines the RESTCONF protocol usage for each HTTP method. 📖 Everything except PATCH is defined in [RFC7231], and this section tells you how RESTCONF uses each method.
4.1. OPTIONS
The OPTIONS method is sent by the client to discover which methods are supported by the server for a specific resource (e.g., GET, POST, DELETE). The server MUST implement this method. 🔍 Clients use OPTIONS to find out which methods a resource supports. The server MUST implement it, no excuses.
The "Accept-Patch" header field MUST be supported and returned in the response to the OPTIONS request, as defined in [RFC5789]. 🎀 The "Accept-Patch" header MUST be supported and sent back in the OPTIONS response, per [RFC5789].
4.2. HEAD
The RESTCONF server MUST support the HEAD method. The HEAD method is sent by the client to retrieve just the header fields (which contain the metadata for a resource) that would be returned for the comparable GET method, without the response message-body. It is supported for all resources that support the GET method. 🧠 The server MUST support HEAD. It gets you just the headers (the metadata) you'd get from GET, minus the body. Any resource that supports GET also supports HEAD.
The request MUST contain a request URI that contains at least the root resource. The same query parameters supported by the GET method are supported by the HEAD method. 🗝️ The request MUST have a URI that includes at least the root resource, and HEAD takes the same query parameters as GET.
The access control behavior is enforced as if the method was GET instead of HEAD. The server MUST respond the same as if the method was GET instead of HEAD, except that no response message-body is included. 🫶 Access control treats HEAD exactly like GET. The server MUST respond the same way it would for GET, just without the body.
4.3. GET 🎀
okay so the RESTCONF server MUST support the GET method 🫶. the client sends GET when it wants to grab data and metadata for a resource 💖. it works for every resource type EXCEPT operation resources, bestie 💀. the request MUST contain a request URI that contains at least the root resource 🌸.
the server MUST NOT return any data resources the user doesn't have read privileges for 🙈 that's just basic privacy, no cap. if the user isn't authorized to read the target resource, an error response with a "401 Unauthorized" status-line SHOULD be returned 💅. the error-tag "access-denied" is returned in this case. a server MAY return a "404 Not Found" status-line too, as described in Section 6.5.4 in [RFC7231] ✨. in that case the error-tag "invalid-value" is returned.
if the user can read some of the target resource but not all of it, the unauthorized bits get left out of the response message-body, and the allowed bits still go back to the client 🦋.
if any content does get returned, the server MUST send a valid response message-body 🍓. more than one element MUST NOT be returned for XML encoding 😭. if multiple elements go out in a JSON message-body, they MUST be sent as a JSON array 🌈. in that case, any timestamp or entity-tag in the response MUST be associated with the first element returned 👑.
if a retrieval request for a data resource that's a YANG leaf-list or list identifies more than one instance AND XML encoding is used in the response, then the server MUST return an error response with a "400 Bad Request" status-line 🙈. the error-tag "invalid-value" is used here. fun fact (well, a fact): a non-configuration list is not required to define any keys, so in that case grabbing a single list instance just isn't possible 🧚.
if a retrieval request is for an instance that doesn't exist, the server MUST return an error response with a "404 Not Found" status-line 💀. the error-tag "invalid-value" is used in this case.
if the target of a retrieval request is an operation resource, then the server MUST return a "405 Method Not Allowed" status-line 🚫. the error-tag "operation-not-supported" is used here.
heads up: access control on data resources may not be completely compatible with HTTP caching 👀. the "Last-Modified" and "ETag" header fields kept for a data resource don't change when the access control rules for that resource change. so it's possible for the representation of a data resource that a particular client can see to change without anyone noticing via "Last-Modified" or "ETag" 😭.
here's a GET example. the client asks for the response headers of an XML "album" resource 📀:
GET /restconf/data/example-jukebox:jukebox/\
library/artist=Foo%20Fighters/album=Wasting%20Light HTTP/1.1
Host: example.com
Accept: application/yang-data+xml
and the server might answer like this 🎶:
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Content-Type: application/yang-data+xml
Cache-Control: no-cache
ETag: "a74eefc993a2b"
Last-Modified: Thu, 26 Jan 2017 14:02:14 GMT
<album xmlns="http://example.com/ns/example-jukebox"
xmlns:jbox="http://example.com/ns/example-jukebox">
<name>Wasting Light</name>
<genre>jbox:alternative</genre>
<year>2011</year>
</album>
for more retrieval examples, check out Appendix B.1 📚✨.
4.4. POST 💅
the RESTCONF server MUST support POST 🧁. the client uses POST to create a data resource or invoke an operation resource. the server looks at the target resource type to figure out how to handle the request, so it's all about the target 🎯.
Resource Types That Support POST
+-----------+------------------------------------------------+
| Type | Description |
+-----------+------------------------------------------------+
| Datastore | Create a top-level configuration data resource |
| Data | Create a configuration data child resource |
| Operation | Invoke an RPC operation |
+-----------+------------------------------------------------+
4.4.1. Create Resource Mode 🧚
if the target resource type is a datastore or a data resource, the POST is treated as a request to create a top-level resource or a child resource, respectively 🌸. the message-body is expected to hold the content of a child resource to create inside the parent (the target resource). the message-body MUST contain exactly one instance of the expected data resource 🫶. the data model for the child tree is the subtree, as defined by YANG for the child resource.
the "insert" (Section 4.8.5) and "point" (Section 4.8.6) query parameters MUST be supported by POST for datastore and data resources 💖. these parameters are only allowed if the list or leaf-list is "ordered-by user" ✨.
if POST succeeds, a "201 Created" status-line comes back and there's no response message-body 🦋. in this case the response MUST include a "Location" header field that identifies the child resource that was created 🎀.
if the data resource already exists, the POST request MUST fail and the server MUST return a "409 Conflict" status-line 💀. the error-tag "resource-denied" is used here.
if the user isn't authorized to create the target resource, an error response with a "403 Forbidden" status-line SHOULD be returned 🙈. the error-tag "access-denied" is used in this case. a server MAY return a "404 Not Found" status-line, as described in Section 6.5.4 in [RFC7231]. the error-tag "invalid-value" is used in this case. all other error responses are handled according to the procedures in Section 7 🌈.
here's the example 🧸. to create a new "jukebox" resource, the client might send this:
POST /restconf/data HTTP/1.1
Host: example.com
Content-Type: application/yang-data+json
{ "example-jukebox:jukebox" : {} }
if the resource gets created, the server might respond like this 🎉:
HTTP/1.1 201 Created
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Location: https://example.com/restconf/data/\
example-jukebox:jukebox
Last-Modified: Thu, 26 Jan 2017 20:56:30 GMT
ETag: "b3a3e673be2"
more creation examples live in Appendix B.2.1 🦋.
4.4.2. Invoke Operation Mode 🔥
if the target resource type is an operation resource, then POST is treated as a request to invoke that operation 👑. the message-body (if there is one) gets processed as the operation's input parameters. check out Section 3.6 for the deets on operation resources 🧠.
if the POST request succeeds, you get a "200 OK" status-line when there's a response message-body, and a "204 No Content" status-line when there isn't 🎀.
if the user isn't authorized to invoke the target operation, an error response with a "403 Forbidden" status-line SHOULD be returned 😭. the error-tag "access-denied" is used here. a server MAY return a "404 Not Found" status-line, as described in Section 6.5.4 in [RFC7231]. all other error responses are handled according to the procedures in Section 7 💅.
example time 🎶. here the client is invoking the "play" operation from the "example-jukebox" YANG module.
a client might send a "play" request like this:
POST /restconf/operations/example-jukebox:play HTTP/1.1
Host: example.com
Content-Type: application/yang-data+json
{
"example-jukebox:input" : {
"playlist" : "Foo-One",
"song-number" : 2
}
}
and the server might respond like this:
HTTP/1.1 204 No Content
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
4.5. PUT 🎀
bestie, the RESTCONF server MUST support the PUT method 💅 The client uses PUT to create a data resource or replace one that's already there ✨ A request message-body MUST be present, representing the new data resource, or the server MUST return a "400 Bad Request" status-line 😭 In that case the error-tag value "invalid-value" is used.
PUT and POST can both create data resources, but they're different. With POST, the client doesn't name the new resource, so the POST target is the parent of what gets created. With PUT, the target is the new resource itself, so the client picks the identifier 🦋
The PUT method MUST be supported for data and datastore resources 🌸 A PUT on the datastore resource replaces the entire contents of the datastore. A PUT on a data resource only replaces that one data resource inside the datastore.
The "insert" (Section 4.8.5) and "point" (Section 4.8.6) query parameters MUST be supported by the PUT method for data resources 🧚 They're only allowed when the list or leaf-list is "ordered-by user".
Consistent with [RFC7231], a PUT that creates a new resource gets a "201 Created" status-line back. If an existing resource gets modified, you get a "204 No Content" status-line instead ✨
If the user isn't authorized to create or replace the target resource, an error response with a "403 Forbidden" status-line SHOULD be returned 🙈 The error-tag value "access-denied" is used here.
A server MAY return a "404 Not Found" status-line, as described in Section 6.5.4 in [RFC7231]. The error-tag value "invalid-value" is used in that case. Every other error response follows the procedures in Section 7 💜
If the target resource is a YANG leaf-list, the PUT method MUST NOT change the value of the leaf-list instance 🍓
If the target resource is a YANG list instance, the key leaf values in the message-body MUST be the same as the key leaf values in the request URI. The PUT method MUST NOT be used to change the key leaf values for a data resource instance 🔥
Example:
An "album" child resource defined in the "example-jukebox" YANG module gets replaced, or created if it doesn't exist yet 🎶
To replace the "album" resource contents, the client might send the following:
PUT /restconf/data/example-jukebox:jukebox/\
library/artist=Foo%20Fighters/album=Wasting%20Light HTTP/1.1
Host: example.com
Content-Type: application/yang-data+json
{
"example-jukebox:album" : [
{
"name" : "Wasting Light",
"genre" : "example-jukebox:alternative",
"year" : 2011
}
]
}
If the resource gets updated, the server might respond like this:
HTTP/1.1 204 No Content
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Last-Modified: Thu, 26 Jan 2017 20:56:30 GMT
ETag: "b27480aeda4c"
Same request, but with XML encoding 🌈
PUT /restconf/data/example-jukebox:jukebox/\
library/artist=Foo%20Fighters/album=Wasting%20Light HTTP/1.1
Host: example.com
Content-Type: application/yang-data+xml
<album xmlns="http://example.com/ns/example-jukebox"
xmlns:jbox="http://example.com/ns/example-jukebox">
<name>Wasting Light</name>
<genre>jbox:alternative</genre>
<year>2011</year>
</album>
Refer to Appendix B.2.4 for an example of using the PUT method to replace the contents of the datastore resource ✨
4.6. PATCH 🦋
The RESTCONF server MUST support the PATCH method for a plain patch, and it MAY support additional media types 💖 The client can find out which PATCH media types the server supports by sending an OPTIONS request and checking the "Accept-Patch" header field in the response (see Section 4.1).
RESTCONF uses the HTTP PATCH method defined in [RFC5789] as an extensible framework for patching mechanisms. Each patch mechanism needs its own unique media type 🧩
This document defines one patch mechanism (Section 4.6.1). Another one, the YANG Patch mechanism, is defined in [YANG-Patch]. Future specifications may define other patch mechanisms 🔮
If the target resource instance doesn't exist, the server MUST NOT create it 🙅♀️
If the PATCH request succeeds, you get a "200 OK" status-line back when there's a message-body, and a "204 No Content" status-line when no response message-body is sent ✨
If the user isn't authorized to alter the target resource, an error response with a "403 Forbidden" status-line SHOULD be returned. A server MAY return a "404 Not Found" status-line, as described in Section 6.5.4 in [RFC7231]. The error-tag value "invalid-value" is used in that case. All other error responses follow the procedures in Section 7 💅
4.6.1. Plain Patch 🎀
The plain patch mechanism merges the contents of the message-body with the target resource 🫶 The message-body for a plain patch MUST be present and MUST be represented by the media type "application/yang-data+xml" or "application/yang-data+json".
A plain patch can create or update a child resource inside the target resource, but it can't delete one 😭 If you need deletion, look at [YANG-Patch], which has a different media type. The YANG Patch media type supports multiple suboperations (for example "merge" and "delete") in a single PATCH method 👑
If the target resource is a YANG leaf-list, the PATCH method MUST NOT change the value of the leaf-list instance 🍓
If the target resource is a YANG list instance, the key leaf values in the message-body MUST be the same as the key leaf values in the request URI. The PATCH method MUST NOT be used to change the key leaf values for a data resource instance 💜
After the server processes the plain patch, a response goes back to the client, as specified in Section 4.6 ✨
Example:
To replace just the "year" field in the "album" resource (instead of replacing the whole thing with PUT), the client might send a plain patch like this:
PATCH /restconf/data/example-jukebox:jukebox/\
library/artist=Foo%20Fighters/album=Wasting%20Light HTTP/1.1
Host: example.com
If-Match: "b8389233a4c"
Content-Type: application/yang-data+xml
<album xmlns="http://example.com/ns/example-jukebox">
<year>2011</year>
</album>
If the field gets updated, the server might respond like this:
HTTP/1.1 204 No Content
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Last-Modified: Thu, 26 Jan 2017 20:56:30 GMT
ETag: "b2788923da4c"
4.7. DELETE 💀
The RESTCONF server MUST support the DELETE method 🗑️ The DELETE method deletes the target resource. If the DELETE request succeeds, a "204 No Content" status-line comes back ✨
If the user isn't authorized to delete the target resource, an error response with a "403 Forbidden" status-line SHOULD be returned. The error-tag value "access-denied" is returned here. A server MAY return a "404 Not Found" status-line, as described in Section 6.5.4 in [RFC7231]. The error-tag value "invalid-value" is returned in that case. Every other error response follows the procedures in Section 7 🙈
If the target resource is a configuration leaf-list or list data node, it MUST represent a single YANG leaf-list or list instance. The server MUST NOT use the DELETE method to delete more than one such instance 🚫
Example:
To delete the "album" resource with the key "Wasting Light", the client might send the following:
DELETE /restconf/data/example-jukebox:jukebox/\
library/artist=Foo%20Fighters/album=Wasting%20Light HTTP/1.1
Host: example.com
If the resource gets deleted, the server might respond like this:
HTTP/1.1 204 No Content
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
4.8. Query Parameters 🌸
Each RESTCONF operation can take zero or more query parameters in the request URI 🧁 Which ones are allowed depends on the resource type, and sometimes on the specific target resource in the request.
- Query parameters can be given in any order.
- Each parameter can appear at most once in a request URI.
- If more than one instance of a query parameter is present, the server MUST return a
"400 Bad Request"status-line. The error-tag value"invalid-value"is returned in this case 😭 - A default value may apply if the parameter is missing.
- Query parameter names and values are case sensitive.
- A server MUST return an error with a
"400 Bad Request"status-line if a query parameter is unexpected. The error-tag value"invalid-value"is returned in this case 💅
Here's the table of query parameters 💖
+---------------+---------+-----------------------------------------+
| Name | Methods | Description |
+---------------+---------+-----------------------------------------+
| content | GET, | Select config and/or non-config data |
| | HEAD | resources |
| | | |
| depth | GET, | Request limited subtree depth in the |
| | HEAD | reply content |
| | | |
| fields | GET, | Request a subset of the target resource |
| | HEAD | contents |
| | | |
| filter | GET, | Boolean notification filter for event |
| | HEAD | stream resources |
| | | |
| insert | POST, | Insertion mode for "ordered-by user" |
| | PUT | data resources |
| | | |
| point | POST, | Insertion point for "ordered-by user" |
| | PUT | data resources |
| | | |
| start-time | GET, | Replay buffer start time for event |
| | HEAD | stream resources |
| | | |
| stop-time | GET, | Replay buffer stop time for event |
| | HEAD | stream resources |
| | | |
| with-defaults | GET, | Control the retrieval of default values |
| | HEAD | |
+---------------+---------+-----------------------------------------+
RESTCONF Query Parameters
Refer to Appendix B.3 for examples of query parameter usage 🧚
If vendors define additional query parameters, they SHOULD use a prefix (such as the enterprise or organization name) for the parameter names, so they don't collide with other parameters 🦋
4.8.1. The "content" Query Parameter 💖
okay so the "content" query parameter is the one that decides how the descendant nodes of your requested data nodes get handled in the reply 🎀 you can ask for config, nonconfig, or all 💅
+-----------+-----------------------------------------------------+
| Value | Description |
+-----------+-----------------------------------------------------+
| config | Return only configuration descendant data nodes |
| | |
| nonconfig | Return only non-configuration descendant data nodes |
| | |
| all | Return all descendant data nodes |
+-----------+-----------------------------------------------------+
this one is only allowed on GET methods for datastore and data resources 🧚 if you try it on other methods or resource types, you get a 400 Bad Request status-line, so no sneaking it in 🙈
if you leave it out, the default is all ✨ and the server MUST support this query parameter, no exceptions 🫶
4.8.2. The "depth" Query Parameter 🦋
the "depth" query parameter limits how deep the subtrees the server sends back can go 🌸 any data node with a "depth" value bigger than your "depth" parameter just won't show up in the response to a GET method 💀
the requested data node is at depth level 1 ✨ if you use the "fields" parameter (Section 4.8.3) to pick out descendant nodes, those nodes and all of their ancestors count as depth 1 💜 this is kind of iconic because it means the fields you picked get included even when the depth value is smaller than their real depth level 👑 any other child node is just 1 more than its parent, simple as 🌈
the "depth" value is either an integer from 1 to 65535, or the string "unbounded" 🍓 and yep, "unbounded" is the default 💖
this parameter is only allowed on GET methods for API, datastore, and data resources 🫶 anything else gets a 400 Bad Request status-line 💀
by default, the server includes all the sub-resources inside a retrieved resource that have the same resource type as the one you asked for 🦋 the exception is the datastore resource 👑 if you retrieve that one, you get the datastore plus all the child data resources by default ✨
if the "depth" query parameter URI is listed in the "capability" leaf-list defined in Section 9.3, then the server supports "depth" 💅
4.8.3. The "fields" Query Parameter 🌸
the "fields" query parameter lets you optionally pick out data nodes inside the target resource for a GET method 🎀 it's a way to grab just a slice of a resource instead of everything 💖
the server returns one message-body representing the target resource, with descendant nodes pruned to match your "fields-expr" value 🧚 it does not send back a bunch of separate sub-resources 🙈
a value of the "fields" query parameter matches this rule:
fields-expr = path "(" fields-expr ")" / path ";" fields-expr / path
path = api-identifier [ "/" path ]
"api-identifier" is defined in Section 3.5.3.1 🦋
the semicolon ; is how you select multiple nodes 🍓 for example, to get only the "genre" and "year" of an album, use fields=genre;year 💜
parentheses give you sub-selectors of a node 💅 and here's the tea: there is no path separator "/" between a "path" field and a left parenthesis "(" 👑 so admin(label;catalogue-number) is good, but admin/(label) is not a thing 💀
for example, say the target resource is the "album" list 🌈 to get only the "label" and "catalogue-number" of the "admin" container inside an album, use fields=admin(label;catalogue-number) ✨
the slash "/" is how you reach a child node of a node 🫶 so to get only the "label" of an album, use fields=admin/label 🌸
this parameter is only allowed on GET methods for API, datastore, and data resources 🎀 otherwise, 400 Bad Request 💀
if the "fields" query parameter URI is listed in the "capability" leaf-list defined in Section 9.3, then the server supports the "fields" parameter 🔥
4.8.4. The "filter" Query Parameter 🧚
the "filter" query parameter tells the server which subset of all possible events you're actually interested in 👀 if you don't include it, every event that isn't blocked by your other parameters gets sent 💖
this one is only allowed on GET methods for an event stream resource 🦋 anything else gets a 400 Bad Request status-line 💀
the format is an XPath 1.0 expression [XPath], and it gets evaluated in this context 💅
- The set of namespace declarations is the set of prefix and namespace pairs for all supported YANG modules, where the prefix is the YANG module name and the namespace is as defined by the "namespace" statement in the YANG module.
- The function library is the core function library defined in XPath 1.0, plus any functions defined by the data model.
- The set of variable bindings is empty.
- The context node is the root node.
the "filter" query parameter is used as defined in Section 3.6 of [RFC5277] 🌈 if the boolean result of the expression is "true" when it's applied to the conceptual "notification" document root, the event notification gets delivered to the client 🫶
if the "filter" query parameter URI is listed in the "capability" leaf-list defined in Section 9.3, then the server supports the "filter" query parameter ✨
4.8.5. The "insert" Query Parameter 👑
the "insert" query parameter says where a resource should go inside an "ordered-by user" list 💖 think of it like picking your spot in the line 🎀
these are the allowed values 💅
+--------+----------------------------------------------------------+
| Value | Description |
+--------+----------------------------------------------------------+
| first | Insert the new data as the new first entry. |
| | |
| last | Insert the new data as the new last entry. |
| | |
| before | Insert the new data before the insertion point, as |
| | specified by the value of the "point" parameter. |
| | |
| after | Insert the new data after the insertion point, as |
| | specified by the value of the "point" parameter. |
+--------+----------------------------------------------------------+
if you don't say anything, the default is "last" 🌸
this parameter is only supported for the POST and PUT methods 🦋 it's also only supported when the target resource is a data resource, and that data represents a YANG list or leaf-list that is "ordered-by user" 🧚
if you use "before" or "after", then a "point" query parameter MUST also be present, or you get a 400 Bad Request status-line 💀 and the "insert" query parameter MUST be supported by the server 🫶
4.8.6. The "point" Query Parameter 🍓
the "point" query parameter says where the insertion point is for a data resource that's being created or moved inside an "ordered-by user" list or leaf-list 💜
its value is a string that identifies the path to the insertion point object 🌈 the format is the same as a target resource URI string ✨
this parameter is only supported for the POST and PUT methods 💅 it's also only supported when the target resource is a data resource, and that data represents a YANG list or leaf-list that is "ordered-by user" 🦋
if the "insert" query parameter is missing, or has a value other than "before" or "after", then you get a 400 Bad Request status-line 💀
this parameter holds the instance identifier of the resource that's used as the insertion point for a POST or PUT method 🎀
the "point" query parameter MUST be supported by the server 👑
4.8.7. The "start-time" Query Parameter 🌈
the "start-time" query parameter triggers the notification replay feature defined in [RFC5277] 🔥 it tells the server that the replay should start at the time you specify ⏰
if the stream doesn't support replay according to the "replay-support" attribute returned by the "stream" list entry for the stream resource, then the server MUST return a 400 Bad Request status-line 💀 no replaying what can't be replayed 🙈
the value of the "start-time" parameter is of type "date-and-time", defined in the "ietf-yang-types" YANG module [RFC6991] 🧚
this parameter is only allowed for GET methods on a "text/event-stream" data resource 🦋 anything else gets a 400 Bad Request status-line 💀
if this parameter isn't there, then no replay subscription is being requested 🌸 it's not valid to specify start times that are later than the current time 🙅♀️ if the value is earlier than the log can support, the replay begins with the earliest available notification 🫶 a client can find out a server's current time by checking the "Date" header field that the server returns in response messages, according to [RFC7231] ⏰
if the server supports this query parameter, then the "replay" query parameter URI MUST be listed in the "capability" leaf-list defined in Section 9.3 🎀 and the "stop-time" query parameter MUST also be supported by the server ✨
if the "replay-support" leaf has the value "true" in the "stream" entry (defined in Section 9.3), then the server MUST support the "start-time" and "stop-time" query parameters for that stream 💖
4.8.8. The "stop-time" Query Parameter 🫶
the "stop-time" query parameter goes along with the replay feature and tells the server the newest notifications you're interested in 🌈 this parameter MUST be used with the "start-time" parameter, and it MUST have a value later than "start-time" 👑
the value of the "stop-time" parameter is of type "date-and-time", defined in the "ietf-yang-types" YANG module [RFC6991] 🧚
this parameter is only allowed for GET methods on a "text/event-stream" data resource 🦋 otherwise, 400 Bad Request 💀
if you leave it out, the notifications keep coming until the subscription is terminated 🔥 values in the future are valid too 🔮
if the server supports this query parameter, then the "replay" query parameter URI MUST be listed in the "capability" leaf-list defined in Section 9.3, and the "start-time" query parameter MUST also be supported by the server 🎀
if the "replay-support" leaf is present in the "stream" entry (defined in Section 9.3), then the server MUST support the "start-time" and "stop-time" query parameters for that stream 🌸
4.8.9. The "with-defaults" Query Parameter 🎀
okay bestie, this one controls how default data nodes show up when you GET a data resource 🧚 The "with-defaults" query parameter is the knob for that, and it's lowkey important.
If the server supports this capability, then it MUST implement the behavior described in Section 4.5.1 of [RFC6243], except applied to the RESTCONF GET operation instead of the NETCONF operations. 💅
+-------------------+-----------------------------------------------+
| Value | Description |
+-------------------+-----------------------------------------------+
| report-all | All data nodes are reported |
| | |
| trim | Data nodes set to the YANG default are not |
| | reported |
| | |
| explicit | Data nodes set to the YANG default by the |
| | client are reported |
| | |
| report-all-tagged | All data nodes are reported, and defaults are |
| | tagged |
+-------------------+-----------------------------------------------+
If the "with-defaults" parameter is set to "report-all", then the server MUST adhere to the default-reporting behavior defined in Section 3.1 of [RFC6243]. 🌸
If the "with-defaults" parameter is set to "trim", then the server MUST adhere to the default-reporting behavior defined in Section 3.2 of [RFC6243]. 🍓
If the "with-defaults" parameter is set to "explicit", then the server MUST adhere to the default-reporting behavior defined in Section 3.3 of [RFC6243]. 🦋
If the "with-defaults" parameter is set to "report-all-tagged", then the server MUST adhere to the default-reporting behavior defined in Section 3.4 of [RFC6243]. Metadata is reported by the server as specified in Section 5.3. The XML encoding for the "default" attribute sent by the server for default nodes is defined in Section 6 of [RFC6243]. The JSON encoding for the "default" attribute MUST use the same values, as defined in [RFC6243], but encoded according to the rules in [RFC7952]. The module name "ietf-netconf-with-defaults" MUST be used for the "default" attribute. this is the most dramatic one, periodt ✨
If the "with-defaults" parameter is not present, then the server MUST adhere to the default-reporting behavior defined in its "basic-mode" parameter for the "defaults" protocol capability URI, defined in Section 9.1.2. 💜
If the server includes the "with-defaults" query parameter URI in the "capability" leaf-list defined in Section 9.3, then the "with-defaults" query parameter MUST be supported. 🫶
Since the server does not report the "also-supported" parameter as described in Section 4.3 of [RFC6243], it is possible that some values for the "with-defaults" parameter will not be supported. If the server does not support the requested value of the "with-defaults" parameter, the server MUST return a response with a "400 Bad Request" status-line. The error-tag value "invalid-value" is used in this case. 😭
5. Messages 💅
The RESTCONF protocol uses HTTP messages. A single HTTP message corresponds to a single protocol method. Most messages can perform a single task on a single resource, such as retrieving a resource or editing a resource. The exception is the PATCH method, which allows multiple datastore edits within a single message. ✨
5.1. Request URI Structure
Resources are represented with URIs following the structure for generic URIs in [RFC3986]. 🦋
A RESTCONF operation is derived from the HTTP method and the request URI, using the following conceptual fields: 🧚
<OP> /<restconf>/<path>?<query>
^ ^ ^ ^
| | | |
method entry resource query
M M O O
M=mandatory, O=optional
where:
<OP> is the HTTP method
<restconf> is the RESTCONF root resource
<path> is the target resource URI
<query> is the query parameter list
- method: the HTTP method identifying the RESTCONF operation requested by the client, to act upon the target resource specified in the request URI. RESTCONF operation details are described in Section 4. 💖
- entry: the root of the RESTCONF API configured on this HTTP server, discovered by getting the
/.well-known/host-metaresource, as described in Section 3.1. 🌈 - resource: the path expression identifying the resource that is being accessed by the RESTCONF operation. If this field is not present, then the target resource is the API itself, represented by the YANG data template named "yang-api", found in Section 8. 🎀
- query: the set of parameters associated with the RESTCONF message; see Section 3.4 of [RFC3986]. RESTCONF parameters have the familiar form of "name=value" pairs. Most query parameters are optional to implement by the server and optional to use by the client. Each optional query parameter is identified by a URI. The server MUST list the optional query parameter URIs it supports in the "capability" leaf-list defined in Section 9.3. 👑
There is a specific set of parameters defined, although the server MAY choose to support query parameters not defined in this document. The contents of any query parameter value MUST be encoded according to Section 3.4 of [RFC3986]. Any reserved characters MUST be percent-encoded, according to Sections 2.1 and 2.5 of [RFC3986]. 💅
Note that the fragment component is not used by the RESTCONF protocol. The fragment is excluded from the target URI by a server, as described in Section 5.1 of [RFC7230]. 🙈
When new resources are created by the client, a "Location" header field is returned, which identifies the path of the newly created resource. The client uses this exact path identifier to access the resource once it has been created. 🍓
The target of a RESTCONF operation is a resource. The "path" field in the request URI represents the target resource for the RESTCONF operation. 🫶
Refer to Appendix B for examples of RESTCONF request URIs. ⭐
5.2. Message Encoding
RESTCONF messages are encoded in HTTP according to [RFC7230]. The "utf-8" character set is used for all messages. RESTCONF message content is sent in the HTTP message-body. 🌸
Content is encoded in either JSON or XML format. A server MUST support one of either XML or JSON encoding. A server MAY support both XML and JSON encoding. A client will need to support both XML and JSON to interoperate with all RESTCONF servers. 🔥
XML encoding rules for data nodes are defined in [RFC7950]. The same encoding rules are used for all XML content. JSON encoding rules are defined in [RFC7951]. Additional JSON encoding rules for metadata are defined in [RFC7952]. This encoding is valid JSON, but it also has special encoding rules to identify module namespaces and provide consistent type processing of YANG data. 🧚
The request input content encoding format is identified with the "Content-Type" header field. This field MUST be present if a message-body is sent by the client. 💖
The server MUST support the "Accept" header field and the "406 Not Acceptable" status-line, as defined in [RFC7231]. The response output content encoding formats that the client will accept are identified with the "Accept" header field in the request. If it is not specified, the request input encoding format SHOULD be used, or the server MAY choose any supported content encoding format. 🦋
If there was no request input, then the default output encoding is XML or JSON, depending on server preference. File extensions encoded in the request are not used to identify format encoding. 🌈
A client can determine if the RESTCONF server supports an encoding format by sending a request using a specific format in the "Content-Type" and/or "Accept" header field. If the server does not support the requested input encoding for a request, then it MUST return an error response with a "415 Unsupported Media Type" status-line. If the server does not support any of the requested output encodings for a request, then it MUST return an error response with a "406 Not Acceptable" status-line. no cap, these status codes are the main event 💀
5.3. RESTCONF Metadata
The RESTCONF protocol needs to support the retrieval of the same metadata that is used in the NETCONF protocol. Information about default leafs, last-modified timestamps, etc. is commonly used to annotate representations of the datastore contents. 🎀
With the XML encoding, the metadata is encoded as attributes in XML, according to Section 3.3 of [W3C.REC-xml-20081126]. With the JSON encoding, the metadata is encoded as specified in [RFC7952]. 🌸
The following examples are based on the example in Appendix B.3.9. The "report-all-tagged" mode for the "with-defaults" query parameter requires that a "default" attribute be returned for default nodes. These examples show that attribute for the "mtu" leaf. 🧚
5.3.1. XML Metadata Encoding Example
GET /restconf/data/interfaces/interface=eth1
?with-defaults=report-all-tagged HTTP/1.1
Host: example.com
Accept: application/yang-data+xml
The server might respond as follows:
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Content-Type: application/yang-data+xml
<interface
xmlns="urn:example.com:params:xml:ns:yang:example-interface">
<name>eth1</name>
<mtu xmlns:wd="urn:ietf:params:xml:ns:netconf:default:1.0"
wd:default="true">1500</mtu>
<status>up</status>
</interface>
5.3.2. JSON Metadata Encoding Example
Note that RFC 6243 defines the "default" attribute with the XML Schema Definition (XSD), not YANG, so the YANG module name has to be assigned instead of derived from the YANG module. The value "ietf-netconf-with-defaults" is assigned for JSON metadata encoding. 🙈
GET /restconf/data/interfaces/interface=eth1\
?with-defaults=report-all-tagged HTTP/1.1
Host: example.com
Accept: application/yang-data+json
The server might respond as follows:
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Content-Type: application/yang-data+json
{
"example:interface" : [
{
"name" : "eth1",
"mtu" : 1500,
"@mtu" : {
"ietf-netconf-with-defaults:default" : true
},
"status" : "up"
}
]
}
5.4. Return Status
Each message represents some sort of resource access. An HTTP "status-line" header field is returned for each request. If a status code in the "4xx" range is returned in the status-line, then the error information SHOULD be returned in the response, according to the format defined in Section 7.1. If a status code in the "5xx" range is returned in the status-line, then the error information MAY be returned in the response, according to the format defined in Section 7.1. If a status code in the "1xx", "2xx", or "3xx" range is returned in the status-line, then error information MUST NOT be returned in the response, since these ranges do not represent error conditions. status codes, bestie, they're basically the vibe check of every response 🫶
5.5. Message Caching 💾
Okay so the datastore contents change at unpredictable times, which means responses from a RESTCONF server generally SHOULD NOT be cached. Caching stale data is a whole vibe nobody wants 🙅♀️
The server MUST include a Cache-Control header field in every response, and it has to say whether that response should be cached. 🫶
Instead of leaning on HTTP caching, the client SHOULD keep track of the ETag and/or Last-Modified header fields the server returns for the datastore resource (or the data resource, if the server supports that). A retrieval request can include the If-None-Match and/or If-Modified-Since header fields, and then the server will send back a 304 Not Modified status-line if the resource hasn't changed. The client MAY use the HEAD method to grab just the message header fields. Those SHOULD include the ETag and Last-Modified header fields, but only if this metadata is maintained for the target resource 🦋
Heads up: access control can be applied to data resources. That means the values in the Last-Modified and ETag headers for a data resource may not be reliable, as described in Section 4.3. Be careful with that one, bestie 👀
6. Notifications 🔔
The RESTCONF protocol supports YANG-defined event notifications. The solution keeps the vibes of NETCONF event notifications [RFC5277] while using the Server-Sent Events [W3C.REC-eventsource-20150203] transport strategy. It's giving efficient and clean 💅
6.1. Server Support 🌸
A RESTCONF server MAY support RESTCONF notifications. Clients can figure out whether a server supports them by using the HTTP OPTIONS, HEAD, or GET method on the "stream" list. If an HTTP error code comes back (like a 404 Not Found status-line), then the server does not support RESTCONF notifications 🙈
6.2. Event Streams 🌊
A RESTCONF server that supports notifications will populate a stream resource for each notification delivery service access point. A RESTCONF client can grab the list of supported event streams from a RESTCONF server by using the GET method on the "stream" list ✨
The "restconf-state/streams" container definition in the "ietf-restconf-monitoring" module (defined in Section 9.3) is used to specify the structure and syntax of the conceptual child resources within the "streams" resource. So that's the blueprint, iykyk 🧚
For example:
The client might send the following request:
GET /restconf/data/ietf-restconf-monitoring:restconf-state/\
streams HTTP/1.1
Host: example.com
Accept: application/yang-data+xml
The server might send the following response:
HTTP/1.1 200 OK
Content-Type: application/yang-data+xml
<streams
xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf-monitoring">
<stream>
<name>NETCONF</name>
<description>default NETCONF event stream</description>
<replay-support>true</replay-support>
<replay-log-creation-time>\
2007-07-08T00:00:00Z\
</replay-log-creation-time>
<access>
<encoding>xml</encoding>
<location>https://example.com/streams/NETCONF\
</location>
</access>
<access>
<encoding>json</encoding>
<location>https://example.com/streams/NETCONF-JSON\
</location>
</access>
</stream>
<stream>
<name>SNMP</name>
<description>SNMP notifications</description>
<replay-support>false</replay-support>
<access>
<encoding>xml</encoding>
<location>https://example.com/streams/SNMP</location>
</access>
</stream>
<stream>
<name>syslog-critical</name>
<description>Critical and higher severity</description>
<replay-support>true</replay-support>
<replay-log-creation-time>
2007-07-01T00:00:00Z
</replay-log-creation-time>
<access>
<encoding>xml</encoding>
<location>\
https://example.com/streams/syslog-critical\
</location>
</access>
</stream>
</streams>
6.3. Subscribing to Receive Notifications 💌
RESTCONF clients can work out the URL for the subscription resource (the one that receives notifications) by sending an HTTP GET request for the "location" leaf with the "stream" list entry. Then the value the server returns can be used for the actual notification subscription 🎀
The client will send an HTTP GET request for the URL the server returned, with the "Accept" type "text/event-stream". The server will treat that connection as an event stream, using the Server-Sent Events [W3C.REC-eventsource-20150203] transport strategy. Lowkey the cleanest handshake ever 🔥
The server MAY support query parameters for a GET method on this resource. These parameters are specific to each event stream.
For example:
The client might send the following request:
GET /restconf/data/ietf-restconf-monitoring:restconf-state/\
streams/stream=NETCONF/access=xml/location HTTP/1.1
Host: example.com
Accept: application/yang-data+xml
The server might send the following response:
HTTP/1.1 200 OK
Content-Type: application/yang-data+xml
<location
xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf-monitoring">\
https://example.com/streams/NETCONF\
</location>
The RESTCONF client can then use this URL value to start monitoring the event stream:
GET /streams/NETCONF HTTP/1.1
Host: example.com
Accept: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
A RESTCONF client MAY request that the server compress the events by using the HTTP header field "Accept-Encoding". For instance:
GET /streams/NETCONF HTTP/1.1
Host: example.com
Accept: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
Accept-Encoding: gzip, deflate
6.3.1. NETCONF Event Stream 🧁
The server SHOULD support the NETCONF event stream defined in Section 3.2.3 of [RFC5277]. The notification messages for this stream are encoded in XML.
The server MAY support additional streams that represent the semantic content of the NETCONF event stream, but using a representation with a different media type. Main character energy 👑
The server MAY support the "start-time", "stop-time", and "filter" query parameters, defined in Section 4.8. Refer to Appendix B.3.6 for filter parameter examples 📚
6.4. Receiving Event Notifications 🦄
RESTCONF notifications are encoded according to the definition of the event stream. The structure of the event data is based on the <notification> element definition in Section 4 of [RFC5277]. It MUST conform to the schema for the <notification> element in Section 4 of [RFC5277], using the XML namespace as defined in the XSD as follows:
urn:ietf:params:xml:ns:netconf:notification:1.0
For JSON-encoding purposes, the module name for the "notification" element is "ietf-restconf".
Two child nodes within the "notification" container are expected, representing the event time and the event payload. The "eventTime" node is defined within the same XML namespace as the <notification> element. It is defined to be within the "ietf-restconf" module namespace for JSON-encoding purposes.
The name and namespace of the payload element are determined by the YANG module containing the notification-stmt representing the notification message.
In the following example, the YANG module "example-mod" is used:
module example-mod {
namespace "http://example.com/event/1.0";
prefix ex;
organization "Example, Inc.";
contact "support at example.com";
description "Example Notification Data Model Module.";
revision "2016-07-07" {
description "Initial version.";
reference "example.com document 2-9976.";
}
notification event {
description "Example notification event.";
leaf event-class {
type string;
description "Event class identifier.";
}
container reporting-entity {
description "Event specific information.";
leaf card {
type string;
description "Line card identifier.";
}
}
leaf severity {
type string;
description "Event severity description.";
}
}
}
An example SSE event notification encoded using XML:
data: <notification
data: xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
data: <eventTime>2013-12-21T00:01:00Z</eventTime>
data: <event xmlns="http://example.com/event/1.0">
data: <event-class>fault</event-class>
data: <reporting-entity>
data: <card>Ethernet0</card>
data: </reporting-entity>
data: <severity>major</severity>
data: </event>
data: </notification>
An example SSE event notification encoded using JSON:
data: {
data: "ietf-restconf:notification" : {
data: "eventTime" : "2013-12-21T00:01:00Z",
data: "example-mod:event" : {
data: "event-class" : "fault",
data: "reporting-entity" : { "card" : "Ethernet0" },
data: "severity" : "major"
data: }
data: }
data: }
Alternatively, since neither XML nor JSON is whitespace sensitive, the above messages can be encoded onto a single line. For example:
XML:
data: <notification xmlns="urn:ietf:params:xml:ns:netconf:notif\
ication:1.0"><eventTime>2013-12-21T00:01:00Z</eventTime><event \
xmlns="http://example.com/event/1.0"><event-class>fault</event-\
class><reportingEntity><card>Ethernet0</card></reporting-entity>\
<severity>major</severity></event></notification>
JSON:
data: {"ietf-restconf:notification":{"eventTime":"2013-12-21\
T00:01:00Z","example-mod:event":{"event-class": "fault","repor\
tingEntity":{"card":"Ethernet0"},"severity":"major"}}}
The SSE specification supports the following additional fields: "event", "id", and "retry". A RESTCONF server MAY send the "retry" field, and if it does, RESTCONF clients SHOULD use it. A RESTCONF server SHOULD NOT send the "event" or "id" fields, as there are no meaningful values that could be used for them that would not be redundant to the contents of the notification itself. RESTCONF servers that do not send the "id" field also do not need to support the HTTP header field "Last-Event-ID" [W3C.REC-eventsource-20150203]. RESTCONF servers that do send the "id" field SHOULD support the "start-time" query parameter as the preferred means for a client to specify where to restart the event stream. Restart energy, but make it iconic ✨💖
7. Error Reporting ✨
Okay bestie, this is the part where things go wrong and we figure out how to tell the client about it 🥺💅. HTTP status codes are how RESTCONF says "yay, it worked" or "nope, here's what happened" 🎀. The error info that NETCONF puts inside its <rpc-error> element gets glammed up for RESTCONF, and the <errors> data tree shows up for the "4xx" and "5xx" status code classes 🦋.
Here's the tricky bit 🙈. An operation resource is defined with a YANG "rpc" statement, and an action is defined with a YANG "action" statement, so we need a mapping from the NETCONF <error-tag> value to an HTTP status code. Which error-tag and response code you use is specific to the data model, and it might be written in the YANG "description" statement for the "action" or "rpc" statement 💜. So go check there, no cap 👑.
Here's the mapping table, so you can screenshot it and never be confused again 📸✨
+-------------------------+------------------+
| error-tag | status code |
+-------------------------+------------------+
| in-use | 409 |
| | |
| invalid-value | 400, 404, or 406 |
| | |
| (request) too-big | 413 |
| | |
| (response) too-big | 400 |
| | |
| missing-attribute | 400 |
| | |
| bad-attribute | 400 |
| | |
| unknown-attribute | 400 |
| | |
| bad-element | 400 |
| | |
| unknown-element | 400 |
| | |
| unknown-namespace | 400 |
| | |
| access-denied | 401 or 403 |
| | |
| lock-denied | 409 |
| | |
| resource-denied | 409 |
| | |
| rollback-failed | 500 |
| | |
| data-exists | 409 |
| | |
| data-missing | 409 |
| | |
| operation-not-supported | 405 or 501 |
| | |
| operation-failed | 412 or 500 |
| | |
| partial-operation | 500 |
| | |
| malformed-message | 400 |
+-------------------------+------------------+
Mapping from <error-tag> to Status Code
7.1. Error Response Message 💌
Time for the error message itself 💖. When an error happens for a request message on any resource type, and the status code that's going back is in the "4xx" range (except for "403 Forbidden"), the server SHOULD send a response message-body with the info described by the "yang-errors" YANG data template in the "ietf-restconf" module, which you'll find in Section 8 🌸. The Content-Type of that response MUST be "application/yang-data", and you can optionally add a structured syntax name suffix 🧚.
The client SHOULD say which encoding(s) it wants for responses by using the right media type(s) in the "Accept" header 🫶. If the client didn't send an "Accept" header, then the server SHOULD use the same structured syntax name suffix that was in the request message, or the server MAY pick any supported message-encoding format 🦋. If there's no request message at all, the server MUST select "application/yang-data+xml" or "application/yang-data+json", depending on what the server prefers 🎀. All of the examples in this document assume XML encoding will be returned if there's an error, except for the one below 🙈.
Here's the YANG tree diagram for the <errors> data 🌳:
+---- errors
+---- error*
+---- error-type enumeration
+---- error-tag string
+---- error-app-tag? string
+---- error-path? instance-identifier
+---- error-message? string
+---- error-info?
The semantics and syntax for RESTCONF error messages are defined with the "yang-errors" YANG data template extension, which is in Section 8 💅.
Examples time, my favorite part 😭✨
Okay so this first one is a "lock-denied" error. That happens when a NETCONF client has locked a datastore. The RESTCONF client is trying to delete a data resource here. Notice the "Accept" header field, which is how the client picks the encoding for the error message 💜. And if this operation had worked, there would be no response message-body content at all 🌈.
DELETE /restconf/data/example-jukebox:jukebox/\
library/artist=Foo%20Fighters/album=Wasting%20Light HTTP/1.1
Host: example.com
Accept: application/yang-data+json
The server might respond like this 🙈:
HTTP/1.1 409 Conflict
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Content-Type: application/yang-data+json
{
"ietf-restconf:errors" : {
"error" : [
{
"error-type" : "protocol",
"error-tag" : "lock-denied",
"error-message" : "Lock failed; lock already held"
}
]
}
}
Next up is a "data-exists" error on a data resource 🍓. The "jukebox" resource already exists, so the client can't create it again, bestie 💀.
The client might send this 📨:
POST /restconf/data/example-jukebox:jukebox HTTP/1.1
Host: example.com
The server might respond like this 🎀:
HTTP/1.1 409 Conflict
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Content-Type: application/yang-data+xml
<errors xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf">
<error>
<error-type>protocol</error-type>
<error-tag>data-exists</error-tag>
<error-path
xmlns:rc="urn:ietf:params:xml:ns:yang:ietf-restconf"
xmlns:jbox="https://example.com/ns/example-jukebox">\
/rc:restconf/rc:data/jbox:jukebox
</error-path>
<error-message>
Data already exists; cannot create new resource
</error-message>
</error>
</errors>
That's the whole error reporting section, iconic behavior from the RESTCONF spec 👑🦋 More to come in the next part, so stay tuned, bestie 💜✨
8. RESTCONF Module ✨
okay so section 8 is where the "ietf-restconf" module lives 💖 it's basically a set of conceptual definitions (one extension and two groupings) that are not meant to be stored as datastore contents on a server 🎀 like, the "restconf" container is not supposed to show up as a top-level data node under the "/restconf/data" URI 🙈
ngl the module doesn't have any protocol-accessible objects, so there's no YANG tree diagram for it 🦋 here's the whole thing, slay:
file "ietf-restconf@2017-01-26.yang"
module ietf-restconf {
yang-version 1.1;
namespace "urn:ietf:params:xml:ns:yang:ietf-restconf";
prefix "rc";
organization
"IETF NETCONF (Network Configuration) Working Group";
contact
"WG Web: <https://datatracker.ietf.org/wg/netconf/>
WG List: <mailto:netconf@ietf.org>
Author: Andy Bierman
<mailto:andy@yumaworks.com>
Author: Martin Bjorklund
<mailto:mbj@tail-f.com>
Author: Kent Watsen
<mailto:kwatsen@juniper.net>";
description
"This module contains conceptual YANG specifications
for basic RESTCONF media type definitions used in
RESTCONF protocol messages.
Note that the YANG definitions within this module do not
represent configuration data of any kind.
The 'restconf-media-type' YANG extension statement
provides a normative syntax for XML and JSON
message-encoding purposes.
Copyright (c) 2017 IETF Trust and the persons identified as
authors of the code. All rights reserved.
Redistribution and use in source and binary forms, with or
without modification, is permitted pursuant to, and subject
to the license terms contained in, the Simplified BSD License
set forth in Section 4.c of the IETF Trust's Legal Provisions
Relating to IETF Documents
(http://trustee.ietf.org/license-info).
This version of this YANG module is part of RFC 8040; see
the RFC itself for full legal notices.";
revision 2017-01-26 {
description
"Initial revision.";
reference
"RFC 8040: RESTCONF Protocol.";
}
extension yang-data {
argument name {
yin-element true;
}
description
"This extension is used to specify a YANG data template that
represents conceptual data defined in YANG. It is
intended to describe hierarchical data independent of
protocol context or specific message-encoding format.
Data definition statements within a yang-data extension
specify the generic syntax for the specific YANG data
template, whose name is the argument of the 'yang-data'
extension statement.
Note that this extension does not define a media type.
A specification using this extension MUST specify the
message-encoding rules, including the content media type.
The mandatory 'name' parameter value identifies the YANG
data template that is being defined. It contains the
template name.
This extension is ignored unless it appears as a top-level
statement. It MUST contain data definition statements
that result in exactly one container data node definition.
An instance of a YANG data template can thus be translated
into an XML instance document, whose top-level element
corresponds to the top-level container.
The module name and namespace values for the YANG module using
the extension statement are assigned to instance document data
conforming to the data definition statements within
this extension.
The substatements of this extension MUST follow the
'data-def-stmt' rule in the YANG ABNF.
The XPath document root is the extension statement itself,
such that the child nodes of the document root are
represented by the data-def-stmt substatements within
this extension. This conceptual document is the context
for the following YANG statements:
- must-stmt
- when-stmt
- path-stmt
- min-elements-stmt
- max-elements-stmt
- mandatory-stmt
- unique-stmt
- ordered-by
- instance-identifier data type
The following data-def-stmt substatements are constrained
when used within a 'yang-data' extension statement.
- The list-stmt is not required to have a key-stmt defined.
- The if-feature-stmt is ignored if present.
- The config-stmt is ignored if present.
- The available identity values for any 'identityref'
leaf or leaf-list nodes are limited to the module
containing this extension statement and the modules
imported into that module.
";
}
rc:yang-data yang-errors {
uses errors;
}
rc:yang-data yang-api {
uses restconf;
}
grouping errors {
description
"A grouping that contains a YANG container
representing the syntax and semantics of a
YANG Patch error report within a response message.";
container errors {
description
"Represents an error report returned by the server if
a request results in an error.";
list error {
description
"An entry containing information about one
specific error that occurred while processing
a RESTCONF request.";
reference
"RFC 6241, Section 4.3.";
leaf error-type {
type enumeration {
enum transport {
description
"The transport layer.";
}
enum rpc {
description
"The rpc or notification layer.";
}
enum protocol {
description
"The protocol operation layer.";
}
enum application {
description
"The server application layer.";
}
}
mandatory true;
description
"The protocol layer where the error occurred.";
}
leaf error-tag {
type string;
mandatory true;
description
"The enumerated error-tag.";
}
leaf error-app-tag {
type string;
description
"The application-specific error-tag.";
}
leaf error-path {
type instance-identifier;
description
"The YANG instance identifier associated
with the error node.";
}
leaf error-message {
type string;
description
"A message describing the error.";
}
anydata error-info {
description
"This anydata value MUST represent a container with
zero or more data nodes representing additional
error information.";
}
}
}
}
grouping restconf {
description
"Conceptual grouping representing the RESTCONF
root resource.";
container restconf {
description
"Conceptual container representing the RESTCONF
root resource.";
container data {
description
"Container representing the datastore resource.
Represents the conceptual root of all state data
and configuration data supported by the server.
The child nodes of this container can be any data
resources that are defined as top-level data nodes
from the YANG modules advertised by the server in
the 'ietf-yang-library' module.";
}
container operations {
description
"Container for all operation resources.
Each resource is represented as an empty leaf with the
name of the RPC operation from the YANG 'rpc' statement.
For example, the 'system-restart' RPC operation defined
in the 'ietf-system' module would be represented as
an empty leaf in the 'ietf-system' namespace. This is
a conceptual leaf and will not actually be found in
the module:
module ietf-system {
leaf system-reset {
type empty;
}
}
To invoke the 'system-restart' RPC operation:
POST /restconf/operations/ietf-system:system-restart
To discover the RPC operations supported by the server:
GET /restconf/operations
In XML, the YANG module namespace identifies the module:
<system-restart
xmlns='urn:ietf:params:xml:ns:yang:ietf-system'/>
In JSON, the YANG module name identifies the module:
{ 'ietf-system:system-restart' : [null] }
";
}
leaf yang-library-version {
type string {
pattern '\d{4}-\d{2}-\d{2}';
}
config false;
mandatory true;
description
"Identifies the revision date of the 'ietf-yang-library'
module that is implemented by this RESTCONF server.
Indicates the year, month, and day in YYYY-MM-DD
numeric format.";
}
}
}
}
9. RESTCONF Monitoring
the "ietf-restconf-monitoring" module is the one that tells you what RESTCONF protocol capabilities and event streams the server has available 👑 and a RESTCONF server MUST implement it, no exceptions 💅 here's the tree:
+--ro restconf-state
+--ro capabilities
| +--ro capability* inet:uri
+--ro streams
+--ro stream* [name]
+--ro name string
+--ro description? string
+--ro replay-support? boolean
+--ro replay-log-creation-time? yang:date-and-time
+--ro access* [encoding]
+--ro encoding string
+--ro location inet:uri
9.1. restconf-state/capabilities
this one is a mandatory container and it holds the RESTCONF protocol capability URIs the server supports 🌸
the server MAY maintain a last-modified timestamp for this container, and if it does, it can return the Last-Modified header field when this data node is retrieved with the GET or HEAD methods 🧚 but heads up, the last-modified timestamp for the datastore resource is not affected by changes to this subtree, so don't mix them up 🙈
the server SHOULD maintain an entity-tag for this container and return the ETag header field when this data node is retrieved with the GET or HEAD methods 💖 same deal here: the entity-tag for the datastore resource is not affected by changes to this subtree 🎀
the server MUST include a "capability" URI leaf-list entry for the "defaults" mode it uses, which is defined in Section 9.1.2 🫶
the server MUST include a "capability" URI leaf-list entry identifying each supported optional protocol feature 🔥 this includes optional query parameters, and it MAY include other capability URIs that are defined outside this document ✨
9.1.1. Query Parameter URIs ✨
okay so this part is giving capability spotlight 🎀 RESTCONF defines a bunch of Capability URIs, one for each query parameter from Section 4.8 that a server supports, so clients can check what the server can actually do. 💅
the server MUST include a "capability" leaf-list entry for each optional query parameter it supports. no skipping 🫶
Name | Section | URI
---------------+---------+------------------------------------------
depth | 4.8.2 | urn:ietf:params:restconf:capability:
| | depth:1.0
fields | 4.8.3 | urn:ietf:params:restconf:capability:
| | fields:1.0
filter | 4.8.4 | urn:ietf:params:restconf:capability:
| | filter:1.0
replay | 4.8.7 | urn:ietf:params:restconf:capability:
| 4.8.8 | replay:1.0
with-defaults | 4.8.9 | urn:ietf:params:restconf:capability:
| | with-defaults:1.0
RESTCONF Query Parameter URIs 🌸
9.1.2. The "defaults" Protocol Capability URI 🦋
this URI tells you which "basic-mode" default-handling mode the server uses when it processes default leafs in requests for data resources. this one is a big deal: the server MUST support it, and it MUST be listed in the "capability" leaf-list from Section 9.3. not optional, bestie 🙈
Name | URI
---------+--------------------------------------------------
defaults | urn:ietf:params:restconf:capability:defaults:1.0
RESTCONF "defaults" Capability URI 🍓
the URI MUST contain a query parameter named "basic-mode", and it has to be set to one of these values:
Value | Description
-----------+------------------------------------------------------
report-all | No data nodes are considered default
|
trim | Values set to the YANG default-stmt value are
| default
|
explicit | Values set by the client are never considered
| default
the "basic-mode" definitions come from "With-defaults Capability for NETCONF" [RFC6243], so go check that one if you want the full tea ☕
here's how each mode behaves:
- if "basic-mode" is set to "report-all", the server MUST follow the default-handling behavior in Section 2.1 of [RFC6243] 💖
- if "basic-mode" is set to "trim", the server MUST follow the default-handling behavior in Section 2.2 of [RFC6243] 🧚
- if "basic-mode" is set to "explicit", the server MUST follow the default-handling behavior in Section 2.3 of [RFC6243] 👑
example (split for display purposes only, it's one long URI 😭):
urn:ietf:params:restconf:capability:defaults:1.0?
basic-mode=explicit
9.2. restconf-state/streams 🌈
this container is optional, and it gives you access to the event streams the server supports. the server MAY omit it if no event streams are supported, so no stress if it's not there 🫶
the server populates this container with a "stream" list entry for every stream type it supports. each stream has a leaf called "events", and that leaf holds a URI for an event stream resource. stream resources are in Section 3.8, and notifications are in Section 6, so you know where to look 🔥
9.3. RESTCONF Monitoring Module 💜
the "ietf-restconf-monitoring" module is where the RESTCONF monitoring info lives. it borrows some type definitions from the "ietf-yang-types" and "ietf-inet-types" modules, both from [RFC6991] 🍓
here's the whole module, copied exactly:
<CODE BEGINS>
file "ietf-restconf-monitoring@2017-01-26.yang"
module ietf-restconf-monitoring {
namespace "urn:ietf:params:xml:ns:yang:ietf-restconf-monitoring";
prefix "rcmon";
import ietf-yang-types { prefix yang; }
import ietf-inet-types { prefix inet; }
organization
"IETF NETCONF (Network Configuration) Working Group";
contact
"WG Web: <https://datatracker.ietf.org/wg/netconf/>
WG List: <mailto:netconf@ietf.org>
Author: Andy Bierman
<mailto:andy@yumaworks.com>
Author: Martin Bjorklund
<mailto:mbj@tail-f.com>
Author: Kent Watsen
<mailto:kwatsen@juniper.net>";
description
"This module contains monitoring information for the
RESTCONF protocol.
Copyright (c) 2017 IETF Trust and the persons identified as
authors of the code. All rights reserved.
Redistribution and use in source and binary forms, with or
without modification, is permitted pursuant to, and subject
to the license terms contained in, the Simplified BSD License
set forth in Section 4.c of the IETF Trust's Legal Provisions
Relating to IETF Documents
(http://trustee.ietf.org/license-info).
This version of this YANG module is part of RFC 8040; see
the RFC itself for full legal notices.";
revision 2017-01-26 {
description
"Initial revision.";
reference
"RFC 8040: RESTCONF Protocol.";
}
container restconf-state {
config false;
description
"Contains RESTCONF protocol monitoring information.";
container capabilities {
description
"Contains a list of protocol capability URIs.";
leaf-list capability {
type inet:uri;
description
"A RESTCONF protocol capability URI.";
}
}
container streams {
description
"Container representing the notification event streams
supported by the server.";
reference
"RFC 5277, Section 3.4, <streams> element.";
list stream {
key name;
description
"Each entry describes an event stream supported by
the server.";
leaf name {
type string;
description
"The stream name.";
reference
"RFC 5277, Section 3.4, <name> element.";
}
leaf description {
type string;
description
"Description of stream content.";
reference
"RFC 5277, Section 3.4, <description> element.";
}
leaf replay-support {
type boolean;
default false;
description
"Indicates if replay buffer is supported for this stream.
If 'true', then the server MUST support the 'start-time'
and 'stop-time' query parameters for this stream.";
reference
"RFC 5277, Section 3.4, <replaySupport> element.";
}
leaf replay-log-creation-time {
when "../replay-support" {
description
"Only present if notification replay is supported.";
}
type yang:date-and-time;
description
"Indicates the time the replay log for this stream
was created.";
reference
"RFC 5277, Section 3.4, <replayLogCreationTime>
element.";
}
list access {
key encoding;
min-elements 1;
description
"The server will create an entry in this list for each
encoding format that is supported for this stream.
The media type 'text/event-stream' is expected
for all event streams. This list identifies the
subtypes supported for this stream.";
leaf encoding {
type string;
description
"This is the secondary encoding format within the
'text/event-stream' encoding used by all streams.
The type 'xml' is supported for XML encoding.
The type 'json' is supported for JSON encoding.";
}
leaf location {
type inet:uri;
mandatory true;
description
"Contains a URL that represents the entry point
for establishing notification delivery via
server-sent events.";
}
}
}
}
}
}
<CODE ENDS>
10. YANG Module Library 📚
the "ietf-yang-library" module from [RFC7895] tells you which YANG modules and submodules the RESTCONF server uses. implementing it is mandatory for RESTCONF servers, and every YANG module and submodule the server uses MUST be identified in the YANG module library. main character energy 👑
10.1. modules-state/module 🎀
this mandatory list has one entry for each YANG data model module the server supports. there MUST be an instance of this list for every YANG module the server uses 💅
the contents of this list are defined in the "module" YANG list statement in [RFC7895] ✨
note that the "ietf-restconf" module doesn't have any protocol-accessible objects to implement. still, a server might list it in the YANG library if an implemented module imports it, either directly or indirectly 🦋
11. IANA Considerations 🌸
11.1. The "restconf" Relation Type 💖
this spec registers the "restconf" relation type in the "Link Relation Types" registry that [RFC5988] defines:
Relation Name: restconf
Description: Identifies the root of the RESTCONF API as configured
on this HTTP server. The "restconf" relation
defines the root of the API defined in RFC 8040.
Subsequent revisions of RESTCONF will use alternate
relation values to support protocol versioning.
Reference: RFC 8040
11.2. Registrations for New URIs and YANG Modules
okay so this bit is where IANA gets the paperwork done 📝 this doc registers two URIs as namespaces in the "IETF XML Registry" [RFC3688] 🎀
URI: urn:ietf:params:xml:ns:yang:ietf-restconf
Registrant Contact: The IESG.
XML: N/A; the requested URI is an XML namespace.
URI: urn:ietf:params:xml:ns:yang:ietf-restconf-monitoring
Registrant Contact: The IESG.
XML: N/A; the requested URI is an XML namespace.
and it also registers two YANG modules in the "YANG Module Names" registry [RFC6020] 💜
name: ietf-restconf
namespace: urn:ietf:params:xml:ns:yang:ietf-restconf
prefix: rc
reference: RFC 8040
name: ietf-restconf-monitoring
namespace: urn:ietf:params:xml:ns:yang:ietf-restconf-monitoring
prefix: rcmon
reference: RFC 8040
11.3. Media Types
11.3.1. Media Type "application/yang-data+xml"
this one is the XML media type, and the template is giving very official vibes 💅
Type name: application
Subtype name: yang-data+xml
Required parameters: None
Optional parameters: None
Encoding considerations: 8-bit
Each conceptual YANG data node is encoded according to the
XML Encoding Rules and Canonical Format for the specific
YANG data node type defined in [RFC7950].
Security considerations: Security considerations related
to the generation and consumption of RESTCONF messages
are discussed in Section 12 of RFC 8040.
Additional security considerations are specific to the
semantics of particular YANG data models. Each YANG module
is expected to specify security considerations for the
YANG data defined in that module.
Interoperability considerations: RFC 8040 specifies the
format of conforming messages and the interpretation
thereof.
Published specification: RFC 8040
Applications that use this media type: Instance document
data parsers used within a protocol or automation tool
that utilize YANG-defined data structures.
Fragment identifier considerations: Fragment identifiers for
this type are not defined. All YANG data nodes are
accessible as resources using the path in the request URI.
Additional information:
Deprecated alias names for this type: N/A
Magic number(s): N/A
File extension(s): None
Macintosh file type code(s): "TEXT"
Person & email address to contact for further information: See
the Authors' Addresses section of RFC 8040.
Intended usage: COMMON
Restrictions on usage: N/A
Author: See the Authors' Addresses section of RFC 8040.
Change controller: Internet Engineering Task Force
(mailto:iesg@ietf.org).
Provisional registration? (standards tree only): no
11.3.2. Media Type "application/yang-data+json"
the JSON sibling, same energy but it's got its own encoding stuff 🦋
Type name: application
Subtype name: yang-data+json
Required parameters: None
Optional parameters: None
Encoding considerations: 8-bit
Each conceptual YANG data node is encoded according to
[RFC7951]. A metadata annotation is encoded according to
[RFC7952].
Security considerations: Security considerations related
to the generation and consumption of RESTCONF messages
are discussed in Section 12 of RFC 8040.
Additional security considerations are specific to the
semantics of particular YANG data models. Each YANG module
is expected to specify security considerations for the
YANG data defined in that module.
Interoperability considerations: RFC 8040 specifies the format
of conforming messages and the interpretation thereof.
Published specification: RFC 8040
Applications that use this media type: Instance document
data parsers used within a protocol or automation tool
that utilize YANG-defined data structures.
Fragment identifier considerations: The syntax and semantics
of fragment identifiers are the same as the syntax and semantics
specified for the "application/json" media type.
Additional information:
Deprecated alias names for this type: N/A
Magic number(s): N/A
File extension(s): None
Macintosh file type code(s): "TEXT"
Person & email address to contact for further information: See
the Authors' Addresses section of RFC 8040.
Intended usage: COMMON
Restrictions on usage: N/A
Author: See the Authors' Addresses section of RFC 8040.
Change controller: Internet Engineering Task Force
(mailto:iesg@ietf.org).
Provisional registration? (standards tree only): no
11.4. RESTCONF Capability URNs
so this doc sets up a registry for RESTCONF capability identifiers 🌸 it's called "RESTCONF Capability URNs", and the review policy is "IETF Review" [RFC5226]. the registry shall record the following for each entry:
- the name of the RESTCONF capability. by convention, this name begins with the colon (":") character.
- the URN for the RESTCONF capability.
- the reference for the document registering the value.
and this doc registers a bunch of capability identifiers in that registry, which is literally the best part 🧚
Index Capability Identifier
---------------------------------------------------------------------
:defaults urn:ietf:params:restconf:capability:defaults:1.0
:depth urn:ietf:params:restconf:capability:depth:1.0
:fields urn:ietf:params:restconf:capability:fields:1.0
:filter urn:ietf:params:restconf:capability:filter:1.0
:replay urn:ietf:params:restconf:capability:replay:1.0
:with-defaults urn:ietf:params:restconf:capability:with-defaults:1.0
11.5. Registration of "restconf" URN Sub-namespace
IANA also registered a brand new URN sub-namespace in the "IETF URN Sub-namespace for Registered Protocol Parameter Identifiers" registry from [RFC3553] ✨ the details look like this:
Registry Name: restconf
Specification: RFC 8040
Repository: "RESTCONF Capability URNs" registry (Section 11.4)
Index value: Sub-parameters MUST be specified in UTF-8, using
standard URI encoding where necessary.
12. Security Considerations 🔥
okay this is the serious section, bestie, so let's be dramatic about it 💀
Section 2.1 says that "a RESTCONF server MUST support the TLS protocol [RFC5246]." that wording leaves the door open for a RESTCONF server to also support future versions of TLS. the big concern is TLS 1.3 [TLS1.3], which brings in 0-RTT handshakes. those can lead to security issues for RESTCONF APIs, as covered in Appendix B.1 of the TLS 1.3 document 🙈 so it is therefore RECOMMENDED that RESTCONF servers do not support 0-RTT at all (not even for idempotent requests) until an update to this RFC says otherwise.
Section 2.5 recommends authentication based on TLS client certificates, but it also allows any authentication scheme from the "Hypertext Transfer Protocol (HTTP) Authentication Scheme Registry". implementations need to be aware that these methods vary a lot in strength, and some may be considered experimental. picking any of these schemes SHOULD be done only after reading the Security Considerations section of the RFC linked to that scheme's registry entry.
the "ietf-restconf-monitoring" YANG module from this memo is built to be accessed through the NETCONF protocol [RFC6241]. the lowest NETCONF layer is the secure transport layer, and the mandatory-to-implement secure transport is Secure Shell (SSH) [RFC6242]. the NETCONF access control model [RFC6536] gives you the tools to restrict particular NETCONF users to a preconfigured subset of all the NETCONF protocol operations and content ✨
the lowest RESTCONF layer is HTTPS, and the mandatory-to-implement secure transport is TLS [RFC5246]. RESTCONF uses the NETCONF access control model [RFC6536], which lets you restrict particular RESTCONF users to a preconfigured subset of all the available RESTCONF protocol operations and content 🦋
this section covers security considerations for the resources RESTCONF defines. security considerations for HTTPS are in [RFC7230]. apart from the "ietf-restconf-monitoring" module (Section 9) and the "ietf-yang-library" module (Section 10), RESTCONF doesn't specify which YANG modules a server needs to support. the security considerations for the other modules RESTCONF manipulates live in the documents that define those modules 🎀
configuration info is sensitive by its very nature 😭 if it's sent in the clear with no integrity checking, devices are wide open to classic eavesdropping and false data injection attacks. config often holds passwords, user names, service descriptions, and topology info, and all of that is sensitive. many attack patterns have been spotted through real operational experience with existing management interfaces, so it would be wise for implementers to research them and take them into account when implementing this protocol 👑
different environments may well allow different rights before and after authentication. when a RESTCONF operation is not properly authorized, the RESTCONF server MUST return a 401 Unauthorized status-line. authorization info can itself be sent as configuration info, which is all the more reason to lock down the connection 🔐 and it's possible for a client to notice configuration changes in data resources it isn't authorized to access, just by watching the ETag and Last-Modified header fields the server returns for the datastore resource 👀
a RESTCONF server implementation SHOULD try to prevent system disruption from excessive resource consumption needed to fulfill edit requests via the POST, PUT, and PATCH methods 💅 and on an implementation like that, it may be possible to construct an attack that tries to eat all the available memory or other resource types 💀
13. References 📚
13.1. Normative References 📚
Okay bestie, these are the normative refs, the ones you actually need to have read 💖
- [RFC2046] Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types", RFC 2046,
DOI 10.17487/RFC2046, November 1996,<http://www.rfc-editor.org/info/rfc2046>. - [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,<http://www.rfc-editor.org/info/rfc2119>. - [RFC3553] Mealling, M., Masinter, L., Hardie, T., and G. Klyne, "An IETF URN Sub-namespace for Registered Protocol Parameters", BCP 73, RFC 3553,
DOI 10.17487/RFC3553, June 2003,<http://www.rfc-editor.org/info/rfc3553>. - [RFC3688] Mealling, M., "The IETF XML Registry", BCP 81, RFC 3688,
DOI 10.17487/RFC3688, January 2004,<http://www.rfc-editor.org/info/rfc3688>. - [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986,
DOI 10.17487/RFC3986, January 2005,<http://www.rfc-editor.org/info/rfc3986>. - [RFC5234] Crocker, D., Ed., and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234,
DOI 10.17487/RFC5234, January 2008,<http://www.rfc-editor.org/info/rfc5234>. - [RFC5246] Dierks, T. and E. Rescorla, "The Transport Layer Security (TLS) Protocol Version 1.2", RFC 5246,
DOI 10.17487/RFC5246, August 2008,<http://www.rfc-editor.org/info/rfc5246>. - [RFC5277] Chisholm, S. and H. Trevino, "NETCONF Event Notifications", RFC 5277,
DOI 10.17487/RFC5277, July 2008,<http://www.rfc-editor.org/info/rfc5277>. - [RFC5280] Cooper, D., Santesson, S., Farrell, S., Boeyen, S., Housley, R., and W. Polk, "Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 5280,
DOI 10.17487/RFC5280, May 2008,<http://www.rfc-editor.org/info/rfc5280>. - [RFC5789] Dusseault, L. and J. Snell, "PATCH Method for HTTP", RFC 5789,
DOI 10.17487/RFC5789, March 2010,<http://www.rfc-editor.org/info/rfc5789>. - [RFC5988] Nottingham, M., "Web Linking", RFC 5988,
DOI 10.17487/RFC5988, October 2010,<http://www.rfc-editor.org/info/rfc5988>. - [RFC6020] Bjorklund, M., Ed., "YANG - A Data Modeling Language for the Network Configuration Protocol (NETCONF)", RFC 6020,
DOI 10.17487/RFC6020, October 2010,<http://www.rfc-editor.org/info/rfc6020>. - [RFC6241] Enns, R., Ed., Bjorklund, M., Ed., Schoenwaelder, J., Ed., and A. Bierman, Ed., "Network Configuration Protocol (NETCONF)", RFC 6241,
DOI 10.17487/RFC6241, June 2011,<http://www.rfc-editor.org/info/rfc6241>. - [RFC6242] Wasserman, M., "Using the NETCONF Protocol over Secure Shell (SSH)", RFC 6242,
DOI 10.17487/RFC6242, June 2011,<http://www.rfc-editor.org/info/rfc6242>. - [RFC6243] Bierman, A. and B. Lengyel, "With-defaults Capability for NETCONF", RFC 6243,
DOI 10.17487/RFC6243, June 2011,<http://www.rfc-editor.org/info/rfc6243>. - [RFC6415] Hammer-Lahav, E., Ed., and B. Cook, "Web Host Metadata", RFC 6415,
DOI 10.17487/RFC6415, October 2011,<http://www.rfc-editor.org/info/rfc6415>. - [RFC6536] Bierman, A. and M. Bjorklund, "Network Configuration Protocol (NETCONF) Access Control Model", RFC 6536,
DOI 10.17487/RFC6536, March 2012,<http://www.rfc-editor.org/info/rfc6536>. - [RFC6570] Gregorio, J., Fielding, R., Hadley, M., Nottingham, M., and D. Orchard, "URI Template", RFC 6570,
DOI 10.17487/RFC6570, March 2012,<http://www.rfc-editor.org/info/rfc6570>. - [RFC6991] Schoenwaelder, J., Ed., "Common YANG Data Types", RFC 6991,
DOI 10.17487/RFC6991, July 2013,<http://www.rfc-editor.org/info/rfc6991>. - [RFC7159] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", RFC 7159,
DOI 10.17487/RFC7159, March 2014,<http://www.rfc-editor.org/info/rfc7159>. - [RFC7230] Fielding, R., Ed., and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing", RFC 7230,
DOI 10.17487/RFC7230, June 2014,<http://www.rfc-editor.org/info/rfc7230>. - [RFC7231] Fielding, R., Ed., and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content", RFC 7231,
DOI 10.17487/RFC7231, June 2014,<http://www.rfc-editor.org/info/rfc7231>. - [RFC7232] Fielding, R., Ed., and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests", RFC 7232,
DOI 10.17487/RFC7232, June 2014,<http://www.rfc-editor.org/info/rfc7232>. - [RFC7235] Fielding, R., Ed., and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Authentication", RFC 7235,
DOI 10.17487/RFC7235, June 2014,<http://www.rfc-editor.org/info/rfc7235>. - [RFC7320] Nottingham, M., "URI Design and Ownership", BCP 190, RFC 7320,
DOI 10.17487/RFC7320, July 2014,<http://www.rfc-editor.org/info/rfc7320>. - [RFC7525] Sheffer, Y., Holz, R., and P. Saint-Andre, "Recommendations for Secure Use of Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS)", BCP 195, RFC 7525,
DOI 10.17487/RFC7525, May 2015,<http://www.rfc-editor.org/info/rfc7525>. - [RFC7589] Badra, M., Luchuk, A., and J. Schoenwaelder, "Using the NETCONF Protocol over Transport Layer Security (TLS) with Mutual X.509 Authentication", RFC 7589,
DOI 10.17487/RFC7589, June 2015,<http://www.rfc-editor.org/info/rfc7589>. - [RFC7895] Bierman, A., Bjorklund, M., and K. Watsen, "YANG Module Library", RFC 7895,
DOI 10.17487/RFC7895, June 2016,<http://www.rfc-editor.org/info/rfc7895>. - [RFC7950] Bjorklund, M., Ed., "The YANG 1.1 Data Modeling Language", RFC 7950,
DOI 10.17487/RFC7950, August 2016,<http://www.rfc-editor.org/info/rfc7950>. - [RFC7951] Lhotka, L., "JSON Encoding of Data Modeled with YANG", RFC 7951,
DOI 10.17487/RFC7951, August 2016,<http://www.rfc-editor.org/info/rfc7951>. - [RFC7952] Lhotka, L., "Defining and Using Metadata with YANG", RFC 7952,
DOI 10.17487/RFC7952, August 2016,<http://www.rfc-editor.org/info/rfc7952>. - [W3C.REC-eventsource-20150203] Hickson, I., "Server-Sent Events", World Wide Web Consortium Recommendation REC-eventsource-20150203, February 2015,
<http://www.w3.org/TR/2015/REC-eventsource-20150203>. - [W3C.REC-xml-20081126] Bray, T., Paoli, J., Sperberg-McQueen, M., Maler, E., and F. Yergeau, "Extensible Markup Language (XML) 1.0 (Fifth Edition)", World Wide Web Consortium Recommendation REC-xml-20081126, November 2008,
<http://www.w3.org/TR/2008/REC-xml-20081126>. - [XPath] Clark, J. and S. DeRose, "XML Path Language (XPath) Version 1.0", World Wide Web Consortium Recommendation REC-xpath-19991116, November 1999,
<http://www.w3.org/TR/1999/REC-xpath-19991116>.
13.2. Informative References 🌸
These ones are the extra-credit reading. Helpful, but not required to slay the spec 🧚
- [REST-Dissertation] Fielding, R., "Architectural Styles and the Design of Network-based Software Architectures", 2000.
- [RFC2818] Rescorla, E., "HTTP Over TLS", RFC 2818,
DOI 10.17487/RFC2818, May 2000,<http://www.rfc-editor.org/info/rfc2818>. - [RFC5226] Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 5226,
DOI 10.17487/RFC5226, May 2008,<http://www.rfc-editor.org/info/rfc5226>. - [TLS1.3] Rescorla, E., "The Transport Layer Security (TLS) Protocol Version 1.3", Work in Progress, draft-ietf-tls-tls13-18, October 2016.
- [YANG-Patch] Bierman, A., Bjorklund, M., and K. Watsen, "YANG Patch Media Type", Work in Progress, draft-ietf-netconf-yang-patch-14, November 2016.
Appendix A. Example YANG Module 🎀
The example YANG module in this doc is a simple media jukebox interface. Cute, right? 🍓
YANG tree diagram for the "example-jukebox" module:
+--rw jukebox!
+--rw library
| +--rw artist* [name]
| | +--rw name string
| | +--rw album* [name]
| | +--rw name string
| | +--rw genre? identityref
| | +--rw year? uint16
| | +--rw admin
| | | +--rw label? string
| | | +--rw catalogue-number? string
| | +--rw song* [name]
| | +--rw name string
| | +--rw location string
| | +--rw format? string
| | +--rw length? uint32
| +--ro artist-count? uint32
| +--ro album-count? uint32
| +--ro song-count? uint32
+--rw playlist* [name]
| +--rw name string
| +--rw description? string
| +--rw song* [index]
| +--rw index uint32
| +--rw id instance-identifier
+--rw player
+--rw gap? decimal64
rpcs:
+---x play
+--ro input
+--ro playlist string
+--ro song-number uint32
A.1. "example-jukebox" YANG Module 🎀
Okay bestie, this is our example jukebox module, and it's giving full data model energy 💖 It's non-normative, so it's just here to show how things fit together 🦋
module example-jukebox {
namespace "http://example.com/ns/example-jukebox";
prefix "jbox";
organization "Example, Inc.";
contact "support at example.com";
description "Example Jukebox Data Model Module.";
revision "2016-08-15" {
description "Initial version.";
reference "example.com document 1-4673.";
}
identity genre {
description
"Base for all genre types.";
}
// abbreviated list of genre classifications
identity alternative {
base genre;
description
"Alternative music.";
}
identity blues {
base genre;
description
"Blues music.";
}
identity country {
base genre;
description
"Country music.";
}
identity jazz {
base genre;
description
"Jazz music.";
}
identity pop {
base genre;
description
"Pop music.";
}
identity rock {
base genre;
description
"Rock music.";
}
container jukebox {
presence
"An empty container indicates that the jukebox
service is available.";
description
"Represents a 'jukebox' resource, with a library, playlists,
and a 'play' operation.";
container library {
description
"Represents the 'jukebox' library resource.";
list artist {
key name;
description
"Represents one 'artist' resource within the
'jukebox' library resource.";
leaf name {
type string {
length "1 .. max";
}
description
"The name of the artist.";
}
list album {
key name;
description
"Represents one 'album' resource within one
'artist' resource, within the jukebox library.";
leaf name {
type string {
length "1 .. max";
}
description
"The name of the album.";
}
leaf genre {
type identityref { base genre; }
description
"The genre identifying the type of music on
the album.";
}
leaf year {
type uint16 {
range "1900 .. max";
}
description
"The year the album was released.";
}
container admin {
description
"Administrative information for the album.";
leaf label {
type string;
description
"The label that released the album.";
}
leaf catalogue-number {
type string;
description
"The album's catalogue number.";
}
}
list song {
key name;
description
"Represents one 'song' resource within one
'album' resource, within the jukebox library.";
leaf name {
type string {
length "1 .. max";
}
description
"The name of the song.";
}
leaf location {
type string;
mandatory true;
description
"The file location string of the
media file for the song.";
}
leaf format {
type string;
description
"An identifier string for the media type
for the file associated with the
'location' leaf for this entry.";
}
leaf length {
type uint32;
units "seconds";
description
"The duration of this song in seconds.";
}
} // end list 'song'
} // end list 'album'
} // end list 'artist'
leaf artist-count {
type uint32;
units "artists";
config false;
description
"Number of artists in the library.";
}
leaf album-count {
type uint32;
units "albums";
config false;
description
"Number of albums in the library.";
}
leaf song-count {
type uint32;
units "songs";
config false;
description
"Number of songs in the library.";
}
} // end library
list playlist {
key name;
description
"Example configuration data resource.";
leaf name {
type string;
description
"The name of the playlist.";
}
leaf description {
type string;
description
"A comment describing the playlist.";
}
list song {
key index;
ordered-by user;
description
"Example nested configuration data resource.";
leaf index { // not really needed
type uint32;
description
"An arbitrary integer index for this playlist song.";
}
leaf id {
type instance-identifier;
mandatory true;
description
"Song identifier. Must identify an instance of
/jukebox/library/artist/album/song/name.";
}
}
}
container player {
description
"Represents the jukebox player resource.";
leaf gap {
type decimal64 {
fraction-digits 1;
range "0.0 .. 2.0";
}
units "tenths of seconds";
description
"Time gap between each song.";
}
}
}
rpc play {
description
"Control function for the jukebox player.";
input {
leaf playlist {
type string;
mandatory true;
description
"The playlist name.";
}
leaf song-number {
type uint32;
mandatory true;
description
"Song number in playlist to play.";
}
}
}
}
Appendix B. RESTCONF Message Examples ✨
Time for the good stuff! These examples use the normative YANG module "ietf-restconf" from Section 8, plus the non-normative "example-jukebox" module from Appendix A.1 🍓
This section shows some typical RESTCONF message exchanges, so you can see what they look like in the wild 👑
B.1. Resource Retrieval Examples 🧚
B.1.1. Retrieve the Top-Level API Resource 💜
The client starts by grabbing the RESTCONF root resource, so it knows where to go next 🫶
GET /.well-known/host-meta HTTP/1.1
Host: example.com
Accept: application/xrd+xml
The server might respond like this:
HTTP/1.1 200 OK
Content-Type: application/xrd+xml
Content-Length: nnn
<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>
<Link rel='restconf' href='/restconf'/>
</XRD>
The client may then retrieve the top-level API resource, using the root resource "/restconf". Main character energy 💅
GET /restconf HTTP/1.1
Host: example.com
Accept: application/yang-data+json
The server might respond like this:
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Content-Type: application/yang-data+json
{
"ietf-restconf:restconf" : {
"data" : {},
"operations" : {},
"yang-library-version" : "2016-06-21"
}
}
Want the response in XML instead? Just use the "Accept" header, like this 🌸
GET /restconf HTTP/1.1
Host: example.com
Accept: application/yang-data+xml
The server will return the same conceptual data either way, which might look like this 🦋
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Cache-Control: no-cache
Content-Type: application/yang-data+xml
<restconf xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf">
<data/>
<operations/>
<yang-library-version>2016-06-21</yang-library-version>
</restconf>
B.1.2. Retrieve the Server Module Information 🌈
The YANG library module can change over time, so it's smart to check what's current 🙈 The client can grab the revision date of the "ietf-yang-library" module that the server supports straight from the API resource, like we just did in the previous section.
In this example, the client asks for the module information in JSON format:
GET /restconf/data/ietf-yang-library:modules-state HTTP/1.1
Host: example.com
Accept: application/yang-data+json
The server might respond like this:
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Cache-Control: no-cache
Last-Modified: Thu, 26 Jan 2017 14:00:14 GMT
Content-Type: application/yang-data+json
{
"ietf-yang-library:modules-state" : {
"module-set-id" : "5479120c17a619545ea6aff7aa19838b036ebbd7",
"module" : [
{
"name" : "foo",
"revision" : "2012-01-02",
"schema" : "https://example.com/modules/foo/2012-01-02",
"namespace" : "http://example.com/ns/foo",
"feature" : [ "feature1", "feature2" ],
"deviation" : [
{
"name" : "foo-dev",
"revision" : "2012-02-16"
}
],
"conformance-type" : "implement"
},
{
"name" : "ietf-yang-library",
"revision" : "2016-06-21",
"schema" : "https://example.com/modules/\
ietf-yang-library/2016-06-21",
"namespace" :
"urn:ietf:params:xml:ns:yang:ietf-yang-library",
"conformance-type" : "implement"
},
{
"name" : "foo-types",
"revision" : "2012-01-05",
"schema" :
"https://example.com/modules/foo-types/2012-01-05",
"namespace" : "http://example.com/ns/foo-types",
"conformance-type" : "import"
},
{
"name" : "bar",
"revision" : "2012-11-05",
"schema" : "https://example.com/modules/bar/2012-11-05",
"namespace" : "http://example.com/ns/bar",
"feature" : [ "bar-ext" ],
"conformance-type" : "implement",
"submodule" : [
{
"name" : "bar-submod1",
"revision" : "2012-11-05",
"schema" :
"https://example.com/modules/bar-submod1/2012-11-05"
},
{
"name" : "bar-submod2",
"revision" : "2012-11-05",
"schema" :
"https://example.com/modules/bar-submod2/2012-11-05"
}
]
}
]
}
}
B.1.3. Retrieve the Server Capability Information ✨
okay so in this one the client wants the server's capability info, asked for in XML 🎀 and the server supports every RESTCONF query parameter, plus one vendor parameter 💅
GET /restconf/data/ietf-restconf-monitoring:restconf-state/\
capabilities HTTP/1.1
Host: example.com
Accept: application/yang-data+xml
the server might reply like this 🦋
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Cache-Control: no-cache
Last-Modified: Thu, 26 Jan 2017 16:00:14 GMT
Content-Type: application/yang-data+xml
<capabilities
xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf-monitoring">
<capability>\
urn:ietf:params:restconf:capability:defaults:1.0?\
basic-mode=explicit\
</capability>
<capability>\
urn:ietf:params:restconf:capability:with-defaults:1.0\
</capability>
<capability>\
urn:ietf:params:restconf:capability:depth:1.0\
</capability>
<capability>\
urn:ietf:params:restconf:capability:fields:1.0\
</capability>
<capability>\
urn:ietf:params:restconf:capability:filter:1.0\
</capability>
<capability>\
urn:ietf:params:restconf:capability:start-time:1.0\
</capability>
<capability>\
urn:ietf:params:restconf:capability:stop-time:1.0\
</capability>
<capability>\
http://example.com/capabilities/myparam\
</capability>
</capabilities>
B.2. Data Resource and Datastore Resource Examples 🌸
B.2.1. Create New Data Resources
okay the vibe here is making new stuff inside existing stuff 🧚 to create a new "artist" resource inside the "library" resource, the client might send this:
POST /restconf/data/example-jukebox:jukebox/library HTTP/1.1
Host: example.com
Content-Type: application/yang-data+json
{
"example-jukebox:artist" : [
{
"name" : "Foo Fighters"
}
]
}
if it gets created, the server might respond like so ✨
HTTP/1.1 201 Created
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Location: https://example.com/restconf/data/\
example-jukebox:jukebox/library/artist=Foo%20Fighters
Last-Modified: Thu, 26 Jan 2017 20:56:30 GMT
ETag: "b3830f23a4c"
next up, the client makes an "album" resource for that artist, still inside the "jukebox" resource 📀
POST /restconf/data/example-jukebox:jukebox/\
library/artist=Foo%20Fighters HTTP/1.1
Host: example.com
Content-Type: application/yang-data+xml
<album xmlns="http://example.com/ns/example-jukebox">
<name>Wasting Light</name>
<year>2011</year>
</album>
if that gets created, the server might respond like this 💜
HTTP/1.1 201 Created
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Location: https://example.com/restconf/data/\
example-jukebox:jukebox/library/artist=Foo%20Fighters/\
album=Wasting%20Light
Last-Modified: Thu, 26 Jan 2017 20:56:30 GMT
ETag: "b8389233a4c"
B.2.2. Detect Datastore Resource Entity-Tag Change
in this one the server only supports the datastore last-changed timestamp 🕰️ the client already has the "Last-Modified" header from the last response and uses that value in the "If-Unmodified-Since" header of the next request. that request patches an "album" list entry with the key value "Wasting Light", and only the "genre" field is getting updated 🎶
PATCH /restconf/data/example-jukebox:jukebox/\
library/artist=Foo%20Fighters/album=Wasting%20Light/\
genre HTTP/1.1
Host: example.com
If-Unmodified-Since: Thu, 26 Jan 2017 20:56:30 GMT
Content-Type: application/yang-data+json
{ "example-jukebox:genre" : "example-jukebox:alternative" }
the datastore resource has changed since the time in that "If-Unmodified-Since" header 😭 so the server might respond like this:
HTTP/1.1 412 Precondition Failed
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Last-Modified: Thu, 26 Jan 2017 19:41:00 GMT
ETag: "b34aed893a4c"
B.2.3. Edit a Datastore Resource
say there's a top-level data resource called "system" from the example-system module, and this container has a child leaf named "enable-jukebox-streaming" 🔧
container system {
leaf enable-jukebox-streaming {
type boolean;
}
}
now PATCH is used by the client to change two top-level resources at once 👑 it turns on jukebox streaming AND adds an "album" sub-resource to each of two "artist" resources. the whole thing is giving multitasking 🤹
PATCH /restconf/data HTTP/1.1
Host: example.com
Content-Type: application/yang-data+xml
<data xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf">
<system xmlns="http://example.com/ns/example-system">
<enable-jukebox-streaming>true</enable-jukebox-streaming>
</system>
<jukebox xmlns="http://example.com/ns/example-jukebox">
<library>
<artist>
<name>Foo Fighters</name>
<album>
<name>One by One</name>
<year>2012</year>
</album>
</artist>
<artist>
<name>Nick Cave and the Bad Seeds</name>
<album>
<name>Tender Prey</name>
<year>1988</year>
</album>
</artist>
</library>
</jukebox>
</data>
B.2.4. Replace a Datastore Resource
this is the big reset 🫠 the entire configuration datastore contents are getting replaced. anything that's not in the <data> element but IS on the server gets deleted 💀
PUT /restconf/data HTTP/1.1
Host: example.com
Content-Type: application/yang-data+xml
<data xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf">
<jukebox xmlns="http://example.com/ns/example-jukebox">
<library>
<artist>
<name>Foo Fighters</name>
<album>
<name>One by One</name>
<year>2012</year>
</album>
</artist>
<artist>
<name>Nick Cave and the Bad Seeds</name>
<album>
<name>Tender Prey</name>
<year>1988</year>
</album>
</artist>
</library>
</jukebox>
</data>
B.2.5. Edit a Data Resource
here the client changes one data node by adding an "album" sub-resource, using a PATCH on the data resource itself 🎸
PATCH /restconf/data/example-jukebox:jukebox/library/\
artist=Nick%20Cave%20and%20the%20Bad%20Seeds HTTP/1.1
Host: example.com
Content-Type: application/yang-data+xml
<artist xmlns="http://example.com/ns/example-jukebox">
<name>Nick Cave and the Bad Seeds</name>
<album>
<name>The Good Son</name>
<year>1990</year>
</album>
</artist>
B.3. Query Parameter Examples 🧁
B.3.1. "content" Parameter
the "content" parameter picks which types of child resources come back from a GET request: configuration, non-configuration, or both 🍓
in this example we use a simple YANG list that has configuration AND non-configuration child resources 🍭
container events {
list event {
key name;
leaf name { type string; }
leaf description { type string; }
leaf event-count {
type uint32;
config false;
}
}
}
Example 1: content=all
to get all the child resources, "content" is set to "all", or left out, since that's the default ✨ the client might send:
GET /restconf/data/example-events:events?\
content=all HTTP/1.1
Host: example.com
Accept: application/yang-data+json
the server might respond like this 🌈
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Cache-Control: no-cache
Content-Type: application/yang-data+json
{
"example-events:events" : {
"event" : [
{
"name" : "interface-up",
"description" : "Interface up notification count",
"event-count" : 42
},
{
"name" : "interface-down",
"description" : "Interface down notification count",
"event-count" : 4
}
]
}
}
Example 2: content=config
to get only the configuration child resources, "content" is set to "config" 🛠️ heads up: the "ETag" and "Last-Modified" headers only show up when the "content" value is "config" 👀
GET /restconf/data/example-events:events?\
content=config HTTP/1.1
Host: example.com
Accept: application/yang-data+json
the server might respond like this:
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Last-Modified: Thu, 26 Jan 2017 16:45:20 GMT
ETag: "eeeada438af"
Cache-Control: no-cache
Content-Type: application/yang-data+json
{
"example-events:events" : {
"event" : [
{
"name" : "interface-up",
"description" : "Interface up notification count"
},
{
"name" : "interface-down",
"description" : "Interface down notification count"
}
]
}
}
Example 3: content=nonconfig
to get only the non-configuration child resources, "content" is set to "nonconfig" 🦋 also, configuration ancestors (if any) and list key leafs (if any) come back too, so you're not left hanging 🫶 the client might send:
GET /restconf/data/example-events:events?\
content=nonconfig HTTP/1.1
Host: example.com
Accept: application/yang-data+json
the server might respond like this:
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Cache-Control: no-cache
Content-Type: application/yang-data+json
{
"example-events:events" : {
"event" : [
{
"name" : "interface-up",
"event-count" : 42
},
{
"name" : "interface-down",
"event-count" : 4
}
]
}
}
B.3.2. "depth" Parameter 🌸
okay so the depth parameter is your limiter for how many levels of child resources the server sends back on a GET 🧚 it counts from the target resource itself, so depth=1 gives you just the target resource level, and depth=2 gives you the target plus its child nodes ✨
here's how the different depth values change the reply for the top-level jukebox data resource 🎶
Example 1: depth=unbounded 💅
to grab all of the child resources, leave depth out or set it to the default value unbounded.
GET /restconf/data/example-jukebox:jukebox?\
depth=unbounded HTTP/1.1
Host: example.com
Accept: application/yang-data+json
the server might respond like this 👑
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Cache-Control: no-cache
Content-Type: application/yang-data+json
{
"example-jukebox:jukebox" : {
"library" : {
"artist" : [
{
"name" : "Foo Fighters",
"album" : [
{
"name" : "Wasting Light",
"genre" : "example-jukebox:alternative",
"year" : 2011,
"song" : [
{
"name" : "Wasting Light",
"location" :
"/media/foo/a7/wasting-light.mp3",
"format" : "MP3",
"length" : 286
},
{
"name" : "Rope",
"location" : "/media/foo/a7/rope.mp3",
"format" : "MP3",
"length" : 259
}
]
}
]
}
]
},
"playlist" : [
{
"name" : "Foo-One",
"description" : "example playlist 1",
"song" : [
{
"index" : 1,
"id" : "/example-jukebox:jukebox/library\
/artist[name='Foo Fighters']\
/album[name='Wasting Light']\
/song[name='Rope']"
},
{
"index" : 2,
"id" : "/example-jukebox:jukebox/library\
/artist[name='Foo Fighters']\
/album[name='Wasting Light']\
/song[name='Bridge Burning']"
}
]
}
],
"player" : {
"gap" : 0.5
}
}
}
Example 2: depth=1 🦋
if you just want to know whether one or more resource instances exist for a target resource, use the value 1.
GET /restconf/data/example-jukebox:jukebox?depth=1 HTTP/1.1
Host: example.com
Accept: application/yang-data+json
the server might respond like this 🫶
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Cache-Control: no-cache
Content-Type: application/yang-data+json
{
"example-jukebox:jukebox" : {}
}
Example 3: depth=3 🍓
to cap things at the target resource plus two child resource layers, use the value 3.
GET /restconf/data/example-jukebox:jukebox?depth=3 HTTP/1.1
Host: example.com
Accept: application/yang-data+json
the server might respond like this 💜
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Cache-Control: no-cache
Content-Type: application/yang-data+json
{
"example-jukebox:jukebox" : {
"library" : {
"artist" : {}
},
"playlist" : [
{
"name" : "Foo-One",
"description" : "example playlist 1",
"song" : {}
}
],
"player" : {
"gap" : 0.5
}
}
}
B.3.3. "fields" Parameter ✨
in this one, the client wants the datastore resource in JSON, but only the modules-state/module list, and only the name and revision nodes from each entry 💖 the top node in the reply matches the target resource node (which is data here). the module-set-id leaf doesn't show up because it isn't selected in the fields expression 🙈
GET /restconf/data?fields=ietf-yang-library:modules-state/\
module(name;revision) HTTP/1.1
Host: example.com
Accept: application/yang-data+json
the server might respond like this 🌈
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Content-Type: application/yang-data+json
{
"ietf-restconf:data" : {
"ietf-yang-library:modules-state" : {
"module" : [
{
"name" : "example-jukebox",
"revision" : "2016-08-15"
},
{
"name" : "ietf-inet-types",
"revision" : "2013-07-15"
},
{
"name" : "ietf-restconf-monitoring",
"revision" : "2017-01-26"
},
{
"name" : "ietf-yang-library",
"revision" : "2016-06-21"
},
{
"name" : "ietf-yang-types",
"revision" : "2013-07-15"
}
]
}
}
}
B.3.4. "insert" Parameter 🎀
here we're creating a brand-new first song entry in the Foo-One playlist 🎧
Request from client:
POST /restconf/data/example-jukebox:jukebox/\
playlist=Foo-One?insert=first HTTP/1.1
Host: example.com
Content-Type: application/yang-data+json
{
"example-jukebox:song" : [
{
"index" : 1,
"id" : "/example-jukebox:jukebox/library\
/artist[name='Foo Fighters']\
/album[name='Wasting Light']\
/song[name='Rope']"
}
]
}
Response from server:
HTTP/1.1 201 Created
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Last-Modified: Thu, 26 Jan 2017 20:56:30 GMT
Location: https://example.com/restconf/data/\
example-jukebox:jukebox/playlist=Foo-One/song=1
ETag: "eeeada438af"
B.3.5. "point" Parameter 🦋
this time the client is slotting a new song into the Foo-One playlist right after the first song 🎵
Request from client:
POST /restconf/data/example-jukebox:jukebox/\
playlist=Foo-One?insert=after&point=\
%2Fexample-jukebox%3Ajukebox\
%2Fplaylist%3DFoo-One%2Fsong%3D1 HTTP/1.1
Host: example.com
Content-Type: application/yang-data+json
{
"example-jukebox:song" : [
{
"index" : 2,
"id" : "/example-jukebox:jukebox/library\
/artist[name='Foo Fighters']\
/album[name='Wasting Light']\
/song[name='Bridge Burning']"
}
]
}
Response from server:
HTTP/1.1 201 Created
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Last-Modified: Thu, 26 Jan 2017 20:56:30 GMT
Location: https://example.com/restconf/data/\
example-jukebox:jukebox/playlist=Foo-One/song=2
ETag: "abcada438af"
B.3.6. "filter" Parameter 🔥
these URIs show a few notification filter specifications, so you can see how they look in practice 👀
// filter = /event/event-class='fault'
GET /streams/NETCONF?filter=%2Fevent%2Fevent-class%3D'fault'
// filter = /event/severity<=4
GET /streams/NETCONF?filter=%2Fevent%2Fseverity%3C%3D4
// filter = /linkUp|/linkDown
GET /streams/SNMP?filter=%2FlinkUp%7C%2FlinkDown
// filter = /*/reporting-entity/card!='Ethernet0'
GET /streams/NETCONF?\
filter=%2F*%2Freporting-entity%2Fcard%21%3D'Ethernet0'
// filter = /*/email-addr[contains(.,'company.com')]
GET /streams/critical-syslog?\
filter=%2F*%2Femail-addr[contains(.%2C'company.com')]
// Note: The module name is used as the prefix.
// filter = (/example-mod:event1/name='joe' and
// /example-mod:event1/status='online')
GET /streams/NETCONF?\
filter=(%2Fexample-mod%3Aevent1%2Fname%3D'joe'%20and\
%20%2Fexample-mod%3Aevent1%2Fstatus%3D'online')
// To get notifications from just two modules (e.g., m1 + m2)
// filter=(/m1:* or /m2:*)
GET /streams/NETCONF?filter=(%2Fm1%3A*%20or%20%2Fm2%3A*)
B.3.7. "start-time" Parameter ⭐
here's a quick look at the start-time query parameter 🕑
// start-time = 2014-10-25T10:02:00Z
GET /streams/NETCONF?start-time=2014-10-25T10%3A02%3A00Z
B.3.8. "stop-time" Parameter 🌙
and this one shows stop-time in action, paired with a start-time 🕓
// start-time = 2014-10-25T10:02:00Z
// stop-time = 2014-10-25T12:31:00Z
GET /mystreams/NETCONF?start-time=2014-10-25T10%3A02%3A00Z\
&stop-time=2014-10-25T12%3A31%3A00Z
B.3.9. "with-defaults" Parameter 💅
picture a server that implements the module "example" from Appendix A.1 of [RFC6243], and its datastore matches Appendix A.2 of [RFC6243] 🧁
if the server's "basic-mode" parameter in the "defaults" protocol capability URI (Section 9.1.2) is "trim", a request for interface "eth1" might look like this:
Without query parameter:
GET /restconf/data/example:interfaces/interface=eth1 HTTP/1.1
Host: example.com
Accept: application/yang-data+json
the server might respond like this 🫧
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Content-Type: application/yang-data+json
{
"example:interface" : [
{
"name" : "eth1",
"status" : "up"
}
]
}
the mtu leaf is missing here because it's set to the default "1500", and the server's default-handling "basic-mode" parameter is "trim" 🙈
With query parameter:
GET /restconf/data/example:interfaces/interface=eth1\
?with-defaults=report-all HTTP/1.1
Host: example.com
Accept: application/yang-data+json
the server might respond like this 🌸
HTTP/1.1 200 OK
Date: Thu, 26 Jan 2017 20:56:30 GMT
Server: example-server
Content-Type: application/yang-data+json
{
"example:interface" : [
{
"name" : "eth1",
"mtu" : 1500,
"status" : "up"
}
]
}
this time the server returns the mtu leaf, because the client asked for report-all mode with the with-defaults query parameter 🥹
Acknowledgements 🎀
okay bestie, big thank yous to Ladislav Lhotka, Juergen Schoenwaelder, Rex Fernando, Robert Wilton, and Jonathan Hansford for contributing to this doc 💖
and a huge shoutout to the excellent technical reviewers: Mehmet Ersue, Mahesh Jethanandani, Qin Wu, Joe Clarke, Bert Wijnen, Ladislav Lhotka, Rodney Cummings, Frank Xialiang, Tom Petch, Robert Sparks, Balint Uveges, Randy Presuhn, Sue Hares, Mark Nottingham, Benoit Claise, Dale Worley, and Lionel Morand 🫶 these people are literally the reason it's so solid, no cap ✨
lowkey need to flag this part 🙈 Contributions to this material by Andy Bierman are based upon work supported by the United States Army, Space & Terrestrial Communications Directorate (S&TCD) under Contract No. W15P7T-13-C-A616. Any opinions, findings, and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the S&TCD.
Authors' Addresses 💅
Andy Bierman
YumaWorks
Email: andy@yumaworks.com
Martin Bjorklund
Tail-f Systems
Email: mbj@tail-f.com
Kent Watsen
Juniper Networks
Email: kwatsen@juniper.net
📦 where this page comes from
- ietf: rfc8040 2017-01
- 💖 girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms