Overview

The Document service provides:

  • REST interfaces
  • Data CRUD operations
  • URI search
  • Indexes
  • Aggregation

The Document service can store your data in one of the following ways:

  • The Document service can store data as a string, number, or nested data.

    • By default, when your service reads the data, it receives raw data from storage and no conversion is performed.
    • If you want to store or read data in a different way, such as to ensure data localization or store date values, then the service must send additional information about its data schema.
  • The Document service supports using a JSON schema to send your data. You can use a JSON schema to define the data format and document structure.

Let’s say you have a comic book store and you want to sell your comics over the Internet. In that case you need to store your documents in both managed and manageable manner.

To store your documents in a managed and manageable manner:

  • Store the descriptions of your comics.
  • Include the language in which the comic is published.
  • Provide a simple list of comics with basic information.
  • Allow searching comics by custom tags and provide sort options.
  • Display the total number and the average price of comics that meet your customer's search query.

Here are some features of the Document service that can help you achieve the listed goals:

Store documents in organized manner

In the comic book store example, you want your comic book descriptions to be consistent. Each description should include, at minimum, the title, price, and availability of each comic. For this purpose, you need a schema that defines the title, price, and availability fields.

Multiple languages, multiple locations, no problem!

The best way to support comic sales in multiple languages is to use localized attributes. Most likely, a customer looking for comics in French, for example, does not want read comic descriptions in English or Spanish. You could set up your web site so that it allows customers to select their preferred language on your site's home page. To support this functionality with the Document service, set all of the home page display fields in your comics documents to localized. When your French-speaking customer selects French, all localized fields, such as Description, appear in the selected language. For example descriptions - when user chooses different language, you display the description in this language. What if you did not provide the description in the selected language? You can set a fallback, or default, language. For more information, see Operate on Object with Localized Attributes. Now that your site supports multiple languages, you realize that selling products internationally requires you to adjust prices and use different currencies. You can implement a logic that displays comic price in currencies based of the customer’s location, regardless of the language chosen. See the Data for more details about how to set up location-based currencies.

Simple list, complex details view You want your customers to see a simple list of comics that meets their search criteria and displays just a few important fields such as the title, a description preview, the release date, and the price. You also want to reduce the time it takes to display the list. To handle such a query response, explore projections: Perform a Projection. When a customer clicks on a particular position, you can display all available information stored for the comics using a simple GET request on a single document, with no worries about the response time.

Tags and sorting You want to further improve your customers' experience with a search option and support tags for your comics. Using tags and searching by keyword are probably the most convenient forms of searching, particularly when the user does not have a particular position or exact values in mind. You can read about how to use tags here: Tags. As your comic offerings grow in size, you want your customers to be able to sort their search results in the way that suits them best. To explore the sort options, see Search for Object sand Sort Search Result. To make sure your customers can retrieve the comics they want quickly, see Create an Index for Better Search Performance for important details about boosting search performance. Statistics If you want your customers to know how many comics meet their criteria as well as the average price, the Document service provides the capability to get aggregated data. See the Aggregation topic, so you don't have to reinvent the wheel when you set up your comic shop search functionality.


API Reference

/all

/all

get

Returns a list of all tenants for a given client.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_view scope to manage this resource.

/all/statistics

get

Returns a list of all tenants for a given client with usage statistics.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_view scope to manage this resource.

/all/statistics/total

get

Returns a document with detailed usage statistics for a given client.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_view scope to manage this resource.

/{tenant}

Deprecated because of security vulnerability. The tenant string is the project's Identifier from the Builder. type: string

/{tenant}

get

Deprecated because of security vulnerability.

head

Deprecated because of security vulnerability.

delete

Deprecated because of security vulnerability.

/{tenant}/{client}

get

Returns an internal representation of an application. Contains a list of existing types for this client and tenant.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_view scope to manage this resource.

head

Returns the same result as GET method but without body.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_view scope to manage this resource.

delete

Deletes data and indexes for the specified tenant and client.

Security / Access Control:
To access this method, access token issued for client-owner must have hybris.document_admin and hybris.document_manage scopes, or access token issued for tenant must have hybris.document_manage scope to manage this resource.

/{tenant}/{client}/data/{type}

head

Returns the number of objects of this type. The 'q' query parameter enables you to count only objects fulfilling the criteria.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_view scope to manage this resource.

get

Returns all objects of this type which satisfy the criteria from the 'q' query parameter. If the 'q' query parameter is omitted, then the response contains all objects of this type.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_view scope to manage this resource.

post

Creates a new object of this type.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_manage scope to manage this resource.

delete

Deletes data for the specified type.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_manage scope to manage this resource.

put

Bulk update of data which will be matched by a given query. All elements that match the query will be updated by data sent in payload.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_manage scope to manage this resource.

/{tenant}/{client}/data/{type}/{dataId}

get

Returns objects by objectId of this type. If the request does not contain the hybris-metaData header parameter with information about the attribute's localization or type conversions, then the response contains raw data. Cannot contain the following characters: /\ \"*<>|?

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_view scope to manage this resource.

head

Returns the same result as GET method but without body.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_view scope to manage this resource.

post

Creates a new object of this type with a given objectId. If the request does not contain a hybris-metaData header parameter containing information about the attribute's localization, then the data is stored as raw data.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_manage scope to manage this resource.

put

Updates the object for objectId and type. If you want to update partially, use patch query parameter instead of partial, because it is deprecated.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_manage scope to manage this resource.

delete

Deletes objects for objectId and type.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_manage scope to manage this resource.

/{tenant}/{client}/data/{type}/{dataId}/{attributeName}

post

Creates an element in the array. The attribute identified by name must be an array.

Security / Access Control:
To access this method, access token must be issued forclient and have hybris.document_manage scope to manage this resource.

delete

Removes the given attribute from the document.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_manage scope to manage this resource.

/{tenant}/{client}/data/{type}/{dataId}/{attributeName}/{index}

get

Gets the element at this index from the array.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_view scope to manage this resource.

head

Returns the same result as GET method but without body.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_view scope to manage this resource.

put

Updates the element at this index in the array.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_manage scope to manage this resource.

delete

Deletes the element at this index from the array.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_manage scope to manage this resource.

/{tenant}/{client}/aggr

/{tenant}/{client}/aggr/{type}

head

Returns the count of objects of this type. Additionally, objects can be filtered by a query.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_view scope to manage this resource.

get

Returns the result of aggregations for objects of this type. At least one of sum or avg query parameters is required. Additionally, the q parameter can be used to restrict the number of input objects.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_view scope to manage this resource.

/{tenant}/{client}/indexes

/{tenant}/{client}/indexes/{type}

get

Returns all indexes created for a collection.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_view scope to manage this resource.

head

Returns the same result as GET method but without body.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_view scope to manage this resource.

post

Creates a new index.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_manage scope to manage this resource.

delete

Deletes all indexes for this type.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_manage scope to manage this resource.

/{tenant}/{client}/indexes/{type}/{name}

get

Returns the index identified by the given name.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_view scope to manage this resource.

head

Returns the same result as GET method but without body.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_view scope to manage this resource.

delete

Deletes an index by the given name.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_manage scope to manage this resource.

/{tenant}/{client}/tags

/{tenant}/{client}/tags/{type}

post

Add a value to the tag for all documents of the given type and supplied restrictions (q param).

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_manage scope to manage this resource.

delete

Delete the value from the tag for all documents of the given type and supplied restrictions (q param).

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_manage scope to manage this resource.

/{tenant}/{client}/tags/{type}/{id}/{tagName}

post

Append several values to an array at once. Values are added only if they are not already in the array.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_manage scope to manage this resource.

delete

Removes values from the tags array.

Security / Access Control:
To access this method, access token must be issued for client and have hybris.document_manage scope to manage this resource.


Considerations

This section details the best practices to follow when using the Document service.

Use the Client Credentials token grant

The Document service requires a token obtained with the Client Credentials flow. This provides an additional level of security so that users who belong to a project but do not have Client Credentials cannot manipulate resources within the project. For more information about obtaining an access token and grants, see the OAuth2 service documentation.

Use data modeling characteristics for NoSQL storage

The Document service does not provide:

  • Transactions spanned over more than one request
  • Joins between objects
  • Constraints typical for relational databases
  • Data validation against used schema

These properties should be taken into consideration when designing the data model.

For more information about how to model your domain, see the MongoDB documentation. Some of the main concepts are:

  • Data duplication and denormalization
  • Embedding data (aggregated views)

Limit of simultaneously created indexes

Always try to plan your indexes in advance, to support your most time-critical queries from the outset. The Document service has a limit of five indexes, created simultaneously by a given client, and up to 20 indexes created at the same time per storage. You can minimize the risk of exceeding those limits by creating the index first. For small amounts of data the index creation process is short and don't block the index creation pool for long. If your request for index creation exceeds any of these limits, the service returns the 429 Too many requests response from the Document service. In that case you need to resend the request.

Restricted characters

When specifying your document, as in this example:

    {
    "key1": "value1",
    "key2": "value2"
    }

remember that you cannot use $, . nor null characters as field names (keys), as those are restricted by MongoDB.

To learn about alternate approach, please refer to the MongoDB documentation, Dollar sign escaping.
Remember that the name of the schema field at the root level should be $schema, because there is logic, implemented in the service, that transforms it. However, at the subdocument level, the name of the schema field must not include $.

Remove data but leave indexes

You can remove all data for a specified type while leaving all indexes unchanged. To do this, use a DELETE method on the /{tenant}/{client}/data/{type} resource and set the query parameter drop to false.

In terms of read and write operations, the Document service's behavior is characterized as eventual consistency. You can find out more in the MongoDB documentation.

Use paging and limiting

The Document service uses paging by default, even if a request does not specify it. To support paging, the Document service uses a Links HTTP header to provide links to the:

  • Current page: rel=self
  • Previous page: rel=prev(not present if the current page is the first page)
  • Next page: rel=next (not present if the current page is the last page)

You can use the:

  • pageSize parameter to specify how many results to return on one page. The default page size is 16.
  • pageNumber parameter to point to a specific page of the returned results.
  • sort parameter to sort your results to avoid situations in which one document is displayed on multiple pages or the document order changes when navigating from one page another.

This is an example request:

curl -G -i -H "Authorization: Bearer 081-3f1219c6-35wf-4863-87b6-5fccf07e09ba" https://api.beta.yaas.io/hybris/document/v1/mycomicsshop/myorg.stock/data/comic?q=name:"Thorgal"+price:(>=10+AND+<=20)
+createdAt:>=2014-04-18&sort=createdAt:asc&pageNumber=2
When creating queries, consider limiting the number of returned documents. This helps to prevent a timeout as a result of too many objects being returned.

Check the returned collection when searching to determine the number of returned objects

If you perform a GET request on a type's collection and the collection is empty, it does not return a status code of 404. Instead, it returns an empty list with a status code of 200.

Use the HEAD method if you only need the total number of queried objects

Perform a call on the {tenant}/{client}/data/{type} resource using the HEAD method with your specific query. The response includes a header with the total number of objects. For more information, see Search for objects and sort search results.

Limit the length of your query

Queries which are too long result in a 400 response from the service, with the following body:

{
  "status": 400,
  "message": "Request URI too long. Please minimize your query.",
  "details": []
}

The query sends in the HATEOAS header. If it is too long, causing the total size of all headers to exceed 8 KB, the request fails. If the request fails for that reason, reduce the length of your query string and resend the request. For example, when you use the query to return multiple documents, you can use generic parameters instead of listing individual parameters such as IDs.


Security

The Document service is a container for your Documents. You control the data stored in the Document service, and only you know whether the document contains personal data and which data subject the data relates to. Therefore, to meet the data privacy requirements you must map documents containing personal data with corresponding data subjects, and implement a logic to serve data subject's requests related to its personal data, such as requests for information or deletion. To meet these goals, follow instructions provided in the Developer Guidelines for Data Privacy.


Multi tenancy

Core services provide you with multi multi-tenant model, which allows you to manage all your tenants' data in easy and convenient way. Your service is the client of core services, and it may contain as many tenants as you need. Without multi-tenancy, you would have to separate your tenants' data manually. In a multi multi-tenant model, you delegate tenant data separation to core services.

The Document service is a good example of a multi multi-tenant core service as it separates the data for services (clients) and within services for their tenants.

Example:

The Product and the Email services serve multiple tenants to store their documents and media files. Both the Product and the Email service are, in this case, clients of the Document and Media services. The diagram below illustrates those dependencies:

The Document service enables you to manage your service's tenants with a single access token issued for your service. Your service client is the owner of the data, and you don't have to issue new tokens with different hybris.tenant scopes. All you need to do is use your tenant identifier as the tenant in Document service path. In the following diagram, two tenants (A and B) call your service. Your service only has to get token once. The same token can then be used for all subsequent requests until the token the expires.


Schema

The Document service supports the use of JSON schemas. You can use a JSON schema to define a data format and the structure of the documents sent to the Document service. There can be different, separate schemas for each document. One advantage of using a schema is that you do not have to send data structure information in headers with every request as the schema allows you to store fields' values as a particular data type.

Do not rely on the #/definitions reference to nested schemas in your documents' schemas, as it is not supported by the Document service. This restriction still allows you to save documents with nested schemas using a definitions reference, but they will not work.

