FIWARE Core Context Management NGSI v2

Description: This tutorial teaches FIWARE users about CRUD Operations. The tutorial builds on the data created in the previous stock management example and introduces the concept of CRUD operations, allowing users to manipulate the data held within the context.

The tutorial uses cUrl commands throughout, but is also available as Postman documentation.

Run in Postman Run in GitPod


Data Entities

Within the FIWARE platform, an entity represents the state of a physical or conceptual object which exists in the real world.

Entities within a stock management system

Within our simple stock management system, we currently have four entity types. The relationships between our entities are defined as shown below:

  • A Store is a real world bricks and mortar building. Stores would have properties such as:
    • Store name, e.g. "Checkpoint Markt"
    • Address, e.g. "Friedrichstraße 44, 10969 Kreuzberg, Berlin"
    • Physical location, e.g. 52.5075 N, 13.3903 E
  • A Shelf is a real world object to hold items which we wish to sell. Each shelf would have properties such as:
    • Shelf name, e.g. "Wall Unit"
    • Physical location, e.g. 52.5075 N, 13.3903 E
    • Maximum capacity
    • An association to the store in which the shelf is located
  • A Product is defined as something that we sell - it is a conceptual object. Products would have properties such as:
    • Product name, e.g. "Melons"
    • Price, e.g. 13.99 Euros
    • Size, e.g. Small
  • An Inventory Item is another conceptual entity, used to associate products, stores, shelves and physical objects. It would have properties such as:
    • An association to the product being sold
    • An association to the store in which the product is being sold
    • An association to the shelf where the product is being displayed
    • Stock count, i.e. product quantity available in the warehouse
    • Shelf count, i.e. number of items available on the shelf

As you can see, each of the entities defined above contain some properties which are liable to change. For example, product price could change, stock could be sold and the number of items on the shelves would drop.


Architecture

This application will only make use of one FIWARE component - the Orion Context Broker. Using the Orion Context Broker is sufficient for an application to qualify as “Powered by FIWARE”.

Currently, the Orion Context Broker relies on open source MongoDB technology to store the context data it manages. Therefore, the architecture will consist of two components:

  • The Orion Context Broker which will receive requests using NGSI-v2
  • The underlying MongoDB database:
    • Used by the Orion Context Broker to store context information such as data entities, subscriptions and registrations

Since the two components interact by means of HTTP requests, they can be containerized and run from exposed ports.

The necessary configuration information can be seen in the services section of the associated docker-compose.yml file:

orion:
    image: quay.io/fiware/orion:latest
    hostname: orion
    container_name: orion
    depends_on:
        - mongo-db
    networks:
        - default
    expose:
        - '1026'
    ports:
        - '1026:1026'
    command: -dbhost mongo-db -logLevel DEBUG
mongo-db:
    image: mongo:4.2
    hostname: mongo-db
    container_name: db-mongo
    expose:
        - '27017'
    ports:
        - '27017:27017'
    networks:
        - default

Both containers reside on the same network - the Orion Context Broker is listening on port 1026 and MongoDB is listening on the default port 27017. For the sake of this tutorial, we have also made the two ports available from outside the network so that cUrl or Postman can access them without having to be run from inside the network. The command-line initialization should be self-explanatory.

Start Up

All services can be initialised from the command-line by running the bash script provided within the repository. Please clone the repository and create the necessary images by running the commands as shown below:

#!/bin/bash
git clone https://github.com/FIWARE/tutorials.CRUD-Operations.git
cd tutorials.CRUD-Operations

./services start

This command will also import seed data from the previous Store Finder tutorial on startup.

Note: If you want to clean up and start over again you can do so with the following command:

./services stop

What is CRUD?

Create, Read, Update and Delete are the four basic functions of persistent storage. These operations are usually referred to using the acronym CRUD. Within a database each of these operations map directly to a series of commands, however their relationship with a RESTful API is slightly more complex.

The Orion Context Broker uses NGSI-v2 to manipulate the context data. As a RESTful API, requests to manipulate the data held within the context follow the standard conventions found when mapping HTTP verbs to CRUD operations.

Entity CRUD Operations

For operations where the <entity-id> is not yet known within the context, or is unspecified, the /v2/entities endpoint is used.

