REST Object API Write

Provides the Create, Update and Delete calls for objects. Sub-entity deletion is considered an update of the object. Update calls will check if the given item already exists and will create it when not.

Create/Update Object

Permissions

Entity Permissions

The user needs to have the corresponding entity permission. They need to have CREATE in case a new item should be created and EDIT for any update of an existing item. In case sub-entities have separate entity permissions they need to apply too.

Object Permissions

The user needs to have the WRITE object permission in case of an update of an existing entity item. In case he doesn't, the api returns HTTP 403 (forbidden)

Field Permissions

The user needs to have the WRITE field permissions for all fields he wants to write.

Qualification Permissions (aka Qualified Field Permissions)

The user needs to have the WRITE permission for a qualification, e.g. for Language = English. If he doesn't, sub-entities which are qualified for this will not be persisted, and an error is returned in the protocol

Body

The structure of the body for the object api is similar, no matter if a post or put is executed. With one exception:

The attribute which represents the external, alphanumeric identifier can be omitted in case of the create api, as the framework will generate a new identifier automatically.

Fields and Entities

The repository property "shortIdentifier" in the custom section is used to define the entity and field names for the json/xml structure. The short identifier is unique within its parent entity only!

The standard repository already contains a short identifier for all fields and enabled qualifications.

Meta attributes

All meta attributes are prefixed with an underscore. Here is a list of the meta attributes used in the body besides the ones already described in the datatypes section.

_qualification

The qualification of the record. The combination of the qualification values in the qualification object define this record as unique within its parent.

_changeType

Optional attribute which defines how a sub-entity record should be handled.

put

The sub-entity record is updated in case it already exists. It will be created if it doesn't exist. This is the default mode in case this attribute is missing

remove

The sub-entity record is removed in case it exists. If not, nothing happens. To uniquely identify the record to be removed, the qualification element is needed. Other attributes can be omitted in this case.

Datatypes

ENTITY_ITEM

Objects can be specified by either the _internalId or the _externalId attribute. In case both is given, the _internalId takes precedence due to performance reasons, there is no fallback logic to the _externalId.
In case the entity item can not be resolved an error is returned.