The Document service supports the following attributes:

  • date - "type": "date"
  • id - {"$ref": "https://pattern.yaas.io/v1/schema-id.json"} - Download sample
  • createdAt - {"$ref": "https://pattern.yaas.io/v1/schema-createdAt.json"} - Download sample
  • modifiedAt - {"$ref": "https://pattern.yaas.io/v1/schema-modifiedAt.json"} - Download sample
  • localized - {"$ref": "https://pattern.yaas.io/v1/schema-localized.json"} - Download sample
  • amount - {"$ref": "https://pattern.yaas.io/v1/schema-amount.json"} - Download sample
For more information about how to create a JSON schema, see the JSON schema website at http://json-schema.org. All abovementioned schemas are also available under old location api.yaas.io/patterns but as per this blog post you should use the new one.

SAP Hybris recommends that you store your schemas in the Schema service. If you choose to publish your schema on your own server instead, it must be accessible without authentication. To define a schema for your document, add the URI to the schema in the metadata attribute in the request body. For example:

{
    "metadata"   : {
            "schema": "http://myserver.com/comicstore/comicSchema_v1.json"
    }
}
The data you send to the Document service is not validated against the schema.


Mixins

A mixin is a simple schema. It is defined by users of the Document service and contains additional attributes for a document. A collection of documents with schemas and mixins can be used to place additional attributes without making changes in the schema. The document, such as a product can have multiple mixins describing various attributes.

Mixins are optional, but they are a good way to keep the structure of the documents organized.

SAP Hybris recommends that you store your schemas in the Schema repository.

The schema has priority over mixins when defining attributes. For example, if you define an attribute as a date in the schema and as localized in the mixin, the schema takes precedence, so the attribute is created as a date.

For more information about mixins in the Document service, see Operate on Mixins.


Data

Metadata

Storing and reading tips for the Document service are sent using a parameter in the header called hybris-metaData. This parameter contains information about the attribute's localization or date type. The hybris-metaData value structure is similar to this example:

attribute_name1:tip1;...;attribute_nameN:tipN
  • The attribute_nameX field is the name of the attribute sent using JSON. If the attribute is nested, the name contains a nested path where each level is separated with a period (.).
  • tipX is a tip about the data interpretation of field by Document service. It supports these tips:
    • localized - Tip for localized data.
    • date - Tip for date data.
    • amount - Tip for localized currencies and prices.
    • id - Tip for the document ID alias. For more information about how to use the hybris-metaData header for the ID alias, see Use alias on ID field when creating and searching.

Get the usage statistics for a client

The Document service allows you to get the usage statistics for a client.

Use one single access token issued for the team to perform all operations described in this section. With this token, perform requests in the context of different tenants within the token validation time.

List all tenants for a client

Send a GET request to the /all endpoint to list all tenants for a given client:

curl -H "Authorization: Bearer {ACCESS_TOKEN}" https://api.beta.yaas.io/hybris/document/v1/all

The successful response returns a 200 status code. An example JSON content in the response body looks similar to the following:

[
  "firstTenant",
  "secondTenant",
  ...
]

List all tenants for a given client with the usage statistics

Send a GET request to the /all/statistics endpoint to list all tenants for a given client with the usage statistics:

curl -H "Authorization: Bearer {ACCESS_TOKEN}" https://api.beta.yaas.io/hybris/document/v1/all/statistics

The successful response returns a 200 status code. An example JSON content in the response body looks similar to the following:

[
  {
    "timestamp": "2016-11-23T09:54:04.798+0000",
    "client": "hybris.product",
    "tenant": "firstTenant",
    "typeCount": 4
  },
  {
    "timestamp": "2016-11-23T09:54:04.798+0000",
    "client": "hybris.product",
    "tenant": "secondTenant",
    "typeCount": 6
  },
  ...
]

Note that in addition to the fields tenant and client, each document in the array contains the following fields:

  • timestamp - This is the timestamp when the report is generated.
  • typeCount - This is the number of types for the given tenant.
The service asynchronously generates the response to the GET request to the /all/statistics. This is refreshed every hour.

Get the usage statistics for a client

Send a GET request to the /all/statistics/total endpoint to acquire the usage statistics for a client:

curl -H "Authorization: Bearer {ACCESS_TOKEN}" https://api.beta.yaas.io/hybris/document/v1/all/statistics/total

The successful response returns a 200 status code. An example JSON content in the response body looks similar to the following:

{
  "timestamp": "2016-11-23T09:54:04.798+0000",
  "client": "hybris.product",
  "tenantCount": 253,
  "typeCount": 276,
  "indexCount": 278,
  "dataSizeBytes": 4445309608
}

The response contains the following fields:

  • timestamp - This is the timestamp when the report is generated.
  • client - This is the client for which this report is generated.
  • tenantCount - This is the number of tenants for the given client.
  • typeCount - This is the number of types for the given client. It's a sum of all types for all tenants.
  • indexCount - This is the overall number of indices for the given client. It's a sum of all indices for all tenants.
  • dataSizeBytes - This is the overall data size in bytes, including types and indices.
The service asynchronously generates the response to the GET request to the /all/statistics/total. This is refreshed every hour.

Create objects

You can create data objects using the /{tenant}/{client}/data/{type} endpoint by providing a proper application/json body. If your request does not include the hybris-metaData header parameter containing information about attribute localization, then the data is stored as raw data.

  • If a request includes the hybris-metaData header parameter containing information about an attribute's localization and the Content-Language header parameter is NOT set, then you need to provide a language map in the body of the request.
  • If a request includes the hybris-metaData header parameter containing information about an attribute's localization and the Content-Language is set, then the data is stored for the given language.
  • Use either the Content-Language header or a language map in the body of the request. Do not use both.
  • If a request includes the hybris-metaData header parameter containing information about an ID alias and an attribute with this name is in the request, then this attribute is interpreted as an ID in the database.

This is an example of a POST request without a hybris-metaData header:

curl -i -H "Authorization: Bearer 081-3f1219c6-35wf-4863-87b6-5fccf07e09ba" -H "Content-type: application/json" -X POST -d '{"kind":"History","name":"Thorgal"}' https://api.beta.yaas.io/hybris/document/v1/mycomicsshop/myorg.stock/data/comic

Store documents as a raw data

The Document service supports storing documents as a raw data. To use this functionality perform a POST request on the /{tenant}/{client}/data/{type} endpoint with rawwrite query parameter set to true. The body of your request must contain at least default metadata attributes, which are id, createdAt, modifiedAt, and version fields. Lack of those attributes results in 400 Bad Request response. The body is inserted to the database in the exact form you sent it with your request.

If the document with the same id attribute already exists, the document is fully replaced.

Please note that you cannot set both the rawwrite and patch query parameters to true, that results in 400 Bad Request.

Send and retrieve compressed data

When working with big data sets, you can send and receive encoded data to reduce response times and bandwidth usage. The Document service supports the GZIP format for content encoding. To send compressed data to the Document service, set the Content-Encoding header with the gzip value. To retrieve your data in the GZIP format, use the Accept-Encoding header with the gzip value. It is recommended that you use data encoding every time you send a large amount of data in the body of your request, as well as when you expect to receive a large data set in the response from the service.

Create objects with a specific ID

You can create data objects using the /{tenant}/{client}/data/{type}/{dataId} resource.

All the rules specified in the Create objects section apply when creating objects with a specific ID.

This is an example of a POST request with a specific dataId:

curl -i -H "Authorization: Bearer 081-3f1219c6-35wf-4863-87b6-5fccf07e09ba" -H "Content-type: application/json" -X POST -d '{"kind":"History","name":"Thorgal"}' https://api.beta.yaas.io/hybris/document/v1/mycomicsshop/myorg.stock/data/comic/1401

Do not check if the ID already exists before creating a new object

In this case, create an object with the ID you want it to have. If the ID already exists, an error is generated. For more information, see Perform simple CRUD operations.

Retrieve objects

You can retrieve specific objects using the /{tenant}/{client}/data/{type}/{dataId} resource to point to exactly one data object to be returned.

  • If a request does not include a hybris-metaData header parameter containing information about an attribute's localization or type conversions, then the response contains raw data.
  • If a request includes a hybris-metaData header parameter containing information about an attribute's localization and the hybris-languages header parameter value is *, then the response contains data for all existing languages.
  • If a request includes a hybris-metaData header parameter containing information about an attribute's localization and Accept-Language is set, then the response contains data for the chosen language (with the given fallback).
  • The value of the Accept-language parameter is case sensitive and should be exactly the same as Content-language parameter used to save localized attribute. For an example, you cannot search for attribute saved with Content-language EN by setting Accept-language parameter to en. Those are two different fields.
  • If a request includes a hybris-metaData header parameter containing information about an ID alias, then the response contains an ID aliased by the defined name.
  • If a request includes a hybris-metaData header parameter containing information about an ID alias with the same name as an attribute in the response, then the attribute in the response is overwritten by the ID.

The body of the response is a JSON object that contains all information for this specific object. For example:

{
    "name": "Thorgal",
    "metadata": {
        "createdAt": "2014-07-25T09:01:51.145+0000",
        "modifiedAt": "2014-07-25T09:01:51.145+0000",
        "version": 1
    },
    "id": "53510b33f12ec86ab0bd0c90",
    "title": "The Brand of the Exiles",
    "kind": "History"
}

You can also retrieve a list of objects using the /{tenant}/{client}/data/{type} resource by providing query parameters for q.

  • If the q query parameter is omitted, then the response contains all objects of this type.
  • If the totalCount query parameter is set to true, then the response contains the hybris-Count header with the total number of objects of this type.

This is a sample request:

curl -G -i 'https://api.beta.yaas.io/hybris/document/v1/mycomicsshop/myorg.stock/data/comic/?q=rarity:uncommon'

The body of the response is an array of JSON objects matching the query parameters:

[
    {
        "cover": "hardcover",
        "metadata": {
            "createdAt": "2014-07-25T09:14:14.481+0000",
            "modifiedAt": "2014-07-25T09:18:37.955+0000",
            "version": 2
        },
        "price": 15.99,
        "name": "Thorgal",
        "id": "53d21fe66b8e4c58a577c509",
        "title": "The Three Elders of Aran",
        "rarity": "uncommon"
    },
    {
        "cover": "paperback",
        "condition": "good",
        "metadata": {
            "createdAt": "2014-07-25T09:15:05.035+0000",
            "modifiedAt": "2014-07-25T09:18:37.955+0000",
            "version": 2
        },
        "price": 15.99,
        "name": "Thorgal",
        "id": "53d220196b8e4c58a577c50b",
        "title": "The Guardian of the Keys",
        "rarity": "uncommon"
    }
]
Update Objects

You can update an existing object with new information using the /{tenant}/{client}/data/{type}/{dataId} resource by providing the dataId.

  • If a request does not include a hybris-metaData header parameter with information about an attribute's localization, then the data is stored as raw data.
  • If a request includes a hybris-metaData header parameter containing information about an attribute's localization and the Content-Language header parameter value is not set, then the body of the request must contain a language map.
  • If a request includes a hybris-metaData header parameter containing information about an attribute's localization and the Content-Language is set, then the data is stored for a given language.
  • Use either the Content-Language header or a language map in the body of the request. Do not use both.
  • If a URL includes the upsert=true parameter, then the object is created when updating non-existing objects.
  • If a URL includes the upsert=false parameter, then a status code of 404 is returned in the response when updating non-existing objects.
  • If the patch parameter is set to true, a partial update is performed. Otherwise, a call results in a full object replacement.

This is an example of a PUT request:

curl -i -H "Authorization: Bearer 081-3f1219c6-35wf-4863-87b6-5fccf07e09ba" -H "Content-type: application/json" -X PUT -d '{"title": "Child of the Stars"}' 'https://api.beta.yaas.io/hybris/document/v1/mycomicsshop/myorg.stock/data/comic/53510b33f12ec86ab0bd0c90?patch=true'

You can also update many objects with a single request using the /{tenant}/{client}/data/{type} endpoint by providing query parameters for q. All elements matching the query are updated with the data sent in the payload.

This is an example of a PUT request that updates numerous objects:

curl -i -H "Authorization: Bearer 081-3f1219c6-35wf-4863-87b6-5fccf07e09ba" -H "Content-type: application/json" -X PUT -d '{"price": 18.99}' 'https://api.beta.yaas.io/hybris/document/v1/mycomicsshop/myorg.stock/data/comic/?q=rarity:uncommon'

In both cases, the response contains information about the status of the update:

{
   "code": "200",
   "status": "200",
   "message": "Operation succeeded"
}

Use versioning (optimistic locking)

Use the optimistic locking feature provided by the Document service if your use case requires protection from parallel data modification, working with out-of-date data. For more information, see Perform versioning with optimistic locking.

When you update a document using a PUT method on the /{tenant}/{client}/data/{type}/{dataId} resource, you can use a non-existing dataId. This operation generates these results:
  • If the URL contains the upsert=true parameter, then the new document with the given dataId is created.
  • If the URL contains the upsert=false parameter or this parameter is not given, then a status code of 404 is returned.

Attributes

You can add and remove additional attributes for objects using the /{tenant}/{client}/data/{type}/{dataId}/{attributeName} endpoint and providing the application/json body of the request that contains the attribute's values.

For example:

curl -i -H "Authorization: Bearer 081-3f1219c6-35wf-4863-87b6-5fccf07e09ba" -H "Content-type: application/json" -X POST -d '{"condition" : "mint"}' 'https://api.beta.yaas.io/hybris/document/v1/mycomicsshop/myorg.stock/data/comic/c001/condition'

Delete objects

There are several ways to delete objects.

  • You can delete specific objects using the /{tenant}/{client}/data/{type}/{dataId} resource by providing the dataId. This enables you to point to exactly one object to be deleted.
  • You can delete all objects for a specific type using the /{tenant}/{client}/data/{type} resource. The delete operation can be narrowed by adding a query parameter for q. This enables you to delete all objects matching the query.
  • You can delete service data for a given tenant using the /{tenant}/{client}/ resource. A separate hybris.document_admin scope is required to access this method and the token has to be acquired for the client-owner (team).