Once an <entity-id> is known within the context, individual data entities can be manipulated using the /v2/entities/<entity-id> endpoint.

It is recommended that entity identifiers should be URNs following the NGSI-LD specification, therefore each id is a URN which follows a standard format: urn:ngsi-ld:<entity-type>:<entity-id>. This helps to make every id in the context data unique.

HTTP Verb /v2/entities /v2/entities/<entity-id>
POST CREATE a new entity and add to the context. CREATE or UPDATE an attribute of a specified entity.
GET READ entity data from the context. This will return data from multiple entities. The data can be filtered. READ entity data from a specified entity. This will return data from a single entity only. The data can be filtered.
PUT :x: :x:
PATCH :x: :x:
DELETE :x: DELETE an entity from the context

A complete list of entity endpoints can be found in the NGSI v2 Swagger Specification

Attribute CRUD Operations

To perform CRUD operations on attributes, the <entity-id> must be known. Each attribute is effectively a key-value pair.

There are three endpoints:

  • /v2/entities/<entity-id>/attrs is only used for a patch operation to update one or more existing attributes.
  • /v2/entities/<entity-id>/attrs/<attribute> is used to manipulate an attribute as a whole.
  • /v2/entities/<entity-id>/attrs/<attribute>/value is used to read or update the value of an attribute, leaving the type untouched.
HTTP Verb .../attrs .../attrs/<attribute> .../attrs/<attribute>/value
POST :x: :x: :x:
GET :x: :x: READ the value of an attribute from a specified entity. This will return a single field.
PUT :x: :x: UPDATE the value of single attribute from a specified entity.
PATCH UPDATE one or more existing attributes from an existing entity. :x: :x:
DELETE. :x: DELETE an existing attribute from an existing entity. :x:

A complete list of attribute endpoints can be found in the NGSI v2 Swagger Specification

Batch CRUD Operations

Additionally, the Orion Context Broker has a convenience batch operation endpoint /v2/op/update to manipulate multiple entities in a single operation.

Batch operations are always triggered by a POST request where the payload is an object with two properties:

  • actionType specifies the kind of action to invoke (e.g. delete)
  • entities is an array of objects holding the list of entities to update, along with the relevant entity data used to perform the operation.

Example CRUD Operations using FIWARE

The following examples assume that the Orion Context Broker is listening on port 1026 of localhost, and the initial seed data has been imported from the previous tutorial.

All examples refer to the Product entity as defined in the stock management system. CRUD operations will therefore relate to adding, reading, amending and deleting a product or series of products. This is a typical use case for a store regional manager, for example setting prices and deciding what products can be sold. The actual responses you receive in each case will depend on the state of the context data in your system at the time. If you find that you have already deleted an entity by mistake, you can restore the initial context by reloading the data from the command-line

./import-data

Create Operations

Create Operations map to HTTP POST.

  • The /v2/entities endpoint is used for creating new entities
  • The /v2/entities/<entity> endpoint is used for adding new attributes

Any newly created entity must have id and type attributes, 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 204 - No Content if the operation is successful or 422 - Unprocessable Entity if the operation fails.

Create a New Data Entity

This example adds a new Product entity ("Lemonade" at 99 cents) to the context.

1 Request:

curl -iX POST \
  --url 'http://localhost:1026/v2/entities' \
  --header 'Content-Type: application/json' \
  --data ' {
      "id":"urn:ngsi-ld:Product:010", "type":"Product",
      "name":{"type":"Text", "value":"Lemonade"},
      "size":{"type":"Text", "value": "S"},
      "price":{"type":"Integer", "value": 99}
}'

New entities can be added by making a POST request to the /v2/entities endpoint.

The request will fail if any of the attributes already exist in the context.

2 Request:

You can check to see if the new Product can be found in the context by making a GET request

curl -X GET \
  --url 'http://localhost:1026/v2/entities/urn:ngsi-ld:Product:010?type=Product'

Create a New Attribute

This example adds a new specialOffer attribute to the existing Product entity with id=urn:ngsi-ld:Product:001.

3 Request:

curl -iX POST \
  --url 'http://localhost:1026/v2/entities/urn:ngsi-ld:Product:001/attrs' \
  --header 'Content-Type: application/json' \
  --data '{
      "specialOffer":{"value": true}
}'