Please note the Syntax (don't overlook the single quotes for external id!):

Entity Items with container:

_externalId: 'Identifier'@'ContainerIdentifier'

_internalId: InternalID@ContainerInternalID

Entity Items without container:

_externalId: 'Identifier'

_internalId: InternalID

Single quotes as part of the identifiers need to be escaped with a backslash. Like

'Iden\'tifier'@'ContainerIdentifir'

Please note that quotes, backslashes or the @ symbol should be escaped in URLs.
Please take a look at the REST Datatypes page for more information.

Entity item with the external id:

"catalog": { "_externalId": "'MY_SUPPLIER_CATALOG'" }

Entity item with the internal id:

"catalog": { "_internalId": "1120" }

MIME_VALUE

A reference to a mime file which must be provided in a separate zip archive
A mime value has a label. The label is shown in the UI in case a preview picture is not used there. The file path defines the location of the file inside of the zip archive when you download or upload the mime value.

The label and type are optional in case you want to write a mime value. They will be extracted from the filePath if omitted.
Please note that the relative file path of a mime value will change once it's uploaded and saved as Product 360 makes sure that every mime value is unique in the system. If you retrieve the mime value again after the upload, the
path will be different. It should always be treated as a black box.

MIME_VALUE object, which at least must contain the relative _filePath.
The file path must correspond to the file location within the uploaded archive file.

_label

Optional: Human readable label for the mime value. Defaults to the filename in the path attribute (without extension)

_type

Optional: The official mime type of the file. If omitted, the mime type will be determined based on the file extension using the mapping provided in the mime.types file in the Product 360 configuration folder.

_path

Mandatory: File patch to the mime file. The path is relative to the ZIP Archive which has been uploaded prior to the REST call with the REST File API.

{
"_label": "Example Picture",
"_type": "image/jpg",
"_path": "mySubFolderInTheZip\examplePicture.jpg"
}

timestamp

ISO 8601 (YYYY-MM-DDTHH:mm:ss.sss)

2012-04-23T18:25:43.511

date

ISO 8601 (YYYY-MM-DD)

2019-07-04

time

ISO 8601 (HH:mm:ss.sss)

18:25:43.511

numbers

Standard JSON. A dot is the decimal separator, no thousand separators

Rounding logic for decimal fields:

The number of fraction digits is defined in the repository with the scale attribute. In case the given value has a higher precision (a higher scale) the API will apply a rounding algorithm to the value to bring it to the maximum scale which is defined in the repository.

The rounding algorithm used it HALF_UP:
Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round up.
If the discarded fraction is ≥ 0.5 it's rounded up; otherwise, down.
Note that this is the rounding mode commonly taught at school.

For more details on this rounding mode you can have a look at the Java documentation for it.

123.45

text

Standard JSON

"My Text"

boolean

Standard JSON, true/false

true | false

Enumeration Fields

Enumeration fields can have _key or _code or _label. Always only one of the three possibilities is considered, even is multiples are provided. Key is used before code, and code is used before label.

In case the label must be used, the HTTP requests locale is used to interpret it. For performance reasons we strongly recommend to use _key or _code.

In case the enumeration field is of datatype ENTITY_ITEM, then the _key must be provided with the ENTITY_ITEM syntax (see above)

No Value / Empty / Null

If an attribute is given with null, null will be applied to the entity item's field. An empty string will be treated as null for text fields.

If an attribute is not part of the document, it will be ignored. In case the attribute is defined as mandatory, a corresponding error will be returned in the protocol

Multi-Value fields

Single fields which are defined as multi-value in the repository (upperBound>1) must be provided as array. It is not possible to add or remove a single value. The existing values will be replaced with the given ones.

Mime-Value fields

To be able to set mime values you need to first upload the binaries in form of a ZIP archive which contains all files which are referenced from the JSON payload. If the file is missing, a corresponding error is returned.

The file can contain folders and sub folders, however, the JSON payload needs to include the full path to the picture within the archive.

See the REST File API for details on how to upload the archive.

A single archive file can be used for multiple items. It will automatically be deleted 24 hours after it has been uploaded.

Examples

Example which uses only external ids for ENTITY_ITEM fields or the code for enumeration fields

This is the typical scenario in which the client of this api has no deeper knowledge on the internal id's or keys of entities and enumeration values.

{
"identifier": "identifier-1",
"manufacturerAID": "A000000000000",
"manufacturerName": "BMW",
"catalog": {
"_code": "MySupplierCatalog"
},
"orderUnit": {
"_code": "C62"
},
"lang": [
{
"_qualification": {
"language": {
"_code": "deu"
}
},
"keywords": [
"shift"
],
"segment": "be treating his father’s favourite in such a manner, one whom",
"manufacturerTypeDescription": "of him. Proud tha",
"descriptionShort": "feel he had been wrong; he had liberality, and he had the mean",
"remarks": "be at present; that you actually declared your resolution of never taking orders"
}
]
}

Response

The response contains useful meta attributes to easily identify the newly created entity item. The entity as well as the new identifier and the container it has been created in as well as the ready to use ENTITY_ITEM syntax.

Meta attributes

_entity

The root entity identifier

_entityItem

The entity item in the ENTITY_ITEM syntax

_identifier

The external, alphanumeric identifier of the entity item. Although this identifier is already part of the _entityItem attribute, it's added separately for your convenience.
The identifier is unique within the container

_container

The container of the entity item in the ENTITY_ITEM syntax. For items, products and variants it's the catalog, for structure groups it is the structure system, etc. Not all entities do have a containers.

_protocol

An array of protocol entries which provide details in case the validation returned errors or warnings. See below for details

{
"_entity": "Article",
"_entityItem": {
"_internalId": "13989@1120",
"_entityId": 1000,
"_externalId": "\u0027NewItem\u0027@\u0027MY_SUPPLIER_CATALOG\u0027"
},
"_identifier": "NewItem",
"_container": {
"_internalId": "1120",
"_entityId": 7000,
"_externalId": "\u0027MY_SUPPLIER_CATALOG\u0027"
},
"_protocol": {
"infoCounter": 0,
"warningCounter": 0,
"errorCounter": 1,
"entries": [
{
"severity": "ERROR",
"category": "DATATYPE",
"property": "Article.OrderUnit",
"message": "\u0027orderUnit\u0027 (Article.OrderUnit): Code value \u0027NoIdea\u0027 not found in enumeration \u0027Enum.OrderUnits\u0027. Either the code is not part of the enumeration or the user has no read permission"
}
]
}
}

Protocol

infoCounter

Number of entries with INFO severity

warningCounter

Number of entries with WARNING severity

errorCounter

Number of entries with ERROR severity

entries

Array of protocol entries

Protocol Entry

severity

INFO, WARNING or ERROR

category

The category of the protocol entry.
Possible categories are:

SYSTEM

Category for general system errors

UNIQUENESS

Category for identity checks, unique constraints etc.

DATATYPE

Category for data type conversion problems as well as parsing issues

CARDINALITY

Category for problems with mandatory fields/elements as well as min/max number of elements (e.g. keywords)

RANGE

Category for min-/max length or value range violations

CONSISTENCY

Category for general consistency checks

SECURITY

Category for any kind of permission/security problems

NOTE

Category for info notes

SUMMARY

Category for summary entries

property

Some form of unique identifier of the field or entity. Might be a combination of field type identifier and entity identifier or, like in this example, the field identifier. In any case it uniquely identifies the repository element

message

A human readable message in the locale of the request

{
"_protocol": {
"infoCounter": 0,
"warningCounter": 0,
"errorCounter": 1,
"entries": [
{
"severity": "ERROR",
"category": "DATATYPE",
"property": "Article.OrderUnit",
"message": "\u0027orderUnit\u0027 (Article.OrderUnit): Code value \u0027NoIdea\u0027 not found in enumeration \u0027Enum.OrderUnits\u0027. Either the code is not part of the enumeration or the user has no read permission"
}
]
}
}

Request Syntax

Create Object

Creates a new object of the given entity. In case the payload contains the corresponding external identifier field, this identifier will be used for the object.
In case no identifier is given, the system will automatically create one for the new object.

If the entity requires a container (e.g. for Items the container is the catalog), the corresponding container field must also be part of the payload or provided as query parameter.

URL Pattern

/object/{entity-identifier}

Method

POST

Content Type
(for the body)

application/json (recommended!) application/xml

Accept
(for the response)

application/json (recommended) application/xml

URL Parameters

{entity-identifier}

Unique identifier of the repository entity

Query Parameter

Name

Datatype

Default

Description

updateIfExists

boolean

false

Based on this parameter an already existing entity item will be updated.
In order for this to work, the identifier and container (if the entity requires one) must be part of the payload.

mimeValueArchive

String

The unique ID of the uploaded mime archive file as returned from the REST File API

container

String

Optional parameter which will set or override the container as it is defined in the JSON payload.
In case of an Item, this would be a ENTITY_ITEM Syntax of a catalog, as the Catalog is the container entity of Item.

This parameter is especially useful in testing scenarios in which the same payload needs to be processed repeatedly for different containers.

Example

/rest/V2.0/object/Article

Return Codes

Code

Reason

200 (Ok)

Entity item has been updated successfully. (only in case the updateIfExists parameter is true and the unique identifier of the object has been provided in the payload)

201 (Created)

Entity Item has been created successfully

400 (Bad Request)

Entity item has not been created/updated successfully
due to at least one validation error. The validation protocol is part of the response

403 (Forbidden)

User has no create permission for this entity

404 (Not Found)

Entity has not been found

429 (Too many Requests)

The number of concurrent write calls is too high. Clients should slow down their requests or use the message queue interface instead (recommended).

Details on thread pool configuration for the Object API can be found here: REST Object API

500

Entity item has not been created/updated due to an unexpected server error.
The server log should be checked.

503 (Service unavailable)

In case the execution has been interrupted or cancelled unexpectedly any currently waiting executions will return server unavailable. This is typically when the server is shutdown forcefully while there are still executions waiting.

Update Object

An existing entity item can be updated with this endpoint.

URL Pattern

/object/{entity-identifier}/{entityItem}

Method

PUT

Content Type
(for the body!)

application/json (recommended) application/xml

Accept
(for the response!)

application/json (recommended) application/xml

URL Parameters

{entity-identifier}

Unique identifier of the repository entity

{entityItem}

The ENTITY_ITEM either in the internalId or externalId syntax. E.g. 'myItem'@'MASTER' or 42@1

Query Parameters

Name

Datatype

Default

Description

createIfMissing

boolean

true

Based on this parameter a missing entity item will be created with the given identifier.
In order for this to work, the externalId must be used for the entityItem parameter. In case the internalId is used and the object is not in the system a 404 code will be returned.

mimeValueArchive

String

The unique ID of the uploaded mime archive file as returned from the REST File API

Example

/rest/V2.0/object/Article/'myItem'@'MASTER'

/rest/V2.0/object/Article/42@1

Return Codes

Code

Reason

200 (Ok)

Entity item has been updated successfully

201 (Created)

Entity item has been created successfully

400 (Bad Request)

Entity item has not been created/updated successfully
due to at least one validation error

403 (Forbidden)

User has no create or edit permission for this entity or object.
Object permission is only checked in case of update

404 (Not Found)

  • Entity has not been found

  • Entity item has not been found.
    Only in case the internalId is used for the entityItem parameter, or the createIfMissing parameter is set to false.

429 (Too many Requests)

The number of concurrent write calls is too high. Clients should slow down their requests or use the message queue interface instead (recommended).

Details on thread pool configuration for the Object API can be found here: REST Object API

500

Entity item has not been created/updated due to an unexpected server error.
The server log should be checked.

503 (Service unavailable)

In case the execution has been interrupted or cancelled unexpectedly any currently waiting executions will return server unavailable. This is typically when the server is shutdown forcefully while there are still executions waiting.

Delete Object

This API is essentially performing the same deletion as the REST List API Delete. In case many items should be deleted, always use the List API. Executing the Object API's delete method for many items is causing more load on the system than executing the REST List API Delete just once because the application can not optimize the database requests.

URL Pattern

/object/{entity-identifier}/{entityItem}

Method

DELETE

Content Type

none

Accept Type

none

URL Parameters

{entity-identifier}

Unique identifier of the repository entity

{entityItem}

The ENTITY_ITEM either in the internalId or externalId syntax. E.g. 'myItem'@'MASTER' or 42@1

Example

/rest/V2.0/object/Article/'myItem'@'MASTER'

/rest/V2.0/object/Article/42@1

Return Codes

Code

Reason

200 (Ok)

Entity item has been deleted successfully

404 (Not Found)

Entity item has not been found

403 (Forbidden)

User has no delete permission for this entity or object

500

Entity item has not been deleted due to an unexpected server error.
The server log should be checked.

Examples

Create an Item in the Master catalog

This call will create a new item in the master catalog with an auto generated identifier. This is the most minimal call to create a new item. It's of course always better to directly provide all data the item should have.

Request
curl --location --request POST 'http://localhost:1512/rest/V2.0/object/Article' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic cmVzdDpoZWlsZXI=' \
--data-raw '{
"catalog": {
"_key": {
"_externalId": "'\''MASTER'\''"
}
}
}'
Response
{
"_entity": "Article",
"_entityItem": {
"_internalId": "5@1",
"_entityId": 1000,
"_externalId": "'Article_1643730037713001'@'MASTER'"
},
"_identifier": "Article_1643730037713001",
"_container": {
"_internalId": "1",
"_entityId": 2900,
"_externalId": "'MASTER'"
},
"_protocol": {
"infoCounter": 0,
"warningCounter": 0,
"errorCounter": 0,
"entries": []
}
}