This is an example of a DELETE request:

curl -i -H "Authorization: Bearer 081-3f1219c6-35wf-4863-87b6-5fccf07e09ba" -X DELETE https://api.beta.yaas.io/hybris/document/v1/mycomicsshop/myorg.stock/data/comic/53510b33f12ec86ab0bd0c90

Audit fields

Each object created in the Document service receives createdAt and modifiedAt fields by default. These fields contain information about when an object was created and when it was last modified.

For more information about using audit fields, see Use Aliases on Audit Fields.


Aggregation

The Document service offers sum and avg aggregates for numeric data stored inside documents and count to get the number of documents. You can also limit the number of documents used to calculate the aggregates by entering a query using the q parameter.

Some examples of use cases for this feature are:

  • The number of products (filtered by manufacturer, color, and size)
  • The average price of a product (filtered by category and manufacturer)
  • The sum of products available in multiple warehouses

Retrieve aggregated data

To get aggregated data, use the /{tenant}/{client}/aggr/{type} resource.

The avg and sum parameters point to specific attributes of documents. You can use multiple attributes separated by commas for each aggregate. The count parameter takes a Boolean value. If set to true a number of documents will be included in a response.

Nested attributes

You can specify nested attributes providing the full path to the attribute where every level is separated by a dot. Because the dot is generally not allowed as a name of an attribute, it will be replaced with underscores in a response. For example, the value for spec.size.width will be returned as spec_size_width.

For example of an aggregation usage, see Get aggregated data.

For performance reasons, it is recommended to use Document service aggregates rather then getting all objects and count it on the client side.


Tags

The Document service enables you to add and remove tags for specific documents or a set of documents narrowed by a query. You can create tag arrays with different names and add them to existing objects.

Create tags for a specific document

To create tags for a specific document, use the /{tenant}/{client}/tags/{type}/{id}/{tagName} endpoint, where the id is a document ID (dataId), and tagName is the name of the tag array. Tag values must be provided using a tags parameter.

The POST request looks similar to this example:

curl -i -H "Authorization: Bearer 081-3f1219c6-35wf-4863-87b6-5fccf07e09ba" -X POST 'https://api.beta.yaas.io/hybris/document/v1/mycomicsshop/myorg.stock/tags/comic/c001/comicTags?tags=comic,paper'

Create tags for multiple documents

You can also add tags for multiple documents matching a query using the /{tenant}/{client}/tags/{type} resource by providing query parameters for q and the tag array name, followed by the tags in tags.

The POST request for this bulk operation looks similar to this example:

curl -i -H "Authorization: Bearer 081-3f1219c6-35wf-4863-87b6-5fccf07e09ba" -X POST 'https://api.beta.yaas.io/hybris/document/v1/mycomicsshop/myorg.stock/tags/comic?q=name:"Thorgal"&tags=genre:fantasy,adventure'

In both cases, the response is:

 {
     "code": "200",
     "status": "200",
     "message": "Operation succeeded"
 }

Search documents using tags

To search documents using tag values, use the /{tenant}/{client}/data/{type} resource with query in the following form:

?q=tagAttribute1:all(value1,value2)+tagAttribute2:in(value1,value2)

The query is built according to the following rules:

  • The tagAttribute is a name of an array of tags. It reflects the {tagName} in the /{tenant}/{client}/tags/{type}/{id}/{tagName} resource.
  • Values in parentheses are comma-separated tag values.
  • The in criterion enables you to search documents in which the tag attribute contains any of the values in parentheses.
  • The all criterion enables you to search documents in which the tag attribute contains all of the values in parentheses.
  • The plus sign (+) character is used because of URL encoding rules and takes the place of a space character that separates query conditions.

The GET request with query on tags looks similar to this example:

curl -I -H "Authorization: Bearer 081-3f1219c6-35wf-4863-87b6-5fccf07e09ba" -X GET 'https://api.beta.yaas.io/hybris/document/v1/mycomicsshop/myorg.stock/data/comic?q=ComicTags:all(hardcover,reprint)'

Remove a specific tag array for a specific document

To remove tags from an array for a specific object, you can use the /{tenant}/{client}/tags/{type}/{id}/{tagName} resource, where id is a document ID (dataId) and tagName is the name of tag array. The tag values to be removed must be provided using a tags parameter.

The DELETE request looks similar to this example:

curl -i -H "Authorization: Bearer 081-3f1219c6-35wf-4863-87b6-5fccf07e09ba" -X DELETE 'https://api.beta.yaas.io/hybris/document/v1/mycomicsshop/myorg.stock/tags/comic/c001/comicTags?tags=comic,paper'

Remove tag values from tag arrays for multiple documents

To remove tags from an array for multiple documents, use the /{tenant}/{client}/tags/{type} resource and provide query parameters for q. The tag array name is followed by tags in tags.

The DELETE request looks similar to this example:

curl -i -H "Authorization: Bearer 081-3f1219c6-35wf-4863-87b6-5fccf07e09ba" -X DELETE 'https://api.beta.yaas.io/hybris/document/v1/mycomicsshop/myorg.stock/tags/comic?q=name:"Thorgal"&removeEmpty=false&tags=genre:fantasy,adventure'
DELETE contains an additional query parameter called removeEmpty. If this is set to false, the array of tags is not removed when all tags are deleted. The array remains empty. If removeEmpty parameter is set to true, the array is removed when last tag is deleted from it.


Indexes

The Document service allows you to create indexes to significantly improve the search performance. For all time-critical queries, you should create thought indexes. Without appropriate indexes, a query scans all documents in a collection. When creating indexes, you should take into account a few considerations. This section will guide you through how to use indexes properly.

Start with queries

Understand how you want to search for your documents. Which attributes do you query? Do you plan to use sorting or projection? Based on this information, you can create a proper index for all of your queries. For example, to search by the country parameter, create an index that supports this case. If another query uses a different parameter or parameters, create an additional index to cover this case, too.

Do not create an index for the id field. All collections implicitly create this unique index.
The system creates indexes in the background. This process can take a long time for large collections. You cannot use the index until the system completes the creation process.
You cannot use alias names when creating an index.

Create an index

You must create indexes for specific types. To create an index, use the /{tenant}/{client}/indexes/{type} resource by providing the application/json body of the request with the details of your index.

A definition of an index consists of two parts: keys (required), where you declare the fields to index, and options (optional), which contains additional configurations.

The limits of simultaneously created indexes apply: - You can create at most five indexes per client at the same time. - You can run 20 index creation processes per storage at the same time. If your request exceeds either of the limits, the service returns a 429 Too many requests response. You must wait for the ongoing index creation to finish and resend your request.
{
    "keys" : { ... },
    "options" : { ... }
}

To create an index on audit field, such as createdAt or modifiedAt, use a full field name with a metadata prefix. Use a dot (.) for separation, as shown in the example:

{
  "keys" : {
    "metadata.createdAt" : 1
    }
}

Keys

The keys subdocument consists of attribute-value pairs, where the attribute is the index key and the value defines the type of the index. The Document service supports two types: 1 for ascending indexes, and -1 for descending indexes.

{
   "keys" : { "country" : 1, "city" : -1 }
}

As you can see, you can define more than one key. This creates a compound index, which supports queries on multiple attributes.

Options

The options subdocument allows you to provide additional configuration options for your index.

Options for all index types

Available options are:

Options field nameDescription
nameAllows you to assign a customized name to your index.
uniqueEnforces the uniqueness of indexed fields
sparseReferences only those documents that contain an indexed field
Option field name

Use the name option to provide your own name for your index.

{
   "keys" : { "country" : 1, "city" : -1 },
   "options" : {
       "name" : "CountryAndCityIndex"
   }
}

If you don't specify the name of an index, the Document service generates a random name and you will receive the name in a response.

{
    "name": "a2X1"
}
We recommend that you explicitly name indexes. The name of an index is returned in case of a unique index violation.
Option field unique

The unique option allows you to create unique indexes that enforce the uniqueness of indexed fields.

{
   "keys" : { "country" : 1, "city" : -1 },
   "options" : {
       "name" : "CountryAndCityIndex",
       "unique" : true
   }
}
When the document does not contain a value for the field in the unique index, the index stores a null value for this document. To meet the unique constraint, the Document service allows only one document without an indexed field. If there is more than one document without a value for the indexed field or without the whole indexed field, the service returns response 409 with the following message: Could not create unique index. Index contains fields with duplicated values.. To avoid this restriction applying to non-existent fields, create a unique index with a sparse option.
Option field sparse

A sparse index contains entries only for documents that include the indexed field. Documents without the indexed field are skipped.

In some cases, it is useful to combine the unique and sparse options to reject duplicate values while ignoring documents that do not have the indexed field.

{
   "keys" : { "country" : 1, "city" : -1 },
   "options" : {
       "name" : "CountryAndCityIndex",
       "sparse" : true
   }
}
Options for text indexes
Options field nameDescription
text index default languageSets the default language for stop words and for rules used by the tokenizer and stemmer
text index weightsSets the impact of the field in relation to other indexed fields

You can find the additional description of options for text search indexes in the Full Text Search.

Option field default language

The default language for text indexes is English. You can set a different language as the default by including it in the options field for simple tokenization without stemming and stop words.

{
    "keys" : { "title": "text", "description" : "text" },
    "options": {
        "default_language" : "none"
    }
}
The default language options field works only with the text index.

You can view a list of supported languages here.

Option field weights

You can set the weights for indexed fields under the options subdocument:

{
    "keys": { "title": "text", "description" : "text" },
    "options": {
        "weights" : { "title" : 10, "description" : 2
       }}
    }
The weights options field works only with the text index.

The preceding example indicates that when searching by the text index, the match for the title field has five times stronger impact than the match for the description field. You can combine an option to set the weights values for your fields with a scoreField query parameter to support your queries and provide the most relevant search results in your solution.

Compound index

A compound index is an index created for more than one field. Such an index supports queries that use multiple attributes.

To search by the two attributes, q=country:"Poland" age:>30, you would create a compound index as shown:

{
   "keys" : { "country" : 1, "age" : 1 },
   "options" : {
       "name" : "CountryAndAgeIndex"
   }
}

Compound indexes can support different queries. The index prefix concept presented in the MongoDB documentation can help you to better understand how it works. It states:

"Index prefixes are the beginning subsets of indexed fields."

For example, this sample compound index:

{
   "keys" : { "country" : 1, "city" : 1, "age" : 1 }
}

has the following index prefixes:

  • { country : 1 }
  • { country : 1, city : 1 }

You can use a compound index to support queries on the index prefixes. It means that Document service can use this index for queries on the following fields:

  • country
  • country and city
  • country and city and age

It's important to understand this concept to avoid creating too many indexes. In the preceding example, we can have one index to support three types of queries instead of three separate indexes. The latter method is much more expensive, as each index consumes memory.

Sorting

Indexes support sorting. Sort operations backed by an index are usually faster.

For a single field index, you can sort the results in both ascending and descending order. For example, the index:

{
   "keys" : { "country" : 1 }
}

allows sorting in both directions:

  • sort=country:asc
  • sort=country:desc

For a compound index, you can sort by all the keys of the index or by a subset, but the keys must be listed in the same order as they appear in the index. For example, the compound index:

{
   "keys" : { "country" : 1, "city" : 1 }
}

supports these sort methods:

  • sort=country:asc
  • sort=country:asc,city:asc

The sort order must be the same as in the index definition for all attributes, or reversed for all attributes. The preceding example index supports the sort=country:desc,city:desc query but does not support the query sort=country:desc,city:asc.

View indexes

To retrieve a complete list of indexes for a specific type, you can use the /{tenant}/{client}/indexes/{type} resource. The list of indexes for the specified type is included in the response.

Remove indexes

You can use the DELETE method to delete indexes in two ways:

  • Delete a specific index using the /{tenant}/{client}/indexes/{type}/{name} resource.
  • Delete all indexes of a specific type using the /{tenant}/{client}/indexes/{type} resource.

Best practices

To make the most of indexing, follow these best practices:

  • Create appropriate indexes for all of your time-critical queries.

  • Do not create an index for the id field. It already exists.

  • Use compound indexes to support multiple queries. Compound indexes can be used by many different queries so you don't need to have a separate index for each one. This is very important as every index consumes memory and too many indexes can lead to worse performance.

  • Don't create too many indexes. All write operations must update every index created for a given type. This decreases the performance of write operations.

  • Use indexes that narrow down the results of your query. For example, if all of your documents include the active field with a value of true, then this field is not a good candidate for indexing.



Full text search

The Document service supports full text search, which means you can search for text in string fields in documents.

The Document service full text search feature supports:

  • case-sensitive and case-insensitive search
  • diacritic-sensitive and diacritic-insensitive searches to recognize or ignore text with accent marks
  • searching in a specified language
  • applying weights to text fields
  • scoring search results

Assumption

This topic describes how to use full text search in the Document service based on the following example data.

