Update
Update, PATCH /entities/{id}/attrs, changes the attributes in the body that the entity already has, and adds the ones it doesn't. It answers 204, or 207 when some members are left unwritten, and lists those in notUpdated.
This update changes speed:
- http
- curl
- rust
- python
PATCH /ngsi-ld/v1/entities/urn:ngsi-ld:Vehicle:A4567/attrs
Content-Type: application/json
{
"speed": {
"type": "Property",
"value": 60
}
}
curl -i -X PATCH http://localhost:1056/ngsi-ld/v1/entities/urn:ngsi-ld:Vehicle:A4567/attrs \
-H 'Content-Type: application/json' \
-d '{
"speed": {
"type": "Property",
"value": 60
}
}'
let fragment = EntityFragment::builder()
.property("speed", 60)
.build()?;
let outcome = client
.entities()
.update_attributes(&id, &fragment)
.send()
.await?;
response = requests.patch(
f"{ENTITY}/attrs",
json={
"speed": {
"type": "Property",
"value": 60,
},
},
)
assert response.status_code in (204, 207)
The answer is 204 whether speed was there before or not. You get 207 with an updated list and a notUpdated list in two cases. One is a scope in the body when the entity has no Scope, in which case the update ignores it and lists it with the reason Attribute not found. The other is an attribute a context source refused, listed with the registrationId of its registration.
Update swaps the instance
Update Attributes and Append Attributes work on whole attribute instances. The instance in the body becomes the attribute, its type included, so an update can even turn a Property into a Relationship.
- http
- curl
- rust
- python
PATCH /ngsi-ld/v1/entities/urn:ngsi-ld:Vehicle:A4567/attrs
Content-Type: application/json
{
"brandName": {
"type": "Relationship",
"object": "urn:ngsi-ld:Brand:Mercedes"
}
}
curl -i -X PATCH http://localhost:1056/ngsi-ld/v1/entities/urn:ngsi-ld:Vehicle:A4567/attrs \
-H 'Content-Type: application/json' \
-d '{
"brandName": {
"type": "Relationship",
"object": "urn:ngsi-ld:Brand:Mercedes"
}
}'
let fragment = EntityFragment::builder()
.relationship("brandName", iri!("urn:ngsi-ld:Brand:Mercedes"))
.build()?;
let outcome = client
.entities()
.update_attributes(&id, &fragment)
.send()
.await?;
response = requests.patch(
f"{ENTITY}/attrs",
json={
"brandName": {
"type": "Relationship",
"object": "urn:ngsi-ld:Brand:Mercedes",
},
},
)
assert response.status_code == 204
HTTP/1.1 204 No Content
brandName is a Relationship afterwards, and nothing of the old Property remains. Members the body does not mention are not carried over.
Changing one attribute
To change one attribute only, send it to its own path.
PATCH /entities/{id}/attrs/{attrId}changes the members you send.PUT /entities/{id}/attrs/{attrId}replaces the attribute with what you send, as replace describes.
Partial Attribute Update, the PATCH, replaces the attribute's content member, the value, languageMap, json, vocab or object, and keeps the rest of the attribute.
- http
- curl
- rust
- python
PATCH /ngsi-ld/v1/entities/urn:ngsi-ld:Building:1/attrs/address
Content-Type: application/json
{
"type": "Property",
"value": {
"street": "Pariser Platz"
}
}
curl -i -X PATCH http://localhost:1056/ngsi-ld/v1/entities/urn:ngsi-ld:Building:1/attrs/address \
-H 'Content-Type: application/json' \
-d '{
"type": "Property",
"value": {
"street": "Pariser Platz"
}
}'
let address: AttributeName = "address".parse()?;
let patch = ValuePatch::new().set("street", "Pariser Platz");
let attribute = Attribute::from(Property::merge_builder(patch).build()?);
let outcome = client
.entities()
.update_attribute(&building, &address, attribute)
.send()
.await?;
response = requests.patch(
f"{BUILDING}/attrs/address",
json={
"type": "Property",
"value": {
"street": "Pariser Platz",
},
},
)
assert response.status_code == 204
HTTP/1.1 204 No Content
The address value is now exactly {"street": "Pariser Platz"}. The city and country inside the value are gone, because the whole value was replaced, and a unitCode or observedAt beside it would have stayed. When the value is an object you want to change inside, partial update is the wrong verb.
Updating one instance
Each instance carries its own datasetId. An append or update names the instance it means.
- http
- curl
- rust
- python
PATCH /ngsi-ld/v1/entities/urn:ngsi-ld:Room:1/attrs
Content-Type: application/json
{
"temperature": {
"type": "Property",
"value": 22.0,
"datasetId": "urn:ngsi-ld:Dataset:sensor-a"
}
}
curl -i -X PATCH http://localhost:1056/ngsi-ld/v1/entities/urn:ngsi-ld:Room:1/attrs \
-H 'Content-Type: application/json' \
-d '{
"temperature": {
"type": "Property",
"value": 22.0,
"datasetId": "urn:ngsi-ld:Dataset:sensor-a"
}
}'
let room = EntityId::from(iri!("urn:ngsi-ld:Room:1"));
let fragment = EntityFragment::builder()
.property(
"temperature",
Property::builder(Value::Number("22.0".parse()?)).dataset_id(iri!("urn:ngsi-ld:Dataset:sensor-a")),
)
.build()?;
let outcome = client
.entities()
.update_attributes(&room, &fragment)
.send()
.await?;
response = requests.patch(
f"{BASE}/entities/urn:ngsi-ld:Room:1/attrs",
json={
"temperature": {
"type": "Property",
"value": 22.0,
"datasetId": "urn:ngsi-ld:Dataset:sensor-a",
},
},
)
assert response.status_code in (204, 207)
This changes only the sensor-a instance. An instance without datasetId is the default instance, and a write that omits datasetId targets it. The data model guide explains instances.
What gets refused
404ResourceNotFoundwhen the entity doesn't exist, or a partial update names an attribute it doesn't have.207when some members were left unwritten. Ascopethe entity has none to replace, or an attribute a context source refused, is listed innotUpdated.400BadRequestDatafor a JSONnullanywhere in the body. Deletion is the NGSI-LD Null, and only in a merge or a partial update.- Everything in the common list.