New attributes can be added by making a POST request to the /v2/entities/<entity>/attrs endpoint.

The payload should consist of a JSON object holding the attribute names and values as shown.

If no type is specified a default type (Boolean, Text , Number or StructuredValue) will be assigned.

Subsequent requests using the same id will update the value of the attribute in the context.

4 Request:

You can check to see if the new Product attribute can be found in the context by making a GET request

curl -X GET \
  --url 'http://localhost:1026/v2/entities/urn:ngsi-ld:Product:001?type=Product'

As you can see there is now a boolean specialOffer flag attached to the "Apples" Product entity.

Batch Create New Data Entities or Attributes

This example uses the convenience batch processing endpoint to add two new Product entities and one new attribute (offerPrice) to the context.

5 Request:

curl -iX POST \
  --url 'http://localhost:1026/v2/op/update' \
  --header 'Content-Type: application/json' \
  --data '{
  "actionType":"append_strict",
  "entities":[
    {
      "id":"urn:ngsi-ld:Product:011", "type":"Product",
      "name":{"type":"Text", "value":"Brandy"},
      "size":{"type":"Text", "value": "M"},
      "price":{"type":"Integer", "value": 1199}
    },
    {
      "id":"urn:ngsi-ld:Product:012", "type":"Product",
      "name":{"type":"Text", "value":"Port"},
      "size":{"type":"Text", "value": "M"},
      "price":{"type":"Integer", "value": 1099}
    },
    {
      "id":"urn:ngsi-ld:Product:001", "type":"Product",
      "offerPrice":{"type":"Integer", "value": 89}
    }
  ]
}'

The request will fail if any of the attributes already exist in the context.

Batch processing uses the /v2/op/update endpoint with a payload with two attributes

  • actionType=append_strict means that the request only succeeds if all entities / attributes are new.
  • The entities attribute holds an array of entities we wish to create.

Subsequent requests using the same data with the actionType=append_strict batch operation will result in an error response.

Batch Create/Overwrite New Data Entities

This example uses the convenience batch processing endpoint to add or amend two Product entities and one attribute (offerPrice) to 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.

6 Request:

curl -iX POST \
  --url 'http://localhost:1026/v2/op/update' \
  --header 'Content-Type: application/json' \
  --data '{
  "actionType":"append",
  "entities":[
    {
      "id":"urn:ngsi-ld:Product:011", "type":"Product",
      "name":{"type":"Text", "value":"Brandy"},
      "size":{"type":"Text", "value": "M"},
      "price":{"type":"Integer", "value": 1199}
    },
    {
      "id":"urn:ngsi-ld:Product:012", "type":"Product",
      "name":{"type":"Text", "value":"Port"},
      "size":{"type":"Text", "value": "M"},
      "price":{"type":"Integer", "value": 1099}
    }
  ]
}'

Batch processing uses the /v2/op/update endpoint with a payload with two attributes:

  • actionType=append means we will overwrite existing entities if they exist
  • The entities attribute holds an array of entities we wish to create/overwrite.

A subsequent request containing the same data (i.e. same entities and actionType=append) won't change the context state.

Read Operations

  • The /v2/entities endpoint is used for listing entities
  • The /v2/entities/<entity> endpoint is used for retrieving the details of a single entity

Filtering

  • The options parameter (combined with the attrs parameter) can be used to filter the returned fields
  • The q parameter can be used to filter the returned entities

Read a Data Entity (verbose)

This example reads the full context from an existing Product entity with a known id.

7 Request:

curl -X GET \
  --url 'http://localhost:1026/v2/entities/urn:ngsi-ld:Product:010?type=Product'

Response:

Product urn:ngsi-ld:Product:010 is "Lemonade" at 99 cents. The response is shown below:

Tip: Use jq to format the JSON responses in this tutorial. Pipe the result by appending

| jq '.'

{
    "id": "urn:ngsi-ld:Product:010",
    "type": "Product",
    "name": { "type": "Text", "value": "Lemonade", "metadata": {} },
    "price": { "type": "Integer", "value": 99, "metadata": {} },
    "size": { "type": "Text", "value": "S", "metadata": {} }
}

Context data can be retrieved by making a GET request to the /v2/entities/<entity> endpoint.

Read an Attribute from a Data Entity

This example reads the value of a single attribute (name) from an existing Product entity with a known id.

