> For the complete documentation index, see [llms.txt](https://ccnp-sp.gitbook.io/studyguide/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ccnp-sp.gitbook.io/studyguide/misc/automation-and-assurance/restconf.md).

# RESTCONF

RESTCONF is a relatively new extension to NETCONF, with RFC8040 published in 2017. RESTCONF uses the same YANG models as NETCONF but with an HTTP-based interface instead of SSH-based.

RESTCONF allows for data to be encoded in JSON or XML. However, instead of **application-type/json** you use **application/yang-data+json** or **application/yang-data+xml** for Content-Type and Accept headers.

RESTCONF uses common REST verbs such as GET, POST, PUT, DELETE instead of NETCONF RPC actions.

Because RESTCONF is essentially a sub-set of NETCONF, not all NETCONF features are supported with RESTCONF. RESTCONF is stateless and lacks the ability to configure multiple datastores and preform datastore locking. There is no candidate config or commit operation. Because of this there is also no ability to preform network-wide transactions, in which a single change that fails on one device rolls back the change on all devices. However, the tradeoff for losing these stateful features is a RESTful API that uses familiar HTTP operations and JSON data encoding. Put simply, RESTCONF is not a replacement for NETCONF.

### Enabling RESTCONF in IOS-XE <a href="#id-2883eb23-510f-49ca-a1f5-8c44397b4e33" id="id-2883eb23-510f-49ca-a1f5-8c44397b4e33"></a>

To enable RESTCONF we simply need to turn on the feature and enable HTTPS server:

```
restconf
ip http secure-server
```

To verify that RESTCONF is running we can use the following show command:

```
Router#show platform software yang-management process
confd            : Running    
nesd             : Running    
syncfd           : Running    
ncsshd           : Not Running
dmiauthd         : Running    
nginx            : Running    
ndbmand          : Running    
pubd             : Running
```

**confd** I believe is the same ConfD YANG agent that was developed by Tail-F. This is a web server that processes RESTCONF requests. **nginx** is essentially a proxy server that proxies HTTPS and transfers traffic to **confd** on the “backend.” **ncsshd** is the only process which isn’t running, which is the netconfd SSH daemon. Interestingly, **nginx** will be running whether or not RESTCONF is enabled.

### RESTCONF on IOS-XR <a href="#id-657ec4b3-4592-4ba0-9392-4c056de53ff4" id="id-657ec4b3-4592-4ba0-9392-4c056de53ff4"></a>

RESTCONF is not supported on IOS-XR. YANG can only use NETCONF or gRPC on IOS-XR.

(Source: <https://www.cisco.com/c/en/us/td/docs/routers/asr9000/software/asr9k-r6-4/programmability/configuration/guide/b-programmability-cg-asr9000-64x/b-programmability-cg-asr9000-64x_chapter_011.html#id_21589> )

### Using RESTCONF with CSR1000v <a href="#id-7f0ad47c-37c2-48ee-80e9-11adea45e101" id="id-7f0ad47c-37c2-48ee-80e9-11adea45e101"></a>

In this short lab we will use Postman to examine how RESTCONF works on a CSR1000v. Every HTTP request must have basic authorization which won’t be included in the screenshots.

RESTCONF URIs follow this format:

```
https://<device>/restconf/data/<yang module>/<leaf>
```

To look at the ietf-interfaces:interfaces model we use the following URI:

```
https://{{csr1000v_ipaddress}}/restconf/data/ietf-interfaces:interfaces
```

<figure><img src="https://1203572585-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgAMH3CMtmYTBkob03NUj%2Fuploads%2FvNh2xA3u4p8H9UH1oVxd%2FUntitled.png?alt=media&amp;token=31b35bc2-390c-4e9e-b7ac-cbf54deb76ea" alt=""><figcaption></figcaption></figure>

Let’s filter this output to only Gi3 by appending **/interface=GigabitEthernet3**

<figure><img src="https://1203572585-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgAMH3CMtmYTBkob03NUj%2Fuploads%2F6RZKbcPkSBAR5S5Lf8zV%2FUntitled%201.png?alt=media&amp;token=fb3c8788-d88e-4f72-bab3-f5d06fe711e3" alt=""><figcaption></figcaption></figure>

Now let’s configure an IP address by using Gi1 as a model from the previous output, pasting it to our body and editing it. We will need to set a header for Content-Type:application/yang-data+json and change the HTTP method to **PUT**. This is because the interface already exists on the router and we are editing it, not creating it. If we created a *new* interface like Loopback99 then we would **POST**.

<figure><img src="https://1203572585-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgAMH3CMtmYTBkob03NUj%2Fuploads%2FF8YhO0aGwnlLZ7NcKyhQ%2FUntitled%202.png?alt=media&amp;token=5fc7a7cb-8e6b-4bdc-8ba7-69ccc2bd1ab4" alt=""><figcaption></figcaption></figure>

* A 204 No Content means the change was accepted.

If we do a GET on the interface again, we can see our change was applied:

<figure><img src="https://1203572585-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgAMH3CMtmYTBkob03NUj%2Fuploads%2Fl3j8Qwzn7NOaBx2gQGU6%2FUntitled%203.png?alt=media&amp;token=1ee99cce-82cb-46cc-9cbb-dbc94f530349" alt=""><figcaption></figcaption></figure>

To preform a **wr mem** we can POST to https\://{{csr1000v\_ipaddress}}/restconf/operations/cisco-ia:save-config/ with an empty body.

<figure><img src="https://1203572585-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgAMH3CMtmYTBkob03NUj%2Fuploads%2Fi3jyOFD8Jgq3UuDGdX0j%2FUntitled%204.png?alt=media&amp;token=e560fef9-b6cc-4ff2-a80f-fc310f946d61" alt=""><figcaption></figcaption></figure>

### RESTCONF HTTP Operations <a href="#id-8f6f19f5-e81e-4ac6-8bf4-0a419309b78a" id="id-8f6f19f5-e81e-4ac6-8bf4-0a419309b78a"></a>

<table><thead><tr><th width="186.33333333333331">Operation</th><th width="254">NETCONF RPC Operation</th><th>Use</th></tr></thead><tbody><tr><td>GET</td><td>&#x3C;get> and &#x3C;get-config></td><td>Get data from a resource</td></tr><tr><td>POST</td><td>&#x3C;edit-config></td><td>Create a resource</td></tr><tr><td>PUT</td><td>&#x3C;edit-config></td><td>Create or replace a resource</td></tr><tr><td>PATCH</td><td>&#x3C;edit-config></td><td>Merge configuration with target resource</td></tr><tr><td>DELETE</td><td>&#x3C;edit-config></td><td>Delete a resource</td></tr></tbody></table>

The difference between POST, PUT, and PATCH can be a little confusing. In general, POST is only used to create a new resource. But what about PUT vs. PATCH? PUT is used to completely replace a configuration, and PATCH is used to add configuration alongside existing configuration. An example will help.

Let’s say we have the following configuration on Lo99:

```
interface Loopback99
 no ip address
 ipv6 address 2001:DB8:1::99/128
end
```

We can also see this from Postman:

<figure><img src="https://1203572585-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgAMH3CMtmYTBkob03NUj%2Fuploads%2FBFxV2QU6tvqhgH9k42wJ%2FUntitled%205.png?alt=media&amp;token=8dbbd2b3-88bb-4e9e-8492-851dda8ed367" alt=""><figcaption></figcaption></figure>

If we use a PATCH, we will add another IPv6 address *alongside* the existing IPv6 address:

<figure><img src="https://1203572585-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgAMH3CMtmYTBkob03NUj%2Fuploads%2FTj1HfhCjLZpBTapXpy04%2FUntitled%206.png?alt=media&amp;token=b1e0d0f3-8915-421f-81c5-c8ba58cc1334" alt=""><figcaption></figcaption></figure>

* The only IPv6 address listed here is 2001:db8:2::99

If we do another GET we now see two IPv6 addresses:

<figure><img src="https://1203572585-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgAMH3CMtmYTBkob03NUj%2Fuploads%2FsQ1cCX77OaCtXlwQl4Fv%2FUntitled%207.png?alt=media&amp;token=ca7cbae3-97b2-4a72-b91a-a5a362026028" alt=""><figcaption></figcaption></figure>

If we do the same thing again, but using PUT, we will only see a single IPv6 address. PUT replaces the entire object, while PATCH adds configuration alongside what is already existing.

<figure><img src="https://1203572585-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgAMH3CMtmYTBkob03NUj%2Fuploads%2FNuFb1jNxhK8y7u54cs0F%2FUntitled%208.png?alt=media&amp;token=8a8c1dec-f16f-48e8-b1c5-0bf856ec0cbb" alt=""><figcaption><p>PUT to the Lo99 interface with a new IPv6 address</p></figcaption></figure>

<figure><img src="https://1203572585-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgAMH3CMtmYTBkob03NUj%2Fuploads%2FbFIP3FS8bNds2OJggvmP%2FUntitled%209.png?alt=media&amp;token=2f5c00ad-2c38-498d-8d93-988ffec15d3a" alt=""><figcaption><p>A GET shows that the previous PUT operation completely replaced the Lo99 config</p></figcaption></figure>

### Further Reading <a href="#id-52c81e51-98fd-4446-9a27-c9e39b551cf4" id="id-52c81e51-98fd-4446-9a27-c9e39b551cf4"></a>

<https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/prog/configuration/172/b_172_programmability_cg/restconf_protocol.html>

\
<https://www.cisco.com/c/en/us/td/docs/routers/asr9000/software/asr9k-r6-4/programmability/configuration/guide/b-programmability-cg-asr9000-64x/b-programmability-cg-asr9000-64x_chapter_011.html#id_21589>

\
<https://developer.cisco.com/learning/tracks/netprog-eng/intro-device-level-interfaces/intro-restconf/introduction/>