[
    {
          "title" : "Functional programming in Scala",
          "description" : "This is book about functional programming using Scala language",
          "price" : 10,
          "metadata" : {
            "createdAt" : "2016-12-07T14:04:03.637+0000",
            "modifiedAt" : "2016-12-07T14:04:03.637+0000",
            "version" : 1
          },
          "id" : "584816d34131211355867871"
    },
    {
          "title" : "Functional programming in JavaScript",
          "description" : "This is book about functional programming using JavaScript",
          "price" : 5,
          "metadata" : {
            "createdAt" : "2016-12-07T14:04:21.358+0000",
            "modifiedAt" : "2016-12-07T14:04:21.358+0000",
            "version" : 1
          },
          "id" : "584816e54131211355867872"
    },
    {
          "title" : "Cooking for fun",
          "description" : "Book about cooking",
          "price" : 15,
          "metadata" : {
            "createdAt" : "2016-12-07T14:05:05.620+0000",
            "modifiedAt" : "2016-12-07T14:05:05.620+0000",
            "version" : 1
          },
          "id" : "584817114131211355867873"
    },
    {
          "title" : "Fishing",
          "description" : "Fishing for masters",
          "price" : 20,
          "metadata" : {
            "createdAt" : "2016-12-07T14:10:02.447+0000",
            "modifiedAt" : "2016-12-07T14:10:02.447+0000",
            "version" : 1
          },
          "id" : "5848183a4131211355867874"
    }
]

Create a text index

Before using text search, create a text index. To create an index, send the application/json body of the request with the details of your index to the /{tenant}/{client}/indexes/{type} resource.

The definition of a text index consists of two parts:

  • keys (required), where you declare the fields to index
  • options (optional) where you define an additional configuration, such as name or default_language
{
    "keys"   : {
        "title": "text",
        "description" : "text"
    },
    "options": {
        "name"  : "myTextIndex"
    }
}
The service supports only one text index per collection.

Example:

curl -i -H "Authorization: Bearer 081-3f1219c6-35wf-4863-87b6-5fccf07e09ba" -H "Content-type: application/json" -X
POST -d '{"keys":{"title": "text","description" : "text"},"options": {"name":"myTextIndex"}}}' https://api.beta.yaas.io/hybris/document/v1/mycomicsshop/myorg.stock/indexes/books

This call creates a text index on 2 fields, title and description.

When you perform a GET request to check the text index details:

curl -X GET -H "Authorization: Bearer 081-3f1219c6-35wf-4863-87b6-5fccf07e09ba" "https://api.beta.yaas.io/hybris/document/v1/mycomicsshop/framefrog.mycomicsshop/indexes/comic"

The response looks similar to the example shown:

[
  {
    "keys": {
      "_id": 1
    },
    "options": {
      "name": "_id_"
    }
  },
  {
    "keys": {
      "$text": true
    },
    "options": {
      "name": "myTextIndex",
      "default_language": "english",
      "weights": {
        "description": 1,
        "title": 1
      }
    }
  }
]

To search for documents using the full text search feature, use the text query parameter.

Example
curl -X GET -H "Authorization: Bearer 021-08d6c686-6fc1-4149-aa5b-1a05a42f40d1" "https://api.beta.yaas.io/hybris/document/v1/mycomicsshop/myorg.stock/data/books?text=JavaScript%20Scala"

The request returns two documents:

[
    {
        "title": "Functional programming in Scala",
        "description": "This is book about functional programming using Scala language",
        "price" : 10,
        "metadata": {
              "createdAt": "2016-12-07T14:04:03.637+0000",
              "modifiedAt": "2016-12-07T14:04:03.637+0000",
              "version": 1
        },
        "id": "584816d34131211355867871"
      },
      {
        "title": "Functional programming in JavaScript",
        "description": "This is book about functional programming using JavaScript",
        "price" : 5,
        "metadata": {
              "createdAt": "2016-12-07T14:04:21.358+0000",
              "modifiedAt": "2016-12-07T14:04:21.358+0000",
              "version": 1
        },
        "id": "584816e54131211355867872"
      }
]

You can also use text search in combination with a regular query. To search in this way, provide both the text and q query parameters.

curl -X GET -H "Authorization: Bearer 021-08d6c686-6fc1-4149-aa5b-1a05a42f40d1" "https://api.beta.yaas.io/hybris/document/v1/mycomicsshop/myorg.stock/data/books?q=price:5&text=JavaScript%20Scala"

The request returns only one document, the book about JavaScript:

[
    {
          "title" : "Functional programming in JavaScript",
          "description" : "This is book about functional programming using JavaScript",
          "price" : 5,
              "metadata" : {
            "version" : 2,
            "createdAt" : "2016-12-08T07:37:27.838+0000",
            "modifiedAt" : "2016-12-08T07:38:42.947+0000"
          },
          "id" : "584816e54131211355867872"
    }
]

Text search with additional parameters

When using text search, you can also provide additional parameters to support case-sensitive search, language-specific text search, and diacritic-sensitive text search.

There is an additional caseSensitive query parameter. If set to true, then the text search is case sensitive. The default value is false.

Example:
curl -X GET -H "Authorization: Bearer 021-08d6c686-6fc1-4149-aa5b-1a05a42f40d1" "https://api.beta.yaas.io/hybris/document/v1/mycomicsshop/myorg.stock/data/books?text=Book&caseSensitive=true"

This search returns only one document:

[
    {
          "title" : "Cooking for fun",
          "description" : "Book about cooking",
          "price" : 15,
          "metadata" : {
            "version" : 1,
            "createdAt" : "2016-12-08T07:37:40.135+0000",
            "modifiedAt" : "2016-12-08T07:37:40.135+0000"
          },
          "id" : "584817114131211355867873"
    }
]

The language query parameter determines the list of stop words for language-specific searches, as well as the rules for the stemmer and tokenizer functions. Stop words are common words that the system can ignore, the stemmer identifies the root form of words, and the tokenizer identifies phrases and meaningful terms within text strings.

The diacriticSensitive query parameter is a Boolean flag that enables or disables a diacritic-sensitive search. Use the parameter to recognize or ignore the accent marks used in various languages during a full text search.

Text search with document score

The text search feature allows you to add a score to each returned document. The score represents the relevance of a document to a given text search query. To add a score to the results, provide an additional query parameter, scoreField, with the name of the field to add to each document.

Because there is no restriction on the document scheme, you can specify the score field name. Changing the name avoids overriding your fields with the new score field that the full text search feature adds.

For example, specify the query parameter scoreField=rank to add a field called rank to every document, along with the document score.

The service adds the field specified in the scoreField query parameter only when it returns the search results. Your documents remain unchanged.
Example
curl -X GET -H "Authorization: Bearer 021-08d6c686-6fc1-4149-aa5b-1a05a42f40d1" "https://api.beta.yaas.io/hybris/document/v1/mycomicsshop/myorg.stock/data/books?text=Book&scoreField=rank"

The request returns the following documents:

[
    {
          "title" : "Functional programming in Scala",
          "description" : "This is book about functional programming using Scala language",
          "price" : 10,
          "metadata" : {
            "version" : 1,
            "createdAt" : "2016-12-08T07:37:17.534+0000",
            "modifiedAt" : "2016-12-08T07:37:17.534+0000"
          },
          "rank" : 0.5833333333333334,
          "id" : "584816d34131211355867871"
    },
    {
         "title" : "Functional programming in JavaScript",
          "description" : "This is book about functional programming using JavaScript",
          "price" : 5,
          "metadata" : {
            "version" : 2,
            "createdAt" : "2016-12-08T07:37:27.838+0000",
            "modifiedAt" : "2016-12-08T07:38:42.947+0000"
          },
          "rank" : 0.6,
          "id" : "584816e54131211355867872"
    },
    {
          "title" : "Cooking for fun",
          "description" : "Book about cooking",
          "price" : 15,
          "metadata" : {
            "version" : 1,
            "createdAt" : "2016-12-08T07:37:40.135+0000",
            "modifiedAt" : "2016-12-08T07:37:40.135+0000"
          },
          "rank" : 0.75,
          "id" : "584817114131211355867873"
    }
]

Sort results by search score

By default, the service does not sort the text search results by relevance. Use the score feature to sort by relevance. To sort results by score, add the scoreField and sort query parameters to your request. Specify the field that contains the score in the scoreField parameter.

Unlike typical field sorting, you can sort the scoreField in ascending order only.

Example
curl -X GET -H "Authorization: Bearer 021-08d6c686-6fc1-4149-aa5b-1a05a42f40d1" "https://api.beta.yaas.io/hybris/document/v1/mycomicsshop/myorg.stock/data/books?text=Book&scoreField=rank&sort=rank:asc"

The search returns sorted results:

[
    {
          "title" : "Cooking for fun",
          "description" : "Book about cooking",
          "price" : 15,
          "metadata" : {
            "version" : 1,
            "createdAt" : "2016-12-08T07:37:40.135+0000",
            "modifiedAt" : "2016-12-08T07:37:40.135+0000"
          },
          "rank" : 0.75,
          "id" : "584817114131211355867873"
    },
    {
          "title" : "Functional programming in JavaScript",
          "description" : "This is book about functional programming using JavaScript",
          "price" : 5,
          "metadata" : {
            "version" : 2,
               "createdAt" : "2016-12-08T07:37:27.838+0000",
            "modifiedAt" : "2016-12-08T07:38:42.947+0000"
          },
          "rank" : 0.6,
          "id" : "584816e54131211355867872"
    },
    {
          "title" : "Functional programming in Scala",
          "description" : "This is book about functional programming using Scala language",
          "price" : 10,
          "metadata" : {
            "version" : 1,
            "createdAt" : "2016-12-08T07:37:17.534+0000",
            "modifiedAt" : "2016-12-08T07:37:17.534+0000"
          },
          "rank" : 0.5833333333333334,
          "id" : "584816d34131211355867871"
    }
]

Create a text index with a specified default language

You can create a text index with a default language by providing the body content as shown:

{
     "keys" : {
         "title": "text",
        "description" : "text"
    },
    "options": {
         "name" : "myTextIndex",
         "default_language": "german"
     }
}

To learn more about the available options for your indexes, see the Options subsection under Create an index, which describes the options and recommendations for usage in detail.

Example
curl -i -H "Authorization: Bearer 081-3f1219c6-35wf-4863-87b6-5fccf07e09ba" -H "Content-type: application/json" -X POST -d '{"keys":{"title": "text","description" : "text"},"options": {"name":"myTextIndex", "default_language": "german"}}}' https://api.beta.yaas.io/hybris/document/v1/mycomicsshop/myorg.stock/indexes/books

For a list of available languages, refer to the MongoDB documentation, Text Search Languages.

Create a text index on all document fields

You can also create a text index on all fields in your documents. Provide a wildcard field name in the keys section of your request called $all.

{
     "keys" : {
         "$all" : "text"
    },
    "options": {
         "name" : "myTextIndex",
         "default_language" : "german"
     }
}
curl -i -H "Authorization: Bearer 081-3f1219c6-35wf-4863-87b6-5fccf07e09ba" -H "Content-type: application/json" -X POST -d '{"keys":{"$all": "text"},"options": {"name":"myTextIndex", "default_language": "german"}}}' https://api.beta.yaas.io/hybris/document/v1/mycomicsshop/myorg.stock/indexes/books

Create a compound index with text

You can create a compound index that includes text fields.

{
     "keys" : {
         "price" : 1,
         "title" : "text"
    },
    "options": {
         "name" : "myTextIndex",
         "default_language" : "german"
     }
}
curl -i -H "Authorization: Bearer 081-3f1219c6-35wf-4863-87b6-5fccf07e09ba" -H "Content-type: application/json" -X POST -d '{"keys":{"price": 1, "title" : "text"},"options": {"name":"myTextIndex", "default_language": "german"}}}' https://api.beta.yaas.io/hybris/document/v1/mycomicsshop/myorg.stock/indexes/books

For compound indices, provide both text and query parameters in the search request.


Caching

Basic information

The Document service supports HTTP caching headers to significantly reduce:

  • Response times.
  • Bandwidth by not sending the same documents again.
  • Processing resources of the service and the underlying MongoDB database.

The Document service uses ETag (entity tag) headers for cache validation.

When you query a type or fetch a single document, the service calculates an ETag. The ETag mechanism is based on the last modification timestamp of a type. If any document was added, deleted, or modified in a type since the last request, the ETag is invalidated and the service returns a new ETag with the response code 200, along with the payload. Otherwise, the service returns 304 without a payload, and informs you that the type was not modified. ETag works in the same way when fetching a single document as well as whole types.

Using ETags makes sense only when you update the ETag every time you receive a response from the Document service. Otherwise, the service sends the payload in each subsequent response.
The ETag mechanism in the Document service uses caching to ensure the best performance, so it introduces a minor eventual consistency. If you critically need to fetch the most up-to-date data every time, you should not use an ETag.

Example

Step 1: The client issues a GET request in order to fetch a single document or an array of documents.

Request
GET /mycomicsshop/myorg.stock/data/comic HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36
Host: https://api.beta.yaas.io/hybris/document/v1
Accept: */*

Step 2: The Document service responds with the document (or an array of documents) with additional ETag and Cache-Control headers. It calculates the value of the entity tag based on response payload. The value of the entity tag is unique.

Response
HTTP/1.1 200 OK
Date: Thu, 11 Jun 2015 09:33:58 GMT
Content-Type: application/json
Content-Length: 228
ETag: "1472652915"
Cache-Control: private, max-age=31536000
[ {
  "kind" : "History",
  "name" : "Thorgal",
  "metadata" : {
    "createdAt" : "2015-06-11T09:33:24.462+0000",
    "modifiedAt" : "2015-06-11T09:33:24.462+0000",
    "version" : 1
  },
  "id" : "557955e4da08b4f25a0a3f18"
} ]

Step 3: After a while, the client wants to get the same content again, so it makes the same GET request one more time. This time it adds the If-None-Match header, the value of which is the entity tag received from the previous response.

Request
GET /mycomicsshop/myorg.stock/data/comic HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36
Host: https://api.beta.yaas.io/hybris/document/v1
Accept: */*
If-None-Match: "1472652915"

