A RESTCONF POST either creates data or invokes an operation; how does the server tell which, and what does each mode return?
answer
- the target decides, not the body
- parent URI, one child inside
- Location on success, 409 on a duplicate
- rpc under /operations, action under /data
- output or no output
basics
~20 sThe target resource decides. POST to the datastore or a data resource creates one child (201 Created plus Location; 409 if it exists); POST to an rpc under /operations or an action under /data invokes it (200 with output, 204 without).
solid answer
~40 sRFC 8040 §4.4 picks the mode from the **type of the target resource**. Aimed at `{+restconf}/data` or a data resource, `POST` is *create resource mode*: the URI names the parent, the body holds exactly one child (key values included), and success is `201 Created` with no body and a mandatory `Location` header naming the new child. If that child already exists the server must answer `409 Conflict` and change nothing. Aimed at an operation resource, `POST` is *invoke operation mode*: a YANG `rpc` at `{+restconf}/operations/<module>:<rpc>`, or a YANG 1.1 `action` at the path of the data node it is bound to followed by the action name. The body carries the `input`; success is `200 OK` with an `output` body, or `204 No Content` when there is no body to return.
code
http · 9 linesPOST /restconf/data/ietf-interfaces:interfaces HTTP/1.1
Host: router1.example.net
Content-Type: application/yang-data+json
{"ietf-interfaces:interface": [{"name": "uplink-3",
"type": "iana-if-type:ethernetCsmacd"}]}
HTTP/1.1 201 Created
Location: https://router1.example.net/restconf/data/ietf-interfaces:interfaces/interface=uplink-3go deeper
Recall that POST creates a child under the URI you give it, and that the same method also runs operations.
Explain how the target resource type selects the mode, the 201-plus-Location and 409 outcomes, and the rpc versus action URIs.
Show how an automation job should handle a retried POST that comes back 409, and why status codes are safer to key on than error-tags.
Weigh strict-create POST against idempotent PUT as the house convention for provisioning workflows that must survive retries.
## One method, two jobs In **RESTCONF** (RFC 8040), `POST` is the only method with two unrelated meanings, and the server does not inspect the body to choose between them: it looks at the **type of the target resource**. RFC 8040 §4.4 lists three cases. | Target resource | What `POST` does | NETCONF equivalent | |---|---|---| | Datastore (`{+restconf}/data`) | creates a top-level configuration node | `<edit-config>` with `create` | | Data resource | creates a configuration child inside it | `<edit-config>` with `create` | | Operation resource | invokes the `rpc` or `action` | the RPC call itself | ## Create resource mode When the target is the datastore or a data resource, `POST` asks the server to create one child: 1. The request URI names the **parent**, never the new child. For a list entry, the key values travel inside the body. 2. The body must contain **exactly one** instance of the child, encoded as `application/yang-data+json` or `application/yang-data+xml`. 3. If the child does not exist, the server creates it and answers `201 Created` with **no body** and a mandatory **`Location`** header giving the new child's URI. RFC 8040's examples also return the new `ETag` and `Last-Modified`. 4. If the child **already exists**, the request must fail with `409 Conflict`. `POST` never overwrites. 5. If the user may not create it, the server should answer `403 Forbidden` (error-tag `access-denied`), and may answer `404` instead. For a list or leaf-list declared `ordered-by user`, the `insert` and `point` query parameters choose where the new entry lands; without them it goes last. One wrinkle for anyone matching error-tags: RFC 8040 §4.4.1 names the error-tag for the duplicate case `resource-denied`, while the same RFC's error example in §7.1 returns `data-exists` for a duplicate `POST`. Both map to `409`, so client logic should key on the status code rather than on the tag. ## Invoke operation mode When the target is an operation resource, the body — if there is one — is the operation's input: - A YANG **`rpc`** is invoked at `{+restconf}/operations/<module>:<rpc>`. - A YANG **`action`** (YANG 1.1) is bound to a data node, so it is invoked inside the data tree: `{+restconf}/data/<path-to-node>/<action>`. Actions are **not** listed under `/operations`. - The input is wrapped in an object named `input` in the defining module's namespace — `"example-actions:input"` in JSON. - Success is `200 OK` when the response carries an `output` body and `204 No Content` when it carries none; an `rpc` or `action` with no `output` section must answer `204`. No resource is created, so there is no `Location`. - A `GET` on an operation resource is refused with `405 Method Not Allowed`: operations are run, not read. ## POST versus PUT for creation | | `POST` | `PUT` | |---|---|---| | URI names | the parent | the new resource itself | | Resource already exists | `409 Conflict`, nothing changed | replaced, `204 No Content` | | Resource created | `201 Created` + `Location` | `201 Created` | | Retried after a lost response | the retry gets `409` | the retry replaces with identical content | The last row matters for automation. A job that retries a `POST` after a timeout and gets `409` cannot tell whether its first attempt landed or someone else created the entry; it has to `GET` the child and compare. A retried `PUT` simply converges, at the price of replacing whatever was there. ## Reading a POST failure - `409 Conflict` on a create usually means the child exists. On a device that also runs NETCONF, a datastore lock held by a NETCONF client, or a confirmed commit awaiting its `persist-id`, also produces `409`, with error-tag `in-use`. - `400 Bad Request` points at the body: the error-tags `malformed-message`, `bad-element` and `unknown-element` all map to `400`. - `405 Method Not Allowed` with error-tag `operation-not-supported` is what a `GET` on an operation resource earns. - `204` on an invoke is a success, not an empty failure — the operation simply had nothing to return. ## Two requests side by side The create below targets the `interfaces` container and names the new entry only in the body; the server's `Location` then gives the URI that a later `PUT`, `PATCH` or `DELETE` would use. An `rpc` invocation would instead target `/restconf/operations/<module>:<rpc>` and come back `200` or `204` with no `Location` at all.
- Why are YANG actions invoked under /data rather than under /operations?An `action` is bound to a specific data node — reset *this* interface, not interfaces in general — so its URI has to identify that node instance, list keys included. RFC 8040 therefore invokes it as `POST {+restconf}/data/<path-to-node>/<action>` and keeps `{+restconf}/operations` for module-level `rpc` statements only, which is also why actions do not appear in the `/operations` listing.
- A RESTCONF client's POST timed out and its retry returned 409 Conflict. What should it do?Treat the `409` as ambiguous, not as failure. The first attempt may have created the child, or another client may have. The client should `GET` the child at the URI it expected in `Location` and compare the content with what it meant to create; if it matches, carry on, and if not, escalate rather than overwrite.
saying these in an interview costs you the question
- RESTCONF chooses between create and invoke by looking at the body's top-level member.
- A successful RESTCONF POST create returns 200 OK with the new data in the body.
- YANG actions are invoked under /operations like any rpc.
- A RESTCONF POST to an existing list entry updates it in place.
- An rpc returning 204 No Content failed silently.