This tutorial teaches NGSI-LD users about CRUD Operations. The tutorial outlines example usage of the various ways of amending context as detailed within the NGSI-LD specification. A series of entities representing temperature sensors are created, modified and deleted based on the temperature sensor model defined in an earlier tutorial.
The tutorial uses cUrl commands throughout, but is also available as Postman documentation.
- このチュートリアルは日本語でもご覧いただけます。
Details
- NGSI-LD CRUD Operations
- Prerequisites
- Architecture
- Start Up - Create Operations - Create a New Data Entity - Create New Attributes - Batch Create New Data Entities or Attributes - Batch Create/Overwrite New Data Entities - Read Operations - Filtering - Read a Data Entity (verbose) - Read an Attribute from a Data Entity - Read a Data Entity (key-value pairs) - Read Multiple attributes values from a Data Entity - List all Data Entities (verbose) - List all Data Entities (key-value pairs) - Filter Data Entities by ID - Update Operations - Overwrite the value of an Attribute value - Overwrite Multiple Attributes of a Data Entity - Batch Update Attributes of Multiple Data Entities - Batch Replace Entity Data - Delete Operations - Data Relationships - Delete an Entity - Delete an Attribute from an Entity - Batch Delete Multiple Entities - Batch Delete Multiple Attributes from an Entity - Find existing data relationships
“Ninety-percent of everything is crud.”
― Theodore Sturgeon, Venture Science Fiction Magazine
CRUD Operations (Create, Read, Update and Delete) are the four basic functions of persistent storage. For a smart system based on NGSI-LD, CRUD actions allow the developer to manipulate the context data within the system. Every CRUD operation is clearly defined within the NGSI-LD specification, so all NGSI-LD compliant context brokers offer the same interface with the same NGSI-LD operations.
This tutorial will describe the rational behind each operation, when to use it and how to execute the various CRUD
operations. Since NGSI-LD is based on JSON-LD passing of @context
as part of each request in mandatory. For
CRUD operations this is typically passed as a Link
header, although as we have seen is also possible to pass an
@context
attribute as part of the body of the request if Content-Type: application/ld+json
. However for GET
requests, the @context
cannot be placed in the payload body technique as GET requests have no body.
There are four endpoints used for CRUD operations on an individual data entity. These follow the usual rules for hierarchical entities within RESTful applications.
For operations where the <entity-id>
is not yet known within the context, or is unspecified, the
/ngsi-ld/v1/entities
endpoint is used. As an example, this is used for creating new entities.
Once an <entity-id>
is known within the context, individual data entities can be manipulated using the
/ngsi-ld/v1/entities/<entity-id>
endpoint.
General Attribute operations on a known entity occur on the /ngsi-ld/v1/entities/<entity-id>/attrs
endpoint and
operations on individual attributes occur on the /ngsi-ld/v1/entities/<entity-id>/attrs/<attr-id>
.
When requesting data or modifying individual entities, the various CRUD operations map naturally to HTTP verbs.
- GET - for reading data
- POST - for creating new entities and attributes
- PATCH - for amending entities and attributes
- DELETE - for deleting entities and attributes
Batch operations allow users to modify multiple data entities with a single request. All batch operations are mapped to the POST HTTP verb.
/entityOperations/create
/entityOperations/update
/entityOperations/upsert
/entityOperations/delete
To keep things simple all components will be run using Docker. Docker is a container technology which allows to different components isolated into their respective environments.
- To install Docker on Windows follow the instructions here
- To install Docker on Mac follow the instructions here
- To install Docker on Linux follow the instructions here
Docker Compose is a tool for defining and running multi-container Docker applications. A YAML file is used configure the required services for the application. This means all container services can be brought up in a single command. Docker Compose is installed by default as part of Docker for Windows and Docker for Mac, however Linux users will need to follow the instructions found here
We will start up our services using a simple bash script. Windows users should download the Windows Subsystem for Linux to provide a command-line functionality similar to a Linux distribution on Windows.
The demo application will send and receive NGSI-LD calls to a compliant context broker. Since the standardized NGSI-LD interface is available across multiple context brokers, so we only need to pick one - for example the Orion Context Broker. The application will therefore only make use of one FIWARE component.
Currently, the Orion Context Broker relies on open source MongoDB technology to keep persistence of the context data it holds.
To promote interoperability of data exchange, NGSI-LD context brokers explicitly expose a
JSON-LD @context
file to define the data held within the
context entities. This defines a unique URI for every entity type and every attribute so that other services outside of
the NGSI domain are able to pick and choose the names of their data structures. Every @context
file must be available
on the network. In our case the tutorial application will be used to host a series of static files.
Therefore, the architecture will consist of three elements:
- The Orion Context Broker which will receive requests using NGSI-LD
- The underlying MongoDB database :
- Used by the Orion Context Broker to hold context data information such as data entities, subscriptions and registrations
- An HTTP Web-Server which offers static
@context
files defining the context entities within the system.
Since all interactions between the three elements are initiated by HTTP requests, the elements can be containerized and run from exposed ports.
The necessary configuration information can be seen in the services section of the associated orion-ld.yml
file:
orion:
image: quay.io/fiware/orion-ld
hostname: orion
container_name: fiware-orion
depends_on:
- mongo-db
networks:
- default
ports:
- "1026:1026"
command: -dbhost mongo-db -logLevel DEBUG
healthcheck:
test: curl --fail -s http://orion:1026/version || exit 1
mongo-db:
image: mongo:3.6
hostname: mongo-db
container_name: db-mongo
expose:
- "27017"
ports:
- "27017:27017"
networks:
- default
command: --nojournal
ld-context:
image: httpd:alpine
hostname: context
container_name: fiware-ld-context
ports:
- "3004:80"
The necessary configuration information can be seen in the services section of the associated docker-compose.yml
file.
It has been described in a previous tutorial
All services can be initialised from the command-line by running the services Bash script provided within the repository. Please clone the repository and create the necessary images by running the commands as shown:
git clone https://github.com/FIWARE/tutorials.CRUD-Operations.git
cd tutorials.CRUD-Operations
git checkout NGSI-LD
./services [orion|scorpio|stellio]
Note
If you want to clean up and start over again you can do so with the following command:
./services stop
Create Operations map to HTTP POST.
- The
/ngsi-ld/v1/entities
endpoint is used for creating new entities - The
/ngsi-ld/v1/entities/<entity-id>/attrs
endpoint is used for adding new attributes
Any newly created entity must have id
and type
attributes and a valid @context
definition. All other attributes
are optional and will depend on the system being modelled. If additional attributes are present though, each should
specify both a type
and a value
.
The response will be 201 - Created if the operation is successful or 409 - Conflict if the operation fails.
This example adds a new TemperatureSensor entity to the context.
curl -iX POST 'http://localhost:1026/ngsi-ld/v1/entities/' \
-H 'Content-Type: application/json' \
-H 'Link: <http://context/user-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
--data-raw '{
"id": "urn:ngsi-ld:TemperatureSensor:001",
"type": "TemperatureSensor",
"category": {
"type": "VocabProperty",
"vocab": "sensor"
},
"temperature": {
"type": "Property",
"value": 25,
"unitCode": "CEL"
}
}'
New entities can be added by making a POST request to the /ngsi-ld/v1/entities
endpoint.
The request will fail if the entity already exists in the context.
You can check to see if the new TemperatureSensor can be found in the context by making a GET request
curl -L -X GET 'http://localhost:1026/ngsi-ld/v1/entities/urn:ngsi-ld:TemperatureSensor:001' \
-H 'Link: <http://context/user-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"'
This example adds a new batteryLevel
Property and a controlledAsset
Relationship to the existing
TemperatureSensor entity with id=urn:ngsi-ld:TemperatureSensor:001
.
curl -iX POST 'http://localhost:1026/ngsi-ld/v1/entities/urn:ngsi-ld:TemperatureSensor:001/attrs' \
-H 'Content-Type: application/json' \
-H 'Link: <http://context/user-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
--data-raw '{
"batteryLevel": {
"type": "Property",
"value": 0.9,
"unitCode": "C62"
},
"controlledAsset": {
"type": "Relationship",
"object": "urn:ngsi-ld:Building:barn002"
}
}'
New attributes can be added by making a POST request to the /ngsi-ld/v1/entities/<entity>/attrs
endpoint.
The payload should consist of a JSON object holding the attribute names and values as shown.
All type=Property
attributes must have a value
associated with them. All type=Relationship
attributes must have an
object
associated with them which holds the URN of another entity. Well-defined common metadata elements such as
unitCode
can be provided as strings, all other metadata should be passed as a JSON object with its own type
and
value
attributes
Subsequent requests using the same id
will update the value of the attribute in the context.
You can check to see if the new TemperatureSensor can be found in the context by making a GET request
curl -L -X GET 'http://localhost:1026/ngsi-ld/v1/entities/urn:ngsi-ld:TemperatureSensor:001' \
-H 'Link: <http://context/user-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"'
As you can see there are now two additional attributes (batteryLevel
and controlledAsset
) added to the entity. These
attributes have been defined in the @context
as part of the Device model and therefore can be read using their
short names.
This example uses the convenience batch processing endpoint to add three new TemperatureSensor entities to the
context. Batch create uses the /ngsi-ld/v1/entityOperations/create
endpoint.
curl -iX POST 'http://localhost:1026/ngsi-ld/v1/entityOperations/create' \
-H 'Content-Type: application/json' \
-H 'Link: <http://context/user-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
-H 'Accept: application/ld+json' \
--data-raw '[
{
"id": "urn:ngsi-ld:TemperatureSensor:002",
"type": "TemperatureSensor",
"category": {
"type": "VocabProperty",
"vocab": "sensor"
},
"temperature": {
"type": "Property",
"value": 20,
"unitCode": "CEL"
}
},
{
"id": "urn:ngsi-ld:TemperatureSensor:003",
"type": "TemperatureSensor",
"category": {
"type": "VocabProperty",
"vocab": "sensor"
},
"temperature": {
"type": "Property",
"value": 2,
"unitCode": "CEL"
}
},
{
"id": "urn:ngsi-ld:TemperatureSensor:004",
"type": "TemperatureSensor",
"category": {
"type": "VocabProperty",
"vocab": "sensor"
},
"temperature": {
"type": "Property",
"value": 100,
"unitCode": "CEL"
}
}
]'
The request will fail if any of the attributes already exist in the context. The response highlights which actions have been successful and the reason for failure (if any has occurred).
[
"urn:ngsi-ld:TemperatureSensor:002",
"urn:ngsi-ld:TemperatureSensor:003",
"urn:ngsi-ld:TemperatureSensor:004"
]
This example uses the convenience batch processing endpoint to add or amend two TemperatureSensor entities in the context.
- if an entity already exists, the request will update that entity's attributes.
- if an entity does not exist, a new entity will be created.
curl -iX POST 'http://localhost:1026/ngsi-ld/v1/entityOperations/upsert' \
-H 'Content-Type: application/json' \
-H 'Link: <http://context/user-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
-H 'Accept: application/ld+json' \
--data-raw '[
{
"id": "urn:ngsi-ld:TemperatureSensor:002",
"type": "TemperatureSensor",
"category": {
"type": "VocabProperty",
"vocab": "sensor"
},
"temperature": {
"type": "Property",
"value": 21,
"unitCode": "CEL"
}
},
{
"id": "urn:ngsi-ld:TemperatureSensor:003",
"type": "TemperatureSensor",
"category": {
"type": "VocabProperty",
"vocab": "sensor"
},
"temperature": {
"type": "Property",
"value": 27,
"unitCode": "CEL"
}
}
]'
Batch processing for create/overwrite uses the /ngsi-ld/v1/entityOperations/upsert
endpoint.
A subsequent request containing the same data (i.e. same entities and actionType=append
) will also succeed won't
change the context state. The modifiedAt
metadata will be amended however.
- The
/ngsi-ld/v1/entities
endpoint is used for listing entities - The
/ngsi-ld/v1/entities/<entity>
endpoint is used for retrieving the details of a single entity.
For read operations the @context
must be supplied in a Link
header.
- The
options
parameter (combined with theattrs
parameter) can be used to filter the returned fields - The
q
parameter can be used to filter the returned entities
This example reads the full context from an existing TemperatureSensor entity with a known id
.
curl -G -iX GET 'http://localhost:1026/ngsi-ld/v1/entities/urn:ngsi-ld:TemperatureSensor:001' \
-H 'Link: <http://context/user-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
-d 'options=sysAttrs'
TemperatureSensor urn:ngsi-ld:TemperatureSensor:001
is returned as normalized NGSI-LD. Additional metadata is
returned because options=sysAttrs
. By default the @context
is returned in the payload body (although this could be
moved due to content negotiation if the Accept:application/json
had been set. The full response is shown below:
{
"id": "urn:ngsi-ld:TemperatureSensor:001",
"type": "TemperatureSensor",
"createdAt": "2020-08-27T14:33:06Z",
"modifiedAt": "2020-08-27T14:33:10Z",
"category": {
"type": "VocabProperty",
"createdAt": "2020-08-27T14:33:06Z",
"modifiedAt": "2020-08-27T14:33:06Z",
"vocab": "sensor"
},
"temperature": {
"type": "Property",
"createdAt": "2020-08-27T14:33:06Z",
"modifiedAt": "2020-08-27T14:33:06Z",
"value": 25,
"unitCode": "CEL"
},
"batteryLevel": {
"value": 0.9,
"type": "Property",
"createdAt": "2020-08-27T14:33:10Z",
"modifiedAt": "2020-08-27T14:33:10Z",
"unitCode": "C62"
},
"controlledAsset": {
"object": "urn:ngsi-ld:Building:barn002",
"type": "Relationship",
"createdAt": "2020-08-27T14:33:10Z",
"modifiedAt": "2020-08-27T14:33:10Z"
}
}
Individual context data entities can be retrieved by making a GET request to the /ngsi-ld/v1/entities/<entity>
endpoint.
This example reads the value of a single attribute (temperature
) from an existing TemperatureSensor entity with a
known id
.
curl -G -iX GET 'http://localhost:1026/ngsi-ld/v1/entities/urn:ngsi-ld:TemperatureSensor:001' \
-H 'Link: <http://context/user-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
-d 'attrs=temperature'
The sensor urn:ngsi-ld:TemperatureSensor:001
is reading at 25°C. The response is shown below:
{
"id": "urn:ngsi-ld:TemperatureSensor:001",
"type": "TemperatureSensor",
"temperature": {
"type": "Property",
"value": 25,
"unitCode": "CEL"
}
}
Because options=keyValues
was not used this is the normalized response including the metadata such as unitCode
.
Context data can be retrieved by making a GET request to the /ngsi-ld/v1/entities/<entity-id>
endpoint and selecting
the attrs
using a comma separated list.
This example reads the key-value pairs from the context of an existing TemperatureSensor entities with a known id
.
curl -G -iX GET 'http://localhost:1026/ngsi-ld/v1/entities/urn:ngsi-ld:TemperatureSensor:001' \
-H 'Link: <http://context/user-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
-H 'Accept: application/json' \
-d 'options=keyValues'
The sensor urn:ngsi-ld:TemperatureSensor:001
is reading at 25°C. The response is shown below:
{
"id": "urn:ngsi-ld:TemperatureSensor:001",
"type": "TemperatureSensor",
"category": "sensor",
"temperature": 25,
"batteryLevel": 0.8,
"controlledAsset": "urn:ngsi-ld:Building:barn002"
}
The response contains an unfiltered list of context data from an entity containing all of the attributes of the
urn:ngsi-ld:TemperatureSensor:001
. The payload body does not contain an @context
attribute since the
Accept: application/json
was set.
Combine the options=keyValues
parameter with the attrs
parameter to retrieve a limited set of key-value pairs.
This example reads the value of two attributes (category
and temperature
) from the context of an existing
TemperatureSensor entity with a known id
.
curl -G -iX GET 'http://localhost:1026/ngsi-ld/v1/entities/urn:ngsi-ld:TemperatureSensor:001' \
-H 'Link: <http://context/user-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
-H 'Accept: application/json' \
-d 'options=keyValues' \
-d 'attrs=category,temperature'
The sensor urn:ngsi-ld:TemperatureSensor:001
is reading at 25°C. The response is shown below:
{
"id": "urn:ngsi-ld:TemperatureSensor:001",
"type": "TemperatureSensor",
"category": "sensor",
"temperature": 25
}
Combine the options=keyValues
parameter and the attrs
parameter to return a list of values.
This example lists the full context of all TemperatureSensor entities.
curl -G -iX GET 'http://localhost:1026/ngsi-ld/v1/entities/' \
-H 'Link: <http://context/user-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
-d 'type=TemperatureSensor'
On start-up the context was empty, four TemperatureSensor entities have been added by create operations so the full context will now contain four sensors.
[
{
"id": "urn:ngsi-ld:TemperatureSensor:004",
"type": "TemperatureSensor",
"category": {
"type": "VocabProperty",
"vocab": "sensor"
},
"temperature": {
"type": "Property",
"value": 100,
"unitCode": "CEL"
}
},
{
"id": "urn:ngsi-ld:TemperatureSensor:002",
"type": "TemperatureSensor",
"category": {
"type": "VocabProperty",
"vocab": "sensor"
},
"temperature": {
"type": "Property",
"value": 21,
"unitCode": "CEL"
}
},
{
"id": "urn:ngsi-ld:TemperatureSensor:003",
"type": "TemperatureSensor",
"category": {
"type": "VocabProperty",
"vocab": "sensor"
},
"temperature": {
"type": "Property",
"value": 27,
"unitCode": "CEL"
}
},
{
"id": "urn:ngsi-ld:TemperatureSensor:001",
"type": "TemperatureSensor",
"batteryLevel": {
"type": "Property",
"value": 0.8,
"unitCode": "C62"
},
"category": {
"type": "VocabProperty",
"vocab": "sensor"
},
"controlledAsset": {
"type": "Relationship",
"object": "urn:ngsi-ld:Building:barn002"
},
"temperature": {
"type": "Property",
"value": 25,
"unitCode": "CEL"
}
}
]
This example lists the temperature
attribute of all TemperatureSensor entities.
curl -G -iX GET 'http://localhost:1026/ngsi-ld/v1/entities/' \
-H 'Link: <http://context/user-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
-H 'Accept: application/json' \
-d 'type=TemperatureSensor' \
-d 'options=keyValues' \
-d 'attrs=temperature'
The full context contains four sensors, they are returned in a random order:
[
{
"id": "urn:ngsi-ld:TemperatureSensor:004",
"type": "TemperatureSensor",
"temperature": 100
},
{
"id": "urn:ngsi-ld:TemperatureSensor:002",
"type": "TemperatureSensor",
"temperature": 21
},
{
"id": "urn:ngsi-ld:TemperatureSensor:003",
"type": "TemperatureSensor",
"temperature": 27
},
{
"id": "urn:ngsi-ld:TemperatureSensor:001",
"type": "TemperatureSensor",
"temperature": 25
}
]
Full context data for a specified entity type can be retrieved by making a GET request to the /ngsi-ld/v1/entities/
endpoint and supplying the type
parameter, combine this with the options=keyValues
parameter and the attrs
parameter to retrieve key-values.
This example lists selected data from two TemperatureSensor entities chosen by id
. Note that every id
must be
unique, so type
is not required for this request. To filter by id
add the entries in a comma delimited list.
curl -G -iX GET 'http://localhost:1026/ngsi-ld/v1/entities/' \
-H 'Link: <http://context/user-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
-H 'Accept: application/json' \
-d 'id=urn:ngsi-ld:TemperatureSensor:001,urn:ngsi-ld:TemperatureSensor:002' \
-d 'options=keyValues' \
-d 'attrs=temperature'
The response details the selected attributes from the selected entities.
[
{
"id": "urn:ngsi-ld:TemperatureSensor:002",
"type": "TemperatureSensor",
"temperature": 21
},
{
"id": "urn:ngsi-ld:TemperatureSensor:001",
"type": "TemperatureSensor",
"temperature": 25
}
]
Overwrite operations are mapped to HTTP PATCH:
- The
/ngsi-ld/v1/entities/<entity-id>/attrs/<attribute>
endpoint is used to update an attribute - The
/ngsi-ld/v1/entities/<entity-id>/attrs
endpoint is used to update multiple attributes
This example updates the value of the category
attribute of the Entity with id=urn:ngsi-ld:TemperatureSensor:001
curl -iX PATCH 'http://localhost:1026/ngsi-ld/v1/entities/urn:ngsi-ld:TemperatureSensor:001/attrs/category' \
-H 'Content-Type: application/json' \
-H 'Link: <http://context/user-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
--data-raw '{
"vocab": ["sensor", "actuator"],
"type": "VocabProperty"
}'
Existing attribute values can be altered by making a PATCH request to the
/ngsi-ld/v1/entities/<entity-id>/attrs/<attribute>
endpoint. The appropriate @context
should be supplied as a Link
header.
This example simultaneously updates the values of both the category
and controlledAsset
attributes of the Entity
with id=urn:ngsi-ld:TemperatureSensor:001
.
curl -iX PATCH 'http://localhost:1026/ngsi-ld/v1/entities/urn:ngsi-ld:TemperatureSensor:001/attrs' \
-H 'Content-Type: application/json' \
-H 'Link: <http://context/user-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
--data-raw '{
"category": {
"vocab": [
"sensor",
"actuator"
],
"type": "VocabProperty"
},
"controlledAsset": {
"type": "Relationship",
"object": "urn:ngsi-ld:Building:barn001"
}
}'
This example uses the convenience batch processing endpoint to update existing sensors.
curl -iX POST 'http://localhost:1026/ngsi-ld/v1/entityOperations/upsert?options=update' \
-H 'Content-Type: application/json' \
-H 'Link: <http://context/user-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
--data-raw '[
{
"id": "urn:ngsi-ld:TemperatureSensor:003",
"type": "TemperatureSensor",
"category": {
"type": "VocabProperty",
"vocab": [
"actuator",
"sensor"
]
}
},
{
"id": "urn:ngsi-ld:TemperatureSensor:004",
"type": "TemperatureSensor",
"category": {
"type": "VocabProperty",
"vocab": [
"actuator",
"sensor"
]
}
}
]'
Batch processing uses the /ngsi-ld/v1/entityOperations/upsert
endpoint. The payload body holds an array of the
entities and attributes we wish to update. The options=update
parameter indicates we will not remove existing
attributes if they already exist and have not been included in the payload.
An alternative would be to use the /ngsi-ld/v1/entityOperations/update
endpoint. Unlike upsert
, the update
operation will not silently create any new entities - it fails if the entities do not already exist.
This example uses the convenience batch processing endpoint to replace entity data of existing sensors.
curl -iX POST 'http://localhost:1026/ngsi-ld/v1/entityOperations/update?options=replace' \
-H 'Content-Type: application/json' \
-H 'Link: <http://context/user-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
--data-raw '[
{
"id": "urn:ngsi-ld:TemperatureSensor:003",
"type": "TemperatureSensor",
"category": {
"type": "VocabProperty",
"vocab": [
"actuator",
"sensor"
]
}
},
{
"id": "urn:ngsi-ld:TemperatureSensor:004",
"type": "TemperatureSensor",
"category": {
"type": "VocabProperty",
"vocab": [
"actuator",
"sensor"
]
}
}
]'
Batch processing uses the /ngsi-ld/v1/entityOperations/update
endpoint with a payload with the - options=replace
parameter, this means we will overwrite existing entities. /ngsi-ld/v1/entityOperations/upsert
could also be used if
new entities are also to be created.
Delete Operations map to HTTP DELETE.
- The
/ngsi-ld/v1/entities/<entity-id>
endpoint can be used to delete an entity - The
/ngsi-ld/v1/entities/<entity-id>/attrs/<attribute>
endpoint can be used to delete an attribute
The response will be 204 - No Content if the operation is successful or 404 - Not Found if the operation fails.
If there are entities within the context which relate to one another, you must be careful when deleting an entity. You will need to check that no references are left dangling once the entity has been deleted.
Organizing a cascade of deletions is beyond the scope of this tutorial, but it would be possible using a batch delete request.
This example deletes the entity with id=urn:ngsi-ld:TemperatureSensor:004
from the context.
curl -iX DELETE 'http://localhost:1026/ngsi-ld/v1/entities/urn:ngsi-ld:TemperatureSensor:004'
Entities can be deleted by making a DELETE request to the /ngsi-ld/v1/entities/<entity>
endpoint.
Subsequent requests using the same id
will result in an error response since the entity no longer exists in the
context.
This example removes the batteryLevel
attribute from the entity with id=urn:ngsi-ld:TemperatureSensor:001
.
curl -L -X DELETE 'http://localhost:1026/ngsi-ld/v1/entities/urn:ngsi-ld:TemperatureSensor:001/attrs/batteryLevel' \
-H 'Link: <http://context/user-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"'
Attributes can be deleted by making a DELETE request to the /ngsi-ld/v1/entities/<entity>/attrs/<attribute>
endpoint.
It is important to supply the appropriate @context
in the request in the form of a Link
header to ensure that the
attribute name can be recognised.
If the entity does not exist within the context or the attribute cannot be found on the entity, the result will be an error response.
This example uses the convenience batch processing endpoint to delete some TemperatureSensor entities.
curl -L -X POST 'http://localhost:1026/ngsi-ld/v1/entityOperations/delete' \
-H 'Content-Type: application/json' \
--data-raw '[
"urn:ngsi-ld:TemperatureSensor:002",
"urn:ngsi-ld:TemperatureSensor:003"
]'
Batch processing uses the /ngsi-ld/v1/entityOperations/delete
endpoint with a payload consisting of an array of
elements to delete.
If an entity does not exist in the context, the result will be an error response.
This example uses the PATCH /ngsi-ld/v1/entities/<entity-id>/attrs
endpoint to delete some attributes from a
TemperatureSensor entity.
curl -L -X PATCH 'http://localhost:1026/ngsi-ld/v1/entities/urn:ngsi-ld:TemperatureSensor:001/attrs' \
-H 'Content-Type: application/json' \
-H 'Link: <http://context/user-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
--data-raw '{
"category": {
"vocab": "urn:ngsi-ld:null",
"type": "VocabProperty"
},
"controlledAsset": {
"type": "Relationship",
"object": "urn:ngsi-ld:null"
}
}'
If a value is set to urn:ngsi-ld:null
the attribute is deleted.
This example returns a header indicating whether any linked data relationships remain against the entity
urn:ngsi-ld:Building:barn002
curl -iX GET 'http://localhost:1026/ngsi-ld/v1/entities/?type=TemperatureSensor&limit=0&count=true&q=controlledAsset==%22urn:ngsi-ld:Building:barn002%22' \
-H 'Link: <http://context/user-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
-H 'Accept: application/json'
[]
Because the limit=0
parameter has been used no entities are listed in the payload body, however the count=true
means that the count is passed as a header instead:
NGSILD-Results-Count: 1
If limit
was not present the payload would hold the details of every matching entity instead.
Want to learn how to add more complexity to your application by adding advanced features? You can find out by reading the other tutorials in this series
MIT © 2020-2025 FIWARE Foundation e.V.