Step 4: The Document service calculates the hash for the payload and compares it to the one from the If-None-Match header from the client's request. If both hashes are equal, the type was not modified and the Document service responds with a status code of 304 (Not Modified) without a payload.

Response
HTTP/1.1 304 Not Modified
Date: Thu, 11 Jun 2015 09:33:58 GMT
ETag: "1472652915"
Cache-Control: private, max-age=31536000

Otherwise, if the document modification occurred within the type and the entity tag differs, it responds with a status code of 200 (OK) with a payload containing the newest version. It also adds the ETag header with a newly calculated hash.

Response
HTTP/1.1 200 OK
Date: Thu, 11 Jun 2015 09:34:01 GMT
Content-Type: application/json
Content-Length: 237
ETag: "1472829315"
Cache-Control: private, no-cache
[ {
  "kind" : "History",
  "name" : "Thorgal modified",
  "metadata" : {
    "createdAt" : "2015-06-11T09:33:24.462+0000",
    "modifiedAt" : "2015-06-11T09:33:59.462+0000",
    "version" : 2
  },
  "id" : "557955e4da08b4f25a0a3f18"
} ]

In cases similar to the example shown, you should update the ETag. Otherwise, when an ETag from the request does not match the current ETag for the type, all subsequent requests return the 200 (OK) response, along with a payload.

This diagram illustrates the aforementioned process.

sequenceDiagram ClientA->> Document service:GET type Comics Note right of Document service: Calculates ETag Document service->> ClientA: Response with ETag ClientA->> Document service:GET type Comics with If-None-Match Note right of Document service: Validates ETag Document service-->> ClientA:304 Not modified without payload ClientB ->> Document service: Insert document into type Comics ClientA->> Document service:GET type Comics with If-None-Match Document service-->> ClientA: 200 OK with payload
For more information about cache validation with ETag, see http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3.2.


Naming conventions

The Document service ensures that the given parameters are valid using the following rules:

  • Tenant - Must be the same as your Project Identifier from the Builder
    • Cannot be null or empty
    • Must have 1-36 characters
    • Cannot contain the following characters: /\. "*<>:|?
  • Client - An ID of a caller
    • Cannot be null or empty
    • Must have 6-49 characters
    • Cannot contain non-alphanumeric characters other than .
    • It is built as a combination of <project_id> and <client_name> separated by a period (.)
    • <project_id> must have 3-16 characters
    • <client_name> must have 2-32 characters
  • Type
    • Cannot be null or empty
    • Must have 1-36 characters
    • Cannot contain the following characters: /\. "*<>:|?
  • dataId
    • Cannot be null or empty
    • Cannot contain the following characters: /\ "*<>|?


Available optimisations to boost your Document service experience

This section describes tips and tricks for improving your experience with the Document service by enhancing performance, reducing resource consumption, and organizing your data.

  • When you work with organized data, you can rely on its structure and find exactly the data you need. There are two ways to keep your content well-organized: Use schemas stored in the Schema service, or use mixins, defined in the Document service.
  • Because schemas in the Schema service are immutable, mixins are a good way to add structure to additional attributes. You can also combine mixins so that documents that contain different attributes can use the same structure of a common attributes. To learn more about schemas, see the Schema topic. To find out more about mixins, visit the Mixins section.
  • You can make your queries less time- and resource-consuming by using one of these options for improving search performance:
    • Paging
    • Streaming, which is more effective for operations on big sets of documents
    • Content encoding

      To improve your search performance, read the Search performance topic. You can also find valuable tips regarding projection and primitive types usage.
  • Creating indexes is an important improvement for all time-critical queries. However, creating indexes is effective only when indexes are thorough, so take your time to read through the Indexes topic. Consider which queries you would like to support with indexing, and how to build the indexes.
  • To significantly reduce bandwidth and processing resources, as well as response times, see the Caching topic, which elaborates on E-Tag support in the Document service.
  • Use aggregates such as sum or count to quickly receive information without handling the data on the client side. See the Aggregation topic for more information.
  • Whenever possible, read and write data using GZIP encoding. For GET requests set the Accept-Encoding header to gzip to receive compressed data and for PUT and POST requests set the Content-Encoding header to gzip and provide compressed body. Transferring compressed data significantly reduces response times and the bandwidth used.
  • You can boost performance and lower your bill by combining two or more of the aforementioned tips.

Here are some example scenarios that use these improvements for document organization, as well as for boosting search performance and reducing costs.

Document organization improvement

You can improve the overall organization of your documents by using schemas with mixins or separate mixins.

Schema and mixin or mixins

In this scenario, you plan to create lots of documents that have a particular structure as well as a few documents that have additional attributes.

First, create a schema in the Schema service that corresponds to the structure of most of your documents. To provide structure for the few documents with extra attributes, create a mixin for the additional attributes. You can also create a separate mixin for each different attribute, so you can combine and mix them according to your needs.

Performance boosters and cost savers

You can enhance the performance of your searches using the following methods.

q query + tags + paging + projection + primitive types

Build your query, narrowing the search to include, for example, documents that contain specific tags, as well as a date range. You can use projection if you only need the response to return some fields (for example, product name and price). The price is stored as a number, so it doesn't needlessly slow down the query. Set the pageSize for your request (the lower the better) and provide the pageNumber to be returned.

q query + fetchAll

The most efficient way to get a big data set is to send the fetchAll parameter, set to true and the Accept-Encoding header set to gzip, along with the GET request. You can further speed up the process by narrowing the results with a q query parameter. Using this approach, you can receive an entire set of documents in a single response, from a single request. The service delivers the data set to you in a compressed gzip format, which significantly improves performance. If you do not use the q query parameter to narrow your requests for very large documents sets of a given type, the service does not return the full data set in response.

Aggregation

Suppose you need to know how many documents of a given type you have, and the average value of two of the attributes. You can accomplish this most efficiently by sending a request with the avg parameter pointing to the specified attributes, and the count parameter set to true. With this approach, you receive your response almost instantly and do not need to worry about the logic for both operations.


Introduction To Tutorials

The Document service API tutorials are based on the following scenario:

  • You have a shop that sells comics.
  • Comic books are identified by a type named comic to differentiate them from other types of books.
  • You are creating a comic called Thorgal.

Remember to replace {tenant} with your Project Identifier and {client} with your YaaS Client Identifier. Both values can be obtained from Projects > {My Project} > Clients > {My client} in the Builder. For more details, see the Authorization section of the Overview.

Do not use the Document service as MongoDB over REST

Even though the Document service is implemented with MongoDB as storage:

  • Do not rely on MongoDB functions.
  • Do not use naming conventions typical for MongoDB.
  • Do not use any restricted characters as field names in subdocuments.
  • Use only Document service conventions.


Perform Simple CRUD Operations

Get all your variables in one place

The following variables are used within this tutorial:

tenant = {{projectId}};
client = {{clientName}};
AccessToken = {{token}};

Create an API client for the Document service

API.createClient('documentService',
'/services/document/v1/api.raml');

Create a simple object

  • Method: POST
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document. In this example, it is comic.
  • Response:
    • Status code: 201
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').post({
  'kind': 'History',
  'name': 'Thorgal'
},
{
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
comic_obj.body

To make calls simpler and code cleaner, assign Id of returned object to a variable.

id = comic_obj.body.id;
id

Retrieve an object

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document. In this example, it is comic
      • dataId: The Id of an object.
  • Response:
    • Status code: 200
get_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
get_obj.body

Retrieve all objects of a given type

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document. In this example, it is comic
  • Response:
    • Status code: 200
get_all = documentService.tenant(tenant).client(client).data.type('comic').get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
get_all.body

Update an object with additional information

Perform a partial update on the object:

  • Method: PUT
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:

    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document. In this example, it is comic.
      • dataId: The ID of an object.
  • Query Parameters:

    • patch: true
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).put({
 'title': 'Child of the Stars'
}, {
  headers: {
            'Authorization': 'Bearer ' + AccessToken,
            'Content-type' : 'application/json'
  },
  query: {
    'patch' : true
  }
})
comic_obj.body
  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document. In this example, it is comic.
      • dataId: The ID of an object.

Verify the object update

Get the object to make sure that it was updated. With the exception of the new attribute, the modifiedAt date information is also updated.

get_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
get_obj.body

Update an object with new information

Now perform a full replace of the object.

  • Method: PUT
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document. In this example, it is comic.
      • dataId: The ID of an object.
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).put({
  'name': 'Thorgal',
  'title': 'The Brand of the Exiles',
  'kind': 'History'
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
comic_obj.body

Verify the information replacement

With the exception of the new attribute, the modifiedAt and createdAt date information is also updated.

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document. In this example, it is comic.
      • dataId: The ID of an object.
get_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
get_obj.body

Delete an attribute from an object

  • Method: DELETE
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}/{attributeName}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document. In this example, it is comic.
      • dataId: The ID of an object.
      • attributeName: The name of an attribute. In this example, it is name.
remove = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).attributeName('name').delete(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
  }
})

Delete an object

  • Method: DELETE
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
remove = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).delete(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
  }
})

Verify the object delete

Request

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document. In this example, it is comic.
      • dataId: The ID of an object.
get_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
get_obj.body

Create a simple object with a custom ID

  • Method: POST
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document. In this example, it is comic.
      • dataId: The ID of an object. In this example, it is sampleId.
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId('sampleId').post({
  "kind": "History",
  "name": "Thorgal"
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
comic_obj.body
documentService.tenant(tenant).client(client).data.type('comic').dataId('sampleId').delete(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
  }
})
comic_obj.body


Use Date and Time Attributes When Creating and Searching

Get all your variables in one place

The following variables are used within this tutorial:

tenant = {{projectId}};
client = {{clientName}};
AccessToken = {{token}};

Create API client for Document service

API.createClient('documentService',
'/services/document/v1/api.raml');

Create an object with one date/time attribute

Request

  • Method: POST
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document. In this example, it is comic.
  • Headers:
    • hybris-metaData: releaseDate:date
  • Response:
    • Status code: 201
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').post({
  'name': 'Thorgal',
  'title': 'Child of the Stars',
  'releaseDate': '1986-05-13T12:00:00.000Z'
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
    'hybris-metaData' : 'releaseDate:date'
  }
})
comic_obj.body

The date should be provided in ISO standard format.

Retrieve an object with a query on the date/time attribute

Failing to comply to an ISO standard might result in a response with an empty array in the body and a status code of 200.

Request

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document. In this example, it is comic.
  • Headers:
    • hybris-metaData: releaseDate:date
  • Query Parameters:
    • q: releaseDate:(>=1986-05-13 AND <1986-05-14)
  • Response:
    • Status code: 200

To get an object with a specific date, you must combine a query as shown in the example. You cannot use releaseDate:=1986-05-13.

get_obj = documentService.tenant(tenant).client(client).data.type('comic').get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
    'hybris-metaData' : 'releaseDate:date'
  },
  query: {
    'q' : "releaseDate:(>=1986-05-13 AND <1986-05-14)"
  } 
})
get_obj.body


Use Alias on an ID Field When Creating and Searching

Get all your variables in one place

The following variables are used within this tutorial:

tenant = {{projectId}};
client = {{clientName}};
AccessToken = {{token}};

Create API client for Document service

API.createClient('documentService',
'/services/document/v1/api.raml');

Create an object with an alias on the ID field

Request

  • Method: POST
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document. In this example, it is comic.
  • Headers:
    • hybris-metaData: comicId:id
  • Response:
    • Status code: 201
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').post({
  'kind': 'History',
  'name': 'Thorgal',
  'comicId': 'C01H02'
}, 
{
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
    'hybris-metaData' : 'comicId:id'
  }
})
comic_obj.body

Retrieve an object with an alias on the ID field using query parameters

Request

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document. In this example, it is comic.
  • Headers:
    • hybris-metaData: comicId:id
  • Query Parameters:
    • q: comicId:"C01H02"
  • Response:
    • Status code: 200
get_obj = documentService.tenant(tenant).client(client).data.type('comic').get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
    'hybris-metaData' : 'comicId:id'
  },
  query: {
    'q' : "comicId:C01H02"
  } 
})
get_obj.body

Retrieve all objects with an alias on the ID field

Request

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document. In this example, it is comic.
  • Headers:
    • hybris-metaData: comicId:id
  • Response:
    • Status code: 200
get_obj = documentService.tenant(tenant).client(client).data.type('comic').get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
    'hybris-metaData' : 'comicId:id'
  }
})
get_obj.body

Request

  • Method: HEAD
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document. In this example, it is comic.
  • Headers:
    • hybris-metaData: comicId:id
  • Query Parameters:
    • q comicId:(C01H02, C01H03)
  • Response:
    • Status code: 200
count = documentService.tenant(tenant).client(client).data.type('comic').head(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
    'hybris-metaData' : 'comicId:id'
  },
  query: {
    'q' : "comicId:(C01H02, C01H03)"
  }        
})
count.headers


Use Aliases on Audit Fields

Get all your variables in one place

The following variables are used within this tutorial:

tenant = {{projectId}};
client = {{clientName}};
AccessToken = {{token}};

Create API client for Document service

API.createClient('documentService',
'/services/document/v1/api.raml');

In the Document service, you can map different naming for the audit fields createdAt and modifiedAt. This can be done using metadata or a schema.

Prerequisites

There are two schemas used in this tutorial. You can create schemas based on the these examples and publish them on a server of your choice or in the Schema service:

Mapping audit fields using metadata

Create a document with nested audit fields and aliases

Request
  • Method: POST
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:

    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
  • Headers:

    • hybris-metadata: timeDetails.when_created:createdAt;timeDetails.when_changed:modifiedAt
  • Response:
    • Status code: 201
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').post({
  'name': 'Thorgal',
  'title': 'Children of the stars'
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
    'hybris-metadata' : 'timeDetails.when_created:createdAt;timeDetails.when_changed:modifiedAt'
  }
})
comic_obj.body

To make calls simpler and code cleaner, assign Id of returned object to a variable.

id = comic_obj.body.id;
id

Retrieve a document

Request
  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
      • dataId: The ID of an object.
  • Headers:
    • hybris-metadata: timeDetails.when_created:createdAt;timeDetails.when_changed:modifiedAt
  • Response:
    • Status code: 200
get_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
    'hybris-metadata' : 'timeDetails.when_created:createdAt;timeDetails.when_changed:modifiedAt'
  }
})
get_obj.body

Mapping audit fields using a schema

Create a document with aliases for audit fields

Request
  • Method: POST
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
  • Response:
    • Status code: 200
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').post({
  'name': 'Thorgal',
  'title': 'Children of the stars',
  'metadata' : {
    'schema': 'https://api.us.yaas.io/hybris/schema/v1/framefrog/mapAuditFields'
  }
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
comic_obj.body

Assign new Id of returned object to a variable.

id = comic_obj.body.id;
id

Retrieve a Document

Request
  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
      • dataId: The ID of an object.
  • Response:
    • Status code: 201
get_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
get_obj.body

Nest audit fields

Request
  • Method: PUT
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
      • dataId: The ID of an object.
  • Query Parameters:
    • patch: true
  • Response:
    • Status code: 200
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).put({
  'metadata': {
    'schema':'https://api.us.yaas.io/hybris/schema/v1/framefrog/nestAuditFields'
  }
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  },
  query: {
    'patch' : true
  }
})
comic_obj.body

Retrieve a document with nested audit fields

Request
  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
      • dataId: The ID of an object.
get_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
get_obj.body


Perform a Projection to Limit a List of Returned Object's Fields or Attributes

Get all your variables in one place

The following variables are used within this tutorial:

tenant = {{projectId}};
client = {{clientName}};
AccessToken = {{token}};

Create API client for Document service

API.createClient('documentService',
'/services/document/v1/api.raml');

Create objects

To simulate a projection, you must first create three sample objects as shown in this example.

Request
  • Method: POST
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
  • Response:
    • Status code: 201
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').post({
  'name': 'Thorgal',
  'title': 'The Three Elders of Aran',
  'price' : '15.99',
  'cover' : 'hardcover'
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
comic_obj.body

To make calls simpler and code cleaner, assign Id of returned object to a variable.

id = comic_obj.body.id;
id
comic_obj2 = documentService.tenant(tenant).client(client).data.type('comic').post({
  'name': 'Thorgal',
  'title': 'Child of the Stars',
  'price' : '10',
  'cover' : 'hardcover'
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
comic_obj2.body
id2 = comic_obj2.body.id;
id2
comic_obj3 = documentService.tenant(tenant).client(client).data.type('comic').post({
  'name': 'Thorgal',
  'title': 'The Guardian of the Keys',
  'price' : '15.99',
  'cover' : 'paperback',
  'condition' : 'good'
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
comic_obj3.body
id3 = comic_obj3.body.id;
id3

Retrieve a specific object with a projection on fields

In this example, you retrieve Thorgal comic with title and price attributes.

Request
  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
      • dataId: The ID of an object.
  • Query parameters:
    • fields: title, price
  • Response:
    • Status code: 200
get_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  },
  query: {
    'fields' : 'title, price'
  }         
})
get_obj.body

Get the number of objects with a projection on fields

In this example, you get Thorgal comics that have a title, price, and version.

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
  • Query parameters:
    • fields: title, price, version
  • Response:
    • Status code: 200
get_obj = documentService.tenant(tenant).client(client).data.type('comic').get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  },
  query: {
    'fields' : 'title, price, version'
  }         
})
get_obj.body


Search for Objects and Sort Search Result

Get all your variables in one place

The following variables are used within this tutorial:

tenant = {{projectId}};
client = {{clientName}};
AccessToken = {{token}};

Create API client for Document service

API.createClient('documentService',
'/services/document/v1/api.raml');

Create objects

To simulate a search, you must first create three sample objects as shown in this example.

Request
  • Method: POST
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
  • Response:
    • Status code: 201
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').post({
  'name': 'Thorgal',
  'title': 'The Three Elders of Aran',
  'price': 15.99,
  'cover': 'hardcover'
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
comic_obj.body
comic_obj2 = documentService.tenant(tenant).client(client).data.type('comic').post({
'name': 'Thorgal',
'title': 'Child of the Stars',
'price': 10,
'cover': 'hardcover'
}, {
  headers: {
            'Authorization': 'Bearer ' + AccessToken,
            'Content-type' : 'application/json'
           }
    })
comic_obj2.body
comic_obj3 = documentService.tenant(tenant).client(client).data.type('comic').post({
  'name': 'Thorgal',
  'title': 'The Guardian of the Keys',
  'price': 15.99,
  'cover': 'paperback',
  'condition' : 'good'
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
comic_obj3.body

Retrieve an object with a query on attributes

In this example, you search for a Thorgal comic using the following query:

  • Cover type is hardcover.
  • Price is between 10 and 20.
  • Title is The Guardian of the Keys or The Three Elders of Aran or Child of the Stars.
  • Added to the database after 2014-04-18.
  • Search results sorted in ascending order.
Request
  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
  • Query Parameters:
    • q: name:"Thorgal" cover:"hardcover" price:(>=10 AND <=20) title:in("The Guardian of the Keys","The Three Elders of Aran","Child of the Stars") createdAt:>=2014-04-18
    • sort: title:asc
get_obj = documentService.tenant(tenant).client(client).data.type('comic').get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  },
  query:   {
    'q' : 'name:Thorgal cover: hardcover price:(>=10 AND <=20) title:in("The Guardian of the Keys", "The Three Elders of Aran", "Child of the Stars") createdAt:>=2014-04-18',
    'sort' : 'title:asc'
  }         
})
get_obj.body

SAP Hybris recommends that you create indexes for better search performance.

Retrieve an object with a query based on attribute presence

In this example, you search for a Thorgal comic with a condition attribute.

Request

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
  • Query Parameters:
    • q: name:"Thorgal" condition:exists
get_obj = documentService.tenant(tenant).client(client).data.type('comic').get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  },
  query:   {
    'q' : 'name:"Thorgal" condition:exists'
  }         
})
get_obj.body
  • If you want to find an object that does not have a specific attribute, use the query term missing instead of exists.
  • If you want to find an object with an attribute that has the value exists or missing, you must put these values in quotation marks: name:"exists".

    Basic search options

    In this example, you search for a Thorgal comic with the following conditions:

  • The name of the comic series is Thorgal:
    name:Thorgal

  • The cover type is hardcover:
    cover:hardcover
  • The price is between 10 and 20 (greater than or equal to 10, less than or equal to 20):
    price:(>=10+AND+<=20)
  • The title is The Guardian of the Keys, The Three Elders of Aran, or Child of the Stars:
    title:in("The+Guardian+of+the+Keys","The+Three+Elders+of+Aran","Child+of+the+Stars")
  • The comic was added to the database on or after April 18, 2015 (2015-04-18):
    createdAt:>=2015-04-18
  • There is an existing attribute that describes the physical condition of the comic:
    condition:exists

    This is how the query looks in a URI:

    ?q=name:"Thorgal" cover:"hardcover" price:(>=10+AND+<=20)+title:in("The+Guardian+of+the+Keys","The+Three+Elders+of+Aran","Child+of+the+Stars")+createdAt:>=2015-04-18+condition:exists

  • The first two conditions point to the specific values of the attributes name and cover.
  • The next condition, price, has a specified range of values defined by logical symbols of equality = and inequality <, >. The range of values must be put inside the parentheses () with the AND operator between the beginning and end values of the range.
  • The condition for title contains three different but specific values separated by commas and enclosed in parentheses. The Document service returns documents that match any of the included values.
  • The next condition refers to a standard createdAt attribute in the Document service that uses date and time notation in an ISO standard format. In this case, it is a range of time defined by logical symbols of equality and inequality, but you can also use a specific date and time.
  • The last condition checks if there is an attribute describing the physical condition of the comic. It only checks whether the specified value exists. It does not check what the value of the attribute is. You can also search for missing attributes by replacing exists with missing.

    Count from a query

    This example returns a total count of the number of objects in the collection.

    Request

  • Method: HEAD

  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
  • Query Parameters:
    • q: name:"Thorgal" cover:"hardcover" price:(>=10 AND <=20) title:("The Guardian of the Keys","The Three Elders of Aran","Child of the Stars") createdAt:>=2014-04-18
count = documentService.tenant(tenant).client(client).data.type('comic').head(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  },
  query:   {
    'q' : 'name:"Thorgal" cover:"hardcover" price:(>=10 AND <=20) title:("The Guardian of the Keys","The Three Elders of Aran","Child of the Stars") createdAt:>=2014-04-18'
  }         
})
count.headers

Streaming big result sets

This example shows how you can stream large result sets when you query the /{tenant}/{client}/data/{type} endpoint without paging.

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
  • Query parameters:
    • fetchAll: A query parameter that fetches all of the records in a single request.
  • Response:
    • Status code: 200
    • Transfer-encoding: chunked
When fetchAll query parameter is set to true, do not provide pageNumber and/or pageSize query parameters as this results in 400 Bad Request response from the Document service.
The response for the request with fetchAll parameter set to true does not return totalCount (even if totalCount parameter was set to true in the request.) If you need a number of documents that are returned, you must handle this logic on your side.


Sort Objects by Localized Attributes

Get all your variables in one place

The following variables are used within this tutorial:

tenant = {{projectId}};
client = {{clientName}};
AccessToken = {{token}};

Create API client for Document service

API.createClient('documentService',
'/services/document/v1/api.raml');

The Document service supports sorting in ascending and descending order.

  • Ascending (asc): Objects with localized attributes are listed after objects without such attributes or without localization on such attributes.
  • Descending (desc): Objects with localized attributes are listed first.

Create objects

To simulate a search, you must first create three sample objects as shown in this example.

Request
  • Method: POST
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
  • Headers:
    • Content-Language: Optional. To be provided only if the body of the request does not contain languages map.
    • hybris-metaData: title:localized
  • Response:
    • Status code: 201
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').post({
  'name': 'Thorgal',
  'title': {
    'pl' : 'Miasto zaginionego boga',
    'en' : 'City of the Lost God'
  },
  'price': 15.99,
  'cover': 'hardcover'
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
    'hybris-metaData' : 'title:localized'
  }
})
comic_obj.body
comic_obj2 = documentService.tenant(tenant).client(client).data.type('comic').post({
  'name': 'Thorgal',
  'title': {
    'pl' : 'Gwiezdne Dziecko',
    'en' : 'Child of the stars'
  },
  'price': 10,
  'cover': 'hardcover'
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
    'hybris-metaData' : 'title:localized'
  }
})
comic_obj2.body
comic_obj3 = documentService.tenant(tenant).client(client).data.type('comic').post({
  'name': 'Thorgal',
  'title': {
    'pl' : 'Strażniczka kluczy',
    'en' : 'The Guardian of the Keys'
  },
  'price': 15.99,
  'cover': 'paperback'
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
    'hybris-metaData' : 'title:localized'
  }
})
comic_obj3.body

To make calls simpler and code cleaner, assign Id of returned object to a variable.

id = comic_obj.body.id;
id
id2 = comic_obj2.body.id;
id2
id3 = comic_obj3.body.id;
id3

Retrieve objects sorted in descending order by localized attribute - without a metadata header

Request
  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
  • Query Parameters:
    • sort: title.pl:desc
get_obj = documentService.tenant(tenant).client(client).data.type('comic').get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  },
  query:   {
    'sort' : 'title.pl:desc'
  }         
})
get_obj.body

Retrieve objects sorted in ascending order by localized attribute - with a metadata header

Request

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
  • Headers:
    • Accept-Language: pl
    • hybris-metaData: title:localized
  • Query Parameters:
    • sort: title:asc
get_obj= documentService.tenant(tenant).client(client).data.type('comic').get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
    'Accept-Language' : 'pl',
    'hybris-metaData' : 'title:localized'
  },
  query:   {
    'sort' : `title:asc`
  }         
})
get_obj.body


Create an Index for Better Searching Performance

Get all your variables in one place

The following variables are used within this tutorial:

tenant = {{projectId}};
client = {{clientName}};
AccessToken = {{token}};

Create an API client for the Document service

API.createClient('documentService',
'/services/document/v1/api.raml');

Create an index for two attributes

To create an ascending index, use 1 as the value. For a descending index, use -1.

Request

  • Method: POST
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/indexes/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document. In this example, it is comic.
  • Response:
    • Status code: 201
