# Management API Config Patch Method

**URL:** <https://openziti.discourse.group/t/management-api-config-patch-method/1531>\
**Category:** General Questions\
**Created:** [August 19, 2023, 1:52am UTC](https://openziti.discourse.group/t/management-api-config-patch-method/1531 "2023-08-19T01:52:53Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![dariuszSki](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/dariuszski/32/339_2.png) [@dariuszSki](https://openziti.discourse.group/u/dariuszSki)\
**Post date:** [August 19, 2023, 1:52am UTC](https://openziti.discourse.group/t/management-api-config-patch-method/1531/1 "2023-08-19T01:52:53Z")

</div>

I am just trying to update just an address in the intercept.v1 config. I am trying to use the Patch Method. I thought I only need to provide parameter(s) that I want to modify using the Patch Method. It does not seem to be the case.

 ![image](https://global.discourse-cdn.com/free1/uploads/netfoundry/original/2X/2/2fab4bc47efce90053cf98e073fdff3b133b5c28.png)

I need to provide the portRanges and protocols for it to succeed even though I don’t need to change them. Is this correct?

 ![image](https://global.discourse-cdn.com/free1/uploads/netfoundry/original/2X/0/072554b99ecbca7b175c98b5346f25ad9e4f3165.png)

---

<div class="post-metadata">

**Author:** ![dariuszSki](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/dariuszski/32/339_2.png) [@dariuszSki](https://openziti.discourse.group/u/dariuszSki)\
**Post date:** [August 19, 2023, 1:57am UTC](https://openziti.discourse.group/t/management-api-config-patch-method/1531/2 "2023-08-19T01:57:26Z")

</div>

The controller version is 0.30.0.

Documentation Reference used.

> **[Edge Management API Reference | OpenZiti](https://openziti.io/docs/reference/developer/api/edge-management-reference/#tag/Config/operation/patchConfig)**
>
> open source zero trust

---

<div class="post-metadata">

**Author:** ![scareything](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/scareything/32/106_2.png) [@scareything](https://openziti.discourse.group/u/scareything)\
**Post date:** [August 19, 2023, 11:01am UTC](https://openziti.discourse.group/t/management-api-config-patch-method/1531/3 "2023-08-19T11:01:55Z")

</div>

Yes, this is expected. I could imagine a `--merge` or similar option that lets you change specific fields in the configuration, but right now `update` is a wholesale replacement of the configuration json. The main advantage of using `update` on configurations is that you don’t need to re-associate an updated configuration with the services that use it.

---

<div class="post-metadata">

**Author:** ![dariuszSki](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/dariuszski/32/339_2.png) [@dariuszSki](https://openziti.discourse.group/u/dariuszSki)\
**Post date:** [August 20, 2023, 11:46pm UTC](https://openziti.discourse.group/t/management-api-config-patch-method/1531/4 "2023-08-20T23:46:29Z")

</div>

Ok, what is the difference between PUT and PATCH? It looks like they do a similar function. What am I missing?

 ![image](https://global.discourse-cdn.com/free1/uploads/netfoundry/original/2X/c/c5313d212cfe4a19395bc26c32b67d7b0012213c.png)

---

<div class="post-metadata">

**Author:** ![TheLumberjack](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/thelumberjack/32/113_2.png) [@TheLumberjack](https://openziti.discourse.group/u/TheLumberjack)\
**Post date:** [August 21, 2023, 12:22am UTC](https://openziti.discourse.group/t/management-api-config-patch-method/1531/5 "2023-08-21T00:22:13Z")

</div>

### PATCH seems not to be working?

A PATCH operation should update a specified field. a PUT operation will update "all the fields" and you'll have to supply all the json.  
I just issued a curl to get my :

```auto
curl -sk -X GET -H "zt-session: $token" $mycontroller/edge/management/v1/configs | jq .

```

to get id: `5LwHA6zG0lxSPrENcThzeL`.

Then I did a GET on that config:

```auto
curl -sk -X GET -H "zt-session: $token" $mycontroller/edge/management/v1/configs/5LwHA6zG0lxSPrENcThzeL | jq .data[]

```

which gives me valid json:

```auto
curl -sk -X GET -H "zt-session: $token" $baseurl/edge/management/v1/configs/5LwHA6zG0lxSPrENcThzeL | jq .
{
  "data": {
    "_links": {
      "self": {
        "href": "./configs/5LwHA6zG0lxSPrENcThzeL"
      }
    },
    "createdAt": "2023-08-20T03:12:06.977Z",
    "id": "5LwHA6zG0lxSPrENcThzeL",
    "tags": {},
    "updatedAt": "2023-08-20T03:12:06.977Z",
    "configType": {
      "_links": {
        "self": {
          "href": "./config-types/NH5p4FpGR"
        }
      },
      "entity": "config-types",
      "id": "NH5p4FpGR",
      "name": "host.v1"
    },
    "configTypeId": "NH5p4FpGR",
    "data": {
      "address": "apache-exporter",
      "listenOptions": {
        "bindUsingEdgeIdentity": true
      },
      "port": 9117,
      "protocol": "tcp"
    },
    "name": "prometheus.host.v1"
  },
  "meta": {}
}

```

So I tried to PATCH 'address':

```auto
curl -sk -X PATCH -H "Content-Type: application/json" -H "zt-session: $token" $mycontroller/edge/management/v1/configs/5LwHA6zG0lxSPrENcThzeL -d '{"data": {"address": "new_address"}}' | jq .

```

The controller returns:

```auto
{
  "error": {
    "cause": {
      "field": "(root)",
      "reason": "(root) is invalid: (root): Must validate \"else\" as \"if\" was not valid",
      "value": "map[address:new_address]"
    },
    "code": "COULD_NOT_VALIDATE",
    "message": "The supplied request contains an invalid document or no valid accept content were available, see cause",
    "requestId": "zOKuMNPmP"
  },
  "meta": {
    "apiEnrollmentVersion": "0.0.1",
    "apiVersion": "0.0.1"
  }
}

```

### Using PUT Works

So I made a PUT.txt file (for easy use in curl):

```auto
{
    "createdAt": "2023-08-20T03:12:06.977Z",
    "id": "5LwHA6zG0lxSPrENcThzeL",
    "tags": {},
    "updatedAt": "2023-08-20T03:12:06.977Z",
    "configType": {
      "_links": {
        "self": {
          "href": "./config-types/NH5p4FpGR"
        }
      },
      "entity": "config-types",
      "id": "NH5p4FpGR",
      "name": "host.v1"
    },
    "configTypeId": "NH5p4FpGR",
    "data": {
      "address": "updated-apache-exporter",
      "listenOptions": {
        "bindUsingEdgeIdentity": true
      },
      "port": 9117,
      "protocol": "tcp"
    },
    "name": "prometheus.host.v1"
}

```

Then used curl to PUT that back:

```auto
curl -sk -X PUT -H "Content-Type: application/json" -H "zt-session: $token" $baseurl/edge/management/v1/configs/5LwHA6zG0lxSPrENcThzeL -d @PUT.txt

```

Afterwards, you can see my config address updated:

```auto
curl -sk -X GET -H "zt-session: $token" \
  $baseurl/edge/management/v1/configs/5LwHA6zG0lxSPrENcThzeL \
  | jq .data.data.address
"updated-apache-exporter"

```

I think we need @andrew.martinez to weigh on this one. PATCH wouldn't work for me.

---

<div class="post-metadata">

**Author:** ![andrew.martinez](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/andrew.martinez/32/540_2.png) [@andrew.martinez](https://openziti.discourse.group/u/andrew.martinez)\
**Post date:** [August 24, 2023, 1:27pm UTC](https://openziti.discourse.group/t/management-api-config-patch-method/1531/6 "2023-08-24T13:27:27Z")

</div>

I recall there being some commotion for config `PATCH`, that I don't clearly recall. I think @plorenz might have been involved.

For the rest of the APIs, PUT is a full update, defaulting optional fields to their defaults and PATCH should only alter the values specified in the request payload. This should be kept consistent here, but as I said above there was a commotion that I don't clearly remember around this endpoint.

As an aside, PUT is also used in some APIs to allow full updates as well as create new resources at specific IDs. We don't support creating specific ids because it can cause issues with the internal database size/performance depending on how the ids are selected.

---

<div class="post-metadata">

**Author:** ![plorenz](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/plorenz/32/54_2.png) [@plorenz](https://openziti.discourse.group/u/plorenz)\
**Post date:** [August 24, 2023, 2:00pm UTC](https://openziti.discourse.group/t/management-api-config-patch-method/1531/7 "2023-08-24T14:00:59Z")

</div>

Patch works, you just need to provide a complete JSON document. PATCH lets you update individual fields and the config JSON is one field of the config. Just as you can't change just the third character of the config name, you can't change just one part of the config JSON. Does that make sense? If we did allow that, it wouldn't be PATCH semantics, it would be something config specific and we'd have to allow specifying how to merge the two JSON documents together.

Example:

```bash
plorenz@vimes:~/work/nf/ziti$ ziti edge create config foo host.v1 '{
      "address": "apache-exporter",
      "listenOptions": {
        "bindUsingEdgeIdentity": true
      },
      "port": 9117,
      "protocol": "tcp"
    }'
New config foo created with id: 7kwgRdBIfEaHAsYDFNJJwi

```

```auto
plorenz@vimes:~/work/nf/ziti$ ziti edge update config foo --output-request-json --data '{
      "address": "some-other-address",
      "listenOptions": {
        "bindUsingEdgeIdentity": true
      },
      "port": 9117,
      "protocol": "tcp"
    }'
PATCH to https://localhost:1280/edge/management/v1/configs/7kwgRdBIfEaHAsYDFNJJwi
{
    "data": {
        "address": "some-other-address",
        "listenOptions": {
            "bindUsingEdgeIdentity": true
        },
        "port": 9117,
        "protocol": "tcp"
    }
}

```

Cheers,  
Paul

---

<div class="post-metadata">

**Author:** ![dariuszSki](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/dariuszski/32/339_2.png) [@dariuszSki](https://openziti.discourse.group/u/dariuszSki)\
**Post date:** [August 24, 2023, 2:50pm UTC](https://openziti.discourse.group/t/management-api-config-patch-method/1531/8 "2023-08-24T14:50:51Z")

</div>

This is very interesting discussion to me. If one researches about differences between PUT and PATCH, one can find a lof of conflicting views about this topic. The more I read the more I am confused about it.

With that being said, can you elaborate on this "PATCH lets you update individual fields and the config JSON is one field of the config". Especially the second part of the statement. Also this " it wouldn't be PATCH semantics"

As I posted at the beginning of this thread, I can use PUT and accomplish the same thing . I only changed one parameter in both requests. Why would one need to use PATCH if one can use PUT?

I often see this explanation when comparing PUT and PATCH

`PATCH is used to apply partial updates to a resource, meaning that only the fields that need to be changed are sent in the request body. PUT is used to replace the entire resource with a new representation, meaning that all the fields of the resource are sent in the request body, even if they are not modified.`

---

<div class="post-metadata">

**Author:** ![andrew.martinez](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/andrew.martinez/32/540_2.png) [@andrew.martinez](https://openziti.discourse.group/u/andrew.martinez)\
**Post date:** [August 25, 2023, 2:21pm UTC](https://openziti.discourse.group/t/management-api-config-patch-method/1531/9 "2023-08-25T14:21:59Z")

</div>

The exact intents for `PUT` and `PATCH` differ between API implementations. API development never circled the wagons on a protocol definition. Instead, a set of conventions has arisen.

It is simpler to take each API in stride. For OpenZiti, `PATCH` allows one to update specified fields on a resource. `PUT` replaces a resource, keeping its ID and other references. In most cases, `PATCH` will be used as it is more convenient for developers. `PUT` has limited applications where developers want to replace a resource fully, and they want their API call to fail if they aren't specifying all of the required fields.