8 Request:

curl -X GET \
  --url 'http://localhost:1026/v2/entities/urn:ngsi-ld:Product:001/attrs/name/value'

Response:

Product urn:ngsi-ld:Product:001 is "Apples" at 99 cents. The response is shown below:

"Apples"

Context data can be retrieved by making a GET request to the /v2/entities/<entity>/attrs/<attribute>/value endpoint.

Read a Data Entity (key-value pairs)

This example reads the key-value pairs of two attributes (name and price) from the context of existing Product entities with a known id.

9 Request:

curl -X GET \
  --url 'http://localhost:1026/v2/entities/urn:ngsi-ld:Product:001?type=Product&options=keyValues&attrs=name,price'

Response:

Product urn:ngsi-ld:Product:001 is "Apples" at 99 cents. The response is shown below:

{
    "id": "urn:ngsi-ld:Product:001",
    "type": "Product",
    "name": "Apples",
    "price": 99
}

Combine the options=keyValues parameter with the attrs parameter to retrieve key-value pairs.

Read Multiple attributes values from a Data Entity

This example reads the value of two attributes (name and price) from the context of existing Product entities with a known ID.

10 Request:

curl -X GET \
  --url 'http://localhost:1026/v2/entities/urn:ngsi-ld:Product:001?type=Product&options=values&attrs=name,price'

Response:

Product urn:ngsi-ld:Product:001 is "Apples" at 99 cents. The response is shown below:

["Apples", 99]

Combine the options=values parameter and the attrs parameter to return a list of values in an array.

List all Data Entities (verbose)

This example lists the full context of all Product entities.

11 Request:

curl -X GET \
  --url 'http://localhost:1026/v2/entities?type=Product'

Response:

On start-up the context held nine products, three more have been added by create operations so the full context will now contain twelve products.

[
    {
        "id": "urn:ngsi-ld:Product:001",
        "type": "Product",
        "name": { "type": "Text", "value": "Apples", "metadata": {} },
        "offerPrice": { "type": "Integer", "value": 89, "metadata": {} },
        "price": { "type": "Integer", "value": 99, "metadata": {} },
        "size": { "type": "Text", "value": "S", "metadata": {} },
        "specialOffer": { "type": "Boolean", "value": true, "metadata": {} }
    },
    {
        "id": "urn:ngsi-ld:Product:002",
        "type": "Product",
        "name": { "type": "Text", "value": "Bananas", "metadata": {} },
        "price": { "type": "Integer", "value": 1099, "metadata": {} },
        "size": { "type": "Text", "value": "M", "metadata": {} }
    },
    {
        "id": "urn:ngsi-ld:Product:003",
        "type": "Product",
        "name": { "type": "Text", "value": "Coconuts", "metadata": {} },
        "price": { "type": "Integer", "value": 1499, "metadata": {} },
        "size": { "type": "Text", "value": "M", "metadata": {} }
    },
    {
        "id": "urn:ngsi-ld:Product:004",
        "type": "Product",
        "name": { "type": "Text", "value": "Melons", "metadata": {} },
        "price": { "type": "Integer", "value": 5000, "metadata": {} },
        "size": { "type": "Text", "value": "XL", "metadata": {} }
    },
    {
        "id": "urn:ngsi-ld:Product:005",
        "type": "Product",
        "name": { "type": "Text", "value": "Kiwi Fruits", "metadata": {} },
        "price": { "type": "Integer", "value": 99, "metadata": {} },
        "size": { "type": "Text", "value": "S", "metadata": {} }
    },
    {
        "id": "urn:ngsi-ld:Product:006",
        "type": "Product",
        "name": { "type": "Text", "value": "Strawberries", "metadata": {} },
        "price": { "type": "Integer", "value": 99, "metadata": {} },
        "size": { "type": "Text", "value": "S", "metadata": {} }
    },
    {
        "id": "urn:ngsi-ld:Product:007",
        "type": "Product",
        "name": { "type": "Text", "value": "Raspberries", "metadata": {} },
        "price": { "type": "Integer", "value": 99, "metadata": {} },
        "size": { "type": "Text", "value": "S", "metadata": {} }
    },
    {
        "id": "urn:ngsi-ld:Product:008",
        "type": "Product",
        "name": { "type": "Text", "value": "Pineapples", "metadata": {} },
        "price": { "type": "Integer", "value": 99, "metadata": {} },
        "size": { "type": "Text", "value": "S", "metadata": {} }
    },
    {
        "id": "urn:ngsi-ld:Product:009",
        "type": "Product",
        "name": { "type": "Text", "value": "Oranges", "metadata": {} },
        "price": { "type": "Integer", "value": 99, "metadata": {} },
        "size": { "type": "Text", "value": "S", "metadata": {} }
    },
    {
        "id": "urn:ngsi-ld:Product:010",
        "type": "Product",
        "name": { "type": "Text", "value": "Lemonade", "metadata": {} },
        "price": { "type": "Integer", "value": 99, "metadata": {} },
        "size": { "type": "Text", "value": "S", "metadata": {} }
    },
    {
        "id": "urn:ngsi-ld:Product:011",
        "type": "Product",
        "name": { "type": "Text", "value": "Brandy", "metadata": {} },
        "price": { "type": "Integer", "value": 1199, "metadata": {} },
        "size": { "type": "Text", "value": "M", "metadata": {} }
    },
    {
        "id": "urn:ngsi-ld:Product:012",
        "type": "Product",
        "name": { "type": "Text", "value": "Port", "metadata": {} },
        "price": { "type": "Integer", "value": 1099, "metadata": {} },
        "size": { "type": "Text", "value": "M", "metadata": {} }
    }
]