index_obj = documentService.tenant(tenant).client(client).indexes.type('comic').post({
  'keys': {
    'name' : 1,
    'cover' : -1
  }
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
index_obj.body
If your request results in the 429 response code from the Document service, send your request again at a later time. To learn more about index creation limitations, see the Considerations section of the Document service documentation.

You can also use options in the body of your request to create, for instance an index with a unique name.

  • Body:

{ "keys" : { "name" : 1, "cover" : -1 }, "options" : { "name" : "ComicIndx" } }

Retrieve all indexes to confirm that the index is on the list

Request

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/indexes/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document. In this example, it is comic.
  • Response:
    • Status code: 200
get_obj = documentService.tenant(tenant).client(client).indexes.type('comic').get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
get_obj.body


Operate on Object with Localized Attributes

Get all your variables in one place

The following variables are used within this tutorial:

tenant = {{projectId}};
client = {{clientName}};
AccessToken = {{token}};

Create API client for Document service

API.createClient('documentService',
'/services/document/v1/api.raml');

Create an object with one localized attribute with multiple languages

Request

  • Method: POST
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
  • Headers:
    • Content-Language: Use this header to specify the language of the attribute value. Do not use this header if the body of your request contains a language map.
    • hybris-metaData: title:localized
  • Response:
    • Status code: 201
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').post({
  'name': 'Thorgal',
  'title': {
    'en': 'The Archers',
    'fr': 'Les Archers'
  }
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
    'hybris-metaData' : 'title:localized'
  }
})
comic_obj.body

To make calls simpler and code cleaner, assign Id of returned object to a variable.

id = comic_obj.body.id;
id

Retrieve objects by localized attributes

Request

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document. In this example, it is comic.
  • Headers:
    • Accept-Language: fr
    • hybris-metaData: title:localized
  • Response:
    • Status code: 200

The response includes an object with the title attribute and its localized value.

get_obj = documentService.tenant(tenant).client(client).data.type('comic').get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
    'hybris-metaData' : 'title:localized',
    'Accept-Language' : 'fr'
  }
})
get_obj.body
  • If an object does not have a localized title, it is returned with a default value.
  • If an object has a localized title, but the desired language is not available, it is returned with a null value.
  • You can also have a fallback mechanism when getting a list of objects. For example, if you want to display an English title instead of a null value when a Polish title is not available , you must pass pl,en in the request header Accept-Language to indicate Polish (pl) as a primary language and English (en) as a fallback language. This fallback accepts the desired languages with their weights, such as pl,en;q=0.8. The weight of the Polish language is 1.0 (implicit) and English is 0.8. The languages are separated by a comma (,), and the weight is supplied after a semicolon (;). For more information, see this list of HTTP header fields.

Update a localized attribute with an additional value

Request

  • Method: PUT
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
      • dataId: The ID of an object.
  • Headers:
    • Content-Language: pl
    • hybris-metaData: title:localized
  • Query Parameters:
    • partial: true
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).put({
  'title': 'Łucznicy'
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
    'hybris-metaData' : 'title:localized',
    'Content-Language' : 'pl'
  },
  query: {
    'patch' : true
  }
})
comic_obj.body

Retrieve an object to verify that its title is available in three languages

To retrieve all values of localized attribute perform a simple GET request without header specifying the particular language.

Request

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
      • dataId: The ID of an object.
get_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
get_obj.body


Get Aggregated Data

Get all your variables in one place

The following variables are used within this tutorial:

tenant = {{projectId}};
client = {{clientName}};
AccessToken = {{token}};

Create API client for Document service

API.createClient('documentService',
'/services/document/v1/api.raml');

Create objects

To try the aggregation, we must first store some data. We start with creating three simple objects of type comic.

Request
  • Method: POST
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
  • Response:
    • Status code: 201
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').post({
  'name': 'Thorgal',
  'title': 'The Three Elders of Aran',
  'price': 16,
  'cover': 'hardcover',
  'reviews' : {
    'number' : 12,
    'score' : 8.7
  }
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
  }
})
comic_obj.body
comic_obj2 = documentService.tenant(tenant).client(client).data.type('comic').post({
  'name': 'Thorgal',
  'title': 'Child of the stars',
  'price': 14,
  'cover': 'hardcover',
  'reviews' : {
    'number' : 10,
    'score' : 9.1
  }
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
  }
})
comic_obj2.body
comic_obj3 = documentService.tenant(tenant).client(client).data.type('comic').post({
  'name': 'Thorgal',
  'title': 'The Guardian of the Keys',
  'price': 12.99,
  'cover': 'paperback',
  'condition' : 'good',
  'reviews' : {
    'number' : 18,
    'score' : 8.9
  }
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
  }
})
comic_obj3.body

Retrieve aggregated data on a specific attribute

For the created data we would like to get the average price, the average reviews' score and the sum of total reviews. Additionally we would like to know the number of objects. We want all of these for comics in hardcover only, so we add a proper query.

Request

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/aggr/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
  • Query Parameters:
    • avg: price,reviews.score
    • count: true
    • sum: reviews.number
    • q: cover:hardcover
get_obj = documentService.tenant(tenant).client(client).aggr.type('comic').get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  },
  query:   {
    'avg' : 'price,reviews.score',
    'sum' : 'reviews.number',
    'count' : 'true',
    'q' : 'cover:hardcover'
  }
})
get_obj.body


Operate on tags

Get all your variables in one place

The following variables are used within this tutorial:

tenant = {{projectId}};
client = {{clientName}};
AccessToken = {{token}};

Create API client for Document service

API.createClient('documentService',
'/services/document/v1/api.raml');

You can use tags in two ways:

  • To add an array of tags to an existing object. You can have more than one array of tags with different names.
  • To create an independent object with tags.

You can use optimistic locking (versioning) using the version query parameter.

Create objects

To simulate adding, removing, and reading tags, you must first create a sample object as shown in this example.

Request
  • Method: POST
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
  • Response:
    • Status code: 201
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').post({
  'name': 'Thorgal',
  'title': 'Child of the Moon'
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
  }
})
comic_obj.body

To make calls simpler and code cleaner, assign Id of returned object to a variable.

id = comic_obj.body.id;
id

Create tags

You can simultaneously add several tags to an object. Tags must be text values. Any duplicates are removed. If you attempt to add tags to an object that does not exist, the object is created.

Request
  • Method: POST
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/tags/{type}/{id}/{tagName}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
    • dataId: The ID of an object.
    • tagName: The name of a tag array.
  • Query parameters:
    • tags: The values to be added as a tags.
  • Response:
    • Status code: 200
comic_obj = documentService.tenant(tenant).client(client).tags.type('comic').id(id).tagName('comicTags').post({
  'name': 'Thorgal',
  'title': 'Child of the Moon'
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
  },
  query: {
    'tags' : 'comic paper'
  }         
})
comic_obj.body

Retrieve a tag array

Request

  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
      • dataId: The ID of an object.
  • Response:
    • Status code: 200
get_tags = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
get_tags.body

You can also use the GET method to retrieve only specific tags in the response. For more information, see Perform projection to limit a list of returned object's fields or attributes.

Remove tags

You can delete one or more tags from the document.

Request

  • Method: DELETE
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/tags/{type}/{id}/{tagName}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
      • id: The ID of an object.
      • tagName: The exact value from the tag array.
  • Query Parameters:
    • tags: comic paper
  • Response:
    • Status code: 204
remove = documentService.tenant(tenant).client(client).tags.type('comic').id(id).tagName('comicTags').delete(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
  },
  query: {
    'tags' : 'comic paper'
  }
})


Perform Versioning with Optimistic Locking

Get all your variables in one place

The following variables are used within this tutorial:

tenant = {{projectId}};
client = {{clientName}};
AccessToken = {{token}};

Create API client for Document service

API.createClient('documentService',
'/services/document/v1/api.raml');

Create an object

To simulate optimistic locking, you must first create a sample object.

Request
  • Method: POST
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
    • dataId: The ID of an object.
  • Response:
    • Status code: 201
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').post({
  'name': 'Thorgal',
  'title': 'Child of the Moon',
  "price": 15.99,
  "cover": "hardcover"
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
  }
})
comic_obj.body

To make calls simpler and code cleaner, assign Id of returned object to a variable.

id = comic_obj.body.id;
id

Retrieve the object

In this example, two employees get the same object using the GET method.

Request

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
      • dataId: The ID of an object.
  • Response:
    • Status code: 200
get_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
get_obj.body

Add a new value for an attribute

Both employees try to change the title from "Child of the Moon" to "Child of the Star" using the PUT method.

Request

  • Method: PUT
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
      • dataId: The ID of an object.
  • Query parameters:
    • partial: true
    • version: 1

First response

This is the response that the first employee receives:

  • Status code: 200
  • Body:
    • Content type: application/json json { "code": "200", "status": "200", "message": "Operation succeeded" }
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).put({
  'title' : 'Child of the Star'
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  },
  query: {partial: true,
    version: 1}
  })
  comic_obj.body

Second response

This is the response that the second employee receives.

  • Status code: 409
  • Body:
  • Content type: application/json

{ "status": "409", "message": "Optimistic locking failure: can't find object with given version: 1", "code": 409 }

comic_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).put({
  'title' : 'Child of the Star'
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  },
  query: {partial: true,
    version: 1}
  })
  comic_obj.body

Retrieve the object after changes

The employee that receives the error code of 409 must get the object again with the new properties.

Request

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
      • dataId: The ID of an object. Response: Status code: 200
get_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
get_obj.body

Delete the object

In this example, an employee want to delete version 1 of the document which is updated by another employee to version 2.

Request

  • Method: DELETE
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
      • dataId: The ID of an object.
  • Query Parameters:
    • version: 2

Response

  • Status code: 409
  • Body:
    • Content type: application/json { "status": "409", "message": "Optimistic locking failure: can't find object with given version: 1", "code": 409 }
remove = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).delete(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken
  }, 
  query:    {version: 1}
})


Perform a Partial Update on Multiple Objects

Get all your variables in one place

The following variables are used within this tutorial:

tenant = {{projectId}};
client = {{clientName}};
AccessToken = {{token}};

Create API client for Document service

API.createClient('documentService',
'/services/document/v1/api.raml');

Create objects

To simulate a bulk update, you must first create three sample objects as shown in this example.

comic_obj = documentService.tenant(tenant).client(client).data.type('comic').post({
  "name": "Thorgal",
  "title": "The Three Elders of Aran",
  "price": 15.99,
  "cover": "hardcover"
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
comic_obj.body
comic_obj2 = documentService.tenant(tenant).client(client).data.type('comic').post({
  "name": "Thorgal",
  "title": "Child of the Stars",
  "price": 10,
  "cover": "hardcover"
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
comic_obj2.body
comic_obj3 = documentService.tenant(tenant).client(client).data.type('comic').post({
  "name": "Thorgal",
  "title": "The Guardian of the Keys",
  "price": 15.99,
  "cover": "paperback",
  "condition": "good"
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
comic_obj3.body

Update multiple objects

Request

  • Method: PUT
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
  • Query parameters:

    • q: price:15.99
  • Response:

    • Status code: 200
update = documentService.tenant(tenant).client(client).data.type('comic').put({
  'rarity': 'uncommon'
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  },
  query: {
    'q' : 'price:15.99'
  }
})
update.body

Retrieve information about updated objects

Request

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
  • Query Parameters:
    • q: rarity:uncommon
  • Response:
    • Status code: 200
get_obj = documentService.tenant(tenant).client(client).data.type('comic').get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  },
  query: {
    'q' : "rarity:uncommon"
  } 
})
get_obj.body


Perform Bulk Operations on Tags

Get all your variables in one place

The following variables are used within this tutorial:

tenant = {{projectId}};
client = {{clientName}};
AccessToken = {{token}};

Create API client for Document service

API.createClient('documentService',
'/services/document/v1/api.raml');

Create objects

To simulate a bulk update, you must first create three sample objects as shown in this example.

comic_obj = documentService.tenant(tenant).client(client).data.type('comic').post({
  "name": "Thorgal",
  "title": "The Three Elders of Aran",
  "price": 15.99,
  "cover": "hardcover"
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
comic_obj.body
comic_obj2 = documentService.tenant(tenant).client(client).data.type('comic').post({
  "name": "Thorgal",
  "title": "Child of the Stars",
  "price": 10,
  "cover": "hardcover"
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
comic_obj2.body
comic_obj3 = documentService.tenant(tenant).client(client).data.type('comic').post({
  "name": "Thorgal",
  "title": "The Guardian of the Keys",
  "price": 15.99,
  "cover": "paperback",
  "condition": "good"
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
comic_obj3.body

Create tags for all objects of a specific type

You can simultaneously add tags to multiple objects of the same type.

  • Tags must be text values.
  • Any duplicates are removed.
  • You can narrow the object list by adding a simple query.
  • This operation creates an array of tags. You can have more than one array of tags with different names.

Request

  • Method: POST
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/tags/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
  • Query Parameters:
    • q: name: Thorgal
    • tags: genre: fantasy,adventure
  • Response:
    • Status code: 200
comic_obj = documentService.tenant(tenant).client(client).tags.type('comic').post(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
  },
  query:  {q : 'name:Thorgal',
  tags : 'genre:fantasy,adventure'}       
})
comic_obj.body

Get all objects of a specific type to confirm tags addition

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
  • Required:
    • tenant: The project that requests this resource.
    • client: The ID of the client.
    • type: The type attribute of the document.
  • Headers:
    • Optional:
      • Accept-Encoding: Set the header to the gzip value to receive a compressed response, thus reducing the response time and bandwidth used. GZIP is the only supported format for content encoding.
  • Query Parameters:
  • q: name: Thorgal
  • Response:
  • Status code: 200
get_obj = documentService.tenant(tenant).client(client).data.type('comic').get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
    'Accept-Encoding' : 'gzip',
  },
  query: {q : 'name:Thorgal'}
})
get_obj.body

Remove tags for all objects of a specific type

This operation contains an additional query parameter called removeEmpty that specifies whether or not to remove the empty array when the tags are removed. If this parameter is set to false, the tags are deleted from the array, but the empty array still exists.

Request

  • Method: DELETE
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/tags/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
  • Query Parameters:
    • q: name: Thorgal
    • removeEmpty: false
    • tags: genre: fantasy,adventure
  • Response:
    • Status code: 204
remove = documentService.tenant(tenant).client(client).tags.type('comic').delete(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
  },
  query: {q : 'name:Thorgal',
  removeEmpty : false,
  tags : 'genre:fantasy,adventure'}
})

Get all objects of a specific type to confirm tags deletion

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
  • Required:
    • tenant: The project that requests this resource.
    • client: The ID of the client.
    • type: The type attribute of the document.
  • Query Parameters:
  • q: name: Thorgal
  • Response:
  • Status code: 200
get_obj = documentService.tenant(tenant).client(client).data.type('comic').get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json',
    'Accept-Encoding' : 'gzip',
  },
  query: {q : 'name:Thorgal',
  tags : 'genre:fantasy,adventure'}
})
get_obj.body