List all Data Entities (key-value pairs)

This example lists the name and price attributes of all Product entities.

12 Request:

curl -X GET \
  --url 'http://localhost:1026/v2/entities/?type=Product&options=keyValues&attrs=name,price'

Response:

On start-up the context held nine products, three more have been added by create operations so the full context will now contain twelve products.

[
    {
        "id": "urn:ngsi-ld:Product:001",
        "type": "Product",
        "name": "Apples",
        "price": 99
    },
    {
        "id": "urn:ngsi-ld:Product:002",
        "type": "Product",
        "name": "Bananas",
        "price": 1099
    },
    {
        "id": "urn:ngsi-ld:Product:003",
        "type": "Product",
        "name": "Coconuts",
        "price": 1499
    },
    {
        "id": "urn:ngsi-ld:Product:004",
        "type": "Product",
        "name": "Melons",
        "price": 5000
    },
    {
        "id": "urn:ngsi-ld:Product:005",
        "type": "Product",
        "name": "Kiwi Fruits",
        "price": 99
    },
    {
        "id": "urn:ngsi-ld:Product:006",
        "type": "Product",
        "name": "Strawberries",
        "price": 99
    },
    {
        "id": "urn:ngsi-ld:Product:007",
        "type": "Product",
        "name": "Raspberries",
        "price": 99
    },
    {
        "id": "urn:ngsi-ld:Product:008",
        "type": "Product",
        "name": "Pineapples",
        "price": 99
    },
    {
        "id": "urn:ngsi-ld:Product:009",
        "type": "Product",
        "name": "Oranges",
        "price": 99
    },
    {
        "id": "urn:ngsi-ld:Product:010",
        "type": "Product",
        "name": "Lemonade",
        "price": 99
    },
    {
        "id": "urn:ngsi-ld:Product:011",
        "type": "Product",
        "name": "Brandy",
        "price": 1199
    },
    {
        "id": "urn:ngsi-ld:Product:012",
        "type": "Product",
        "name": "Port",
        "price": 1099
    }
]

Full context data for a specified entity type can be retrieved by making a GET request to the /v2/entities endpoint and supplying the type parameter, combine this with the options=keyValues parameter and the attrs parameter to retrieve key-values.

List Data Entity by type

This example lists the id and type of all Product entities.

13 Request:

curl -X GET \
  --url 'http://localhost:1026/v2/entities/?type=Product&options=count&attrs=__NONE'

Response:

On start-up the context held nine products, three more have been added by create operations so the full context will now contain twelve products.

[
    {
        "id": "urn:ngsi-ld:Product:001",
        "type": "Product"
    },
    {
        "id": "urn:ngsi-ld:Product:002",
        "type": "Product"
    },
    {
        "id": "urn:ngsi-ld:Product:003",
        "type": "Product"
    },
    {
        "id": "urn:ngsi-ld:Product:004",
        "type": "Product"
    },
    {
        "id": "urn:ngsi-ld:Product:005",
        "type": "Product"
    },
    {
        "id": "urn:ngsi-ld:Product:006",
        "type": "Product"
    },
    {
        "id": "urn:ngsi-ld:Product:007",
        "type": "Product"
    },
    {
        "id": "urn:ngsi-ld:Product:008",
        "type": "Product"
    },
    {
        "id": "urn:ngsi-ld:Product:009",
        "type": "Product"
    },
    {
        "id": "urn:ngsi-ld:Product:010",
        "type": "Product"
    },
    {
        "id": "urn:ngsi-ld:Product:011",
        "type": "Product"
    },
    {
        "id": "urn:ngsi-ld:Product:012",
        "type": "Product"
    }
]

Context data for a specified entity type can be retrieved by making a GET request to the /v2/entities endpoint and supplying the type parameter. Combine this with options=count and attrs=__NONE to return the id attributes of the given type.

Note: The NGSIv2 specification specifies that attrs= has to be a "comma-separated list of attribute names whose data are to be included in the response". id and type are not allowed to be used as attribute names. If you specify a name that does not exist in attributes, such as __NONE to the attrs= parameter, No attribute will match and you will always retrieve only the id and type of the entity.

Update Operations

Overwrite operations are mapped to HTTP PUT. HTTP PATCH can be used to update several attributes at once.

  • The /v2/entities/<entity>/attrs/<attribute>/value endpoint is used to update an attribute
  • The /v2/entities/<entity>/attrs endpoint is used to update multiple attributes

Overwrite the value of an Attribute value

This example updates the value of the price attribute of the Entity with id=urn:ngsi-ld:Product:001

14 Request:

curl -iX PUT \
  --url 'http://localhost:1026/v2/entities/urn:ngsi-ld:Product:001/attrs/price/value?type=Product' \
  --header 'Content-Type: text/plain' \
  --data 89

Existing attribute values can be altered by making a PUT request to the /v2/entities/<entity>/attrs/<attribute>/value endpoint.

Overwrite Multiple Attributes of a Data Entity

This example simultaneously updates the values of both the price and name attributes of the Entity with id=urn:ngsi-ld:Product:001.

15 Request:

curl -iX PATCH \
  --url 'http://localhost:1026/v2/entities/urn:ngsi-ld:Product:001/attrs?type=Product' \
  --header 'Content-Type: application/json' \
  --data ' {
      "price":{"type":"Integer", "value": 89},
      "name": {"type":"Text", "value": "Ale"}
}'

Batch Overwrite Attributes of Multiple Data Entities

This example uses the convenience batch processing endpoint to update existing products.

16 Request:

curl -iX POST \
  --url 'http://localhost:1026/v2/op/update' \
  --header 'Content-Type: application/json' \
  --data '{
  "actionType":"update",
  "entities":[
    {
      "id":"urn:ngsi-ld:Product:001", "type":"Product",
      "price":{"type":"Integer", "value": 1199}
    },
    {
      "id":"urn:ngsi-ld:Product:002", "type":"Product",
      "price":{"type":"Integer", "value": 1199},
      "size": {"type":"Text", "value": "L"}
    }
  ]
}'

Batch processing uses the /v2/op/update endpoint with a payload with two attributes - actionType=append means we will overwrite existing entities if they exist whereas the entities attribute holds an array of entities we wish to update.

Batch Create/Overwrite Attributes of Multiple Data Entities

This example uses the convenience batch processing endpoint to update existing products.

17 Request:

curl -iX POST \
  --url 'http://localhost:1026/v2/op/update' \
  --header 'Content-Type: application/json' \
  --data '{
  "actionType":"append",
  "entities":[
    {
      "id":"urn:ngsi-ld:Product:001", "type":"Product",
      "price":{"type":"Integer", "value": 1199}
    },
    {
      "id":"urn:ngsi-ld:Product:002", "type":"Product",
      "price":{"type":"Integer", "value": 1199},
      "specialOffer": {"type":"Boolean", "value":  true}
    }
  ]
}'

Batch processing uses the /v2/op/update endpoint with a payload with two attributes - actionType=append means we will overwrite existing entities if they exist whereas the entities attribute holds an array of entities we wish to update.