Nested objects

Get all your variables in one place

The following variables are used within this tutorial:

tenant = {{projectId}};
client = {{clientName}};
AccessToken = {{token}};

Create API client for Document service

API.createClient('documentService',
'/services/document/v1/api.raml');

Create an object with a nested array object

In this example, you want to sell second-hand comics. This means that you can have the same comics from different publishers. To do this, you want to have an object with an array that keeps a list of publishers.

Request

  • Method: POST
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
  • Response:
    • Status code: 201
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').post({
  "name": "Thorgal",
  "title": "Child of the Stars",
  "publishers": [
    {"publisher":"Le Lombard"},
    {"publisher":"Orbita"}
  ]
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
comic_obj.body

To make calls simpler and code cleaner, assign Id of returned object to a variable.

id = comic_obj.body.id;
id

Create an additional array record

In this example, you want to update your nested array object with an additional publisher. You must refer explicitly to an array name. It is the name of the attribute that contains an array. Optionally, you can use a PUT method on a necessary record in the array with a specific index. If the specified index does not exist, null values are added to ensure the given index. For example, if you specify an index of 3 and the array has less than three elements, null values are added.

Request

  • Method: POST
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}/{attributeName}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
      • dataId: The ID of an object.
      • attributeName: The name of an attribute.
  • Response:
    • Status code: 200
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).attributeName('publishers').post({
  'publisher' : 'Korona'
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
comic_obj.body

The new publisher is added at the end of the array.

Retrieve only specific array values

To verify that the new publisher is added, you must get that specific publisher in the response. You know it is the third publisher, so you need to refer to a specific array index.

Request

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}/{attributeName}/{index}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
      • dataId: The ID of an object.
      • attributeName: The name of an attribute.
      • index: The specific array index, such as 2.
  • Response:
    • Status code: 200
get_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).attributeName('publishers').index('2').get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
get_obj.body

Remove specific array values

You no longer need the first publisher, so you can delete it. Please note, that removing array values results in null value being inserted inside the array at a given position.

Request

  • Method: DELETE
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}/{attributeName}/{index}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
      • dataId: The ID of an object.
      • attributeName: The name of an attribute.
      • index: The specific array index, such as 0.
  • Response:
    • Status code: 204
remove = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).attributeName('publishers').index('0').delete(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})

Retrieve the entire object to verify that one record from the array is missing

Request

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
      • dataId: The ID of an object.
  • Response:
    • Status code: 200
get_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-type' : 'application/json'
  }
})
get_obj.body


Nested Attributes

Get all your variables in one place

The following variables are used within this tutorial:

tenant = {{projectId}};
client = {{clientName}};
AccessToken = {{token}};

Create API client for Document service

API.createClient('documentService',
'/services/document/v1/api.raml');

You can create documents with nested attributes using a schema or metadata.

Schema

There is a schema used in this tutorial. You can create schema based on this example and publish it in the Schema service or on a server of your choice:

Create a new document with nested attributes using a schema

Request

  • Method: POST
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
  • Headers:
    • Content-Language: en_US
  • Response:
    • Status code: 201
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').post({
  "name": "Thorgal",
  "original_release" : "1985-05-13T12:00:00.000Z",
  "title": "The Archers",
  "available": {
    "published": "1989-05-13T12:00:00.000Z",
    "title": "The Archers"
  },
  "metadata"   : {
    "schema": "https://api.us.yaas.io/hybris/schema/v1/framefrog/comicSchema_v2.json"
  }}, {
    headers: {
      'Authorization': 'Bearer ' + AccessToken,
      'Content-Type' : 'application/json',
      'Content-Language' : 'en_US'
    }
  })
  comic_obj.body

To make calls simpler and code cleaner, assign Id of returned object to a variable.

id = comic_obj.body.id;
id

Retrieve an object created with a schema

Request

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
      • dataId: The ID of an object.
  • Headers:
    • hybris-languages: *
  • Response:
    • Status code: 200
get_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-Type' : 'application/json',
    'hybris-languages' : '*'
  }
})
get_obj.body
The schema defines the fields title as localized by "$ref": "https://pattern.yaas.io/v2/schema-localized.json". In effect, all titles have the localized attribute set as in the Content-Language header or body of the request.

Create a new document with nested attributes using metadata

Request

  • Method: POST
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
  • Headers:
    • Content-Language: en_US
    • hybris-metaData: title:localized;available.title:localized;original_release:date;available.published:date
  • Response:
    • Status code: 201
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').post({
  "name": "Thorgal",
  "original_release": "1985-05-13T12:00:00.000Z",
  "title": "The Archers",
  "available": {
    "published": "1989-05-13T12:00:00.000Z",
    "title": "The Archers"
  }
},
{
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-Type' : 'application/json',
    'Content-Language' : 'en_US',
    'hybris-metaData' : 'title:localized;available.title:localized;original_release:date;available.published:date'
  }
})
comic_obj.body

To make calls simpler and code cleaner, assign Id of returned object to a variable.

id = comic_obj.body.id;
id

Retrieve an object created with a metadata

Request

  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
      • dataId: The ID of an object.
  • Headers:
    • hybris-languages: To retrieve your localized attributes in all stored language versions use * parameter.
  • Response:
    • Status code: 200
get_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-Type' : 'application/json',
    'hybris-languages' : '*'
  }
})
get_obj.body
To get the same effect with localized attributes, you must define title fields as localized in the hybris-metaData header: title:localized;available.title:localized


Operate on Mixins

Get all your variables in one place

The following variables are used within this tutorial:

tenant = {{projectId}};
client = {{clientName}};
AccessToken = {{token}};

Create API client for Document service

API.createClient('documentService',
'/services/document/v1/api.raml');

This tutorial explains how to provide additional product attributes using mixins.

Please be advised that while creating mixins for subdocuments special characters are not allowed, please see Best Practices. You can escape those signs by adding a logic to translate this fields into substitutes.

The tutorial is divided into two subsections:

  • The first example uses an existing schema that has been published on a server and placed in metadata.
  • The second example presents how to create a mixin with an inline schema.

The schema has priority over mixins when defining attributes. For example, if you define an attribute as a date in the schema and as localized in the mixin, the schema takes precedence, so the attribute is created as a date.

Schemas

There are two schemas used in this tutorial. You can create schemas based on these examples and publish them on a server of your choice or in the Schema service:

Use existing schemas

Create an object with a schema

Use a schema to create an object with localized title and am original_price of type amount.

Request
  • Method: POST
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
  • Headers:
    • Content-Language: Use this header to specify the language of the attribute value. Do not use this header if the body of your request contains a language map.
  • Response:
    • Status code: 201
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').post({
  "name": "Thorgal",
  "title": {
    "en": "The Archers",
    "fr": "Les Archers"
  },
  "original_price": {
    "usd": 19.99,
    "eur": 15.99
  },
  "metadata": {
    "schema" : "https://api.us.yaas.io/hybris/schema/v1/framefrog/comicSchema_v5.json"
  }}, {
    headers: {
      'Authorization': 'Bearer ' + AccessToken,
      'Content-Type' : 'application/json'
    }
  })

To make calls simpler and code cleaner, assign Id of returned object to a variable.

id = comic_obj.body.id;

Update an object with a simple mixin

Update an object by adding a simple mixin that defines the new field CollectorsValue of type amount.

Request
  • Method: PUT
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
      • dataId: The ID of an object.
  • Query Parameters:
    • partial: true
  • Response:
    • Status code: 200
documentService.tenant(tenant).client(client).data.type('comic').dataId(id).put({
  "mixins" : {
    "collectors_info" : {
      "CollectorsValue": {
        "usd": 30.99,
        "eur": 23.99
      }
    }
  },
  "metadata" : {
    "schema" : "https://api.us.yaas.io/hybris/schema/v1/framefrog/comicSchema_v5.json",
    "mixins" : {
      "collectors_info" : "https://api.us.yaas.io/hybris/schema/v1/framefrog/comicCollectorValue_v1.json"
    }
  }
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-Type' : 'application/json'
  },
  query:   {
    'partial' : 'true'
  }
})

Get an object with a simple mixin

When reading the object all the attributes will be returned according to their types defined in both schema and mixin.

Request
  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
      • dataId: The ID of an object.
  • Headers:
    • Accept-Language: fr
    • hybris-currencies: usd
  • Response:
    • Status code: 201
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Accept-Language' : 'fr',
    'hybris-currencies' : 'usd'
  }
})

Use an inline mixin

Create an object with a schema

Request
  • Method: POST
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}
  • URI parameters:
  • Required:
    • tenant: The project that requests this resource.
    • client: The ID of the client.
    • type: The type attribute of the document.
  • Headers:
  • Content-Language: Use this header to specify the language of the attribute value. Do not use this header if the body of your request contains a language map.
  • Response:
  • Status code: 201
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').post({
  "name": "Thorgal",
  "title": {
    "en": "The Archers",
    "fr": "Les Archers"
  },
  "original_price": {
    "usd": 19.99,
    "eur": 15.99
  },
  "metadata": {
    "schema" : "https://api.us.yaas.io/hybris/schema/v1/framefrog/comicSchema_v5.json"
  }}, {
    headers: {
      'Authorization': 'Bearer ' + AccessToken,
      'Content-Type' : 'application/json'
    }
  })

Update an object with an inline mixin

Request
  • Method: PUT
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
      • dataId: The ID of an object.
  • Query Parameters:
    • partial: true
  • Response:
    • Status code: 200
documentService.tenant(tenant).client(client).data.type('comic').dataId(id).put({
  "mixins":
  {
    "collectors_info":
    {
      "CollectorsValue": {
        "usd": 35.99,
        "eur": 26.99
      }
    }
  },
  "metadata":
  {
    "schema": "https://api.us.yaas.io/hybris/schema/v1/framefrog/comicSchema_v5.json",
    "mixins":
    {
      "collectors_info":
      {
        "$schema"   : "http://json-schema.org/draft-04/schema#",
        "type"      : "object",
        "properties":
        {
          "CollectorsValue"    :
          {
            "$ref": "https://api.us.yaas.io/hybris/schema/v1/framefrog/comicCollectorValue_v1.json"
          }
        }
      }
    }
  }
}, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Content-Type' : 'application/json'
  },
  query:   {
    'partial' : 'true'
  }
})

To make calls simpler and code cleaner, assign Id of returned object to a variable.

id = comic_obj.body.id;

Get an object with an inline mixin

When reading the object all the attributes will be returned according to their types defined in both schema and inline mixin.

Request
  • Method: GET
  • Request URL: https://api.beta.yaas.io/hybris/document/v1/{tenant}/{client}/data/{type}/{dataId}
  • URI parameters:
    • Required:
      • tenant: The project that requests this resource.
      • client: The ID of the client.
      • type: The type attribute of the document.
      • dataId: The ID of an object.
  • Headers:
    • Accept-Language: fr
    • hybris-currencies: usd
  • Response:
    • Status code: 201
comic_obj = documentService.tenant(tenant).client(client).data.type('comic').dataId(id).get(null, {
  headers: {
    'Authorization': 'Bearer ' + AccessToken,
    'Accept-Language' : 'fr',
    'hybris-currencies' : 'usd'
  }
})


Security

The Document service is a container for your Documents. You control the data stored in the Document service, and only you know whether the document contains personal data and which data subject the data relates to. Therefore, to meet the data privacy requirements you must map documents containing personal data with corresponding data subjects, and implement a logic to serve data subject's requests related to its personal data, such as requests for information or deletion. To meet these goals, follow instructions provided in the Developer Guidelines for Data Privacy.


Glossary

TermDescription
CRUDIt stands for basic operations: Create, Read, Update and Delete.
documentA data object created in a database that contains a set of information provided as a JSON schema when created. Identified by its ID.
ETag (entity tag)A header included in a GET response that contains a unique hash for the payload in order to validate the cache. This mechanism is used for cache validation by comparing two entities from the same requested resource.
indexA value that identifies the data item. Indexes locate data items within a data array or table, therefore using indexes improves search performance.
mixinA mixin is a simple schema that contains additional document attributes.
schemaA human- and machine-readable description of a JSON document expressed in terms of constraints on the fields and structure.
storageA dedicated hardware instance shared by the group of clients.
tagKeyword or term assigned to the document. You can use tags to describe documents for a better, more intuitive search experience.


  • Send feedback

    If you find any information that is unclear or incorrect, please let us know so that we can improve the Dev Portal content.

  • Get Help

    Use our private help channel. Receive updates over email and contact our specialists directly.

  • hybris Experts

    If you need more information about this topic, visit hybris Experts to post your own question and interact with our community and experts.