Batch Replace Entity Data

This example uses the convenience batch processing endpoint to replace entity data of existing products.

18 Request:

curl -iX POST \
  --url 'http://localhost:1026/v2/op/update' \
  --header 'Content-Type: application/json' \
  --data '{
  "actionType":"replace",
  "entities":[
    {
      "id":"urn:ngsi-ld:Product:010", "type":"Product",
      "price":{"type":"Integer", "value": 1199}
    }
  ]
}'

Batch processing uses the /v2/op/update endpoint with a payload with two attributes - actionType=replace means we will overwrite existing entities if they exist whereas the entities attribute holds an array of entities whose data we wish to replace.

Delete Operations

Delete Operations map to HTTP DELETE.

  • The /v2/entities/<entity> endpoint can be used to delete an entity
  • The /v2/entities/<entity>/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.

Data Relationships

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.

Delete an Entity

This example deletes the entity with id=urn:ngsi-ld:Product:001 from the context.

19 Request:

curl -iX DELETE \
  --url 'http://localhost:1026/v2/entities/urn:ngsi-ld:Product:010'

Entities can be deleted by making a DELETE request to the /v2/entities/<entity> endpoint.

Subsequent requests using the same id will result in an error response since the entity no longer exists in the context.

Delete an Attribute from an Entity

This example removes the specialOffer attribute from the entity with id=urn:ngsi-ld:Product:001.

20 Request:

curl -iX DELETE \
  --url 'http://localhost:1026/v2/entities/urn:ngsi-ld:Product:001/attrs/specialOffer'

Attributes can be deleted by making a DELETE request to the /v2/entities/<entity>/attrs/<attribute> endpoint.

If the attribute does not exist in the context, the result will be an error response.

Batch Delete Multiple Entities

This example uses the convenience batch processing endpoint to delete some Product entities.

21 Request:

curl -iX POST \
  --url 'http://localhost:1026/v2/op/update' \
  --header 'Content-Type: application/json' \
  --data '{
  "actionType":"delete",
  "entities":[
    {
      "id":"urn:ngsi-ld:Product:001", "type":"Product"
    },
    {
      "id":"urn:ngsi-ld:Product:002", "type":"Product"
    }
  ]
}'

Batch processing uses the /v2/op/update endpoint with a payload with two attributes - actionType=delete means we will delete something from the context and the entities attribute holds the id of the entities we wish to delete.

If an entity does not exist in the context, the result will be an error response.

Batch Delete Multiple Attributes from an Entity

This example uses the convenience batch processing endpoint to delete some attributes from a Product entity.

22 Request:

curl -iX POST \
  --url 'http://localhost:1026/v2/op/update' \
  --header 'Content-Type: application/json' \
  --data '{
  "actionType":"delete",
  "entities":[
    {
      "id":"urn:ngsi-ld:Product:003", "type":"Product",
      "price":{},
      "name": {}
    }
  ]
}'

Batch processing uses the /v2/op/update endpoint with a payload with two attributes - actionType=delete means we will delete something from the context and the entities attribute holds an array of attributes we wish to delete.

If any attribute does not exist in the context, the result will be an error response.

Find existing data relationships

This example returns the key of all entities directly associated with the urn:ngsi-ld:Product:001.

23 Request:

curl -X GET \
  --url 'http://localhost:1026/v2/entities/?q=refProduct==urn:ngsi-ld:Product:001&options=count&attrs=type'

Response:

[
    {
        "id": "urn:ngsi-ld:InventoryItem:001",
        "type": "InventoryItem"
    },
    {
        "id": "urn:ngsi-ld:InventoryItem:004",
        "type": "InventoryItem"
    },
    {
        "id": "urn:ngsi-ld:InventoryItem:006",
        "type": "InventoryItem"
    },
    {
        "id": "urn:ngsi-ld:InventoryItem:401",
        "type": "InventoryItem"
    }
]
  • If this request returns an empty array, the entity has no associates - it can be safely deleted
  • If the response lists a series of InventoryItem entities they should be deleted before the associated Product entity is removed from the context.

Note that we deleted Product urn:ngsi-ld:Product:001 earlier, so what we see above is actually a dangling reference, i.e. the returned InventoryItem references a Product that no longer exists.