Table of Contents

Working With OData

In this article you will learn more on how to expose objects to the outside world with an open communication protocol like OData. Client applications like Microsoft Excel 2016 or higher are able to consume these objects real-time.

OData

The framework supports exposing objects to the outside world with the help of the OData protocol. OData is a REST-based protocol for querying and updating data and is built on standardized technologies such as HTTP, Atom/XML and JSON. It provides a uniform way to describe both the data and the data model so other client tools can take advantage of this. At this moment we only support OData version 4.

Before you can expose an object with the OData protocol, you must configure an object with at least one method.

OData is fully documented, please refer to the following articles:

Service Endpoints

A service endpoint is the url where the Ometa OData service can be accessed by a client application like Microsoft Excel. It is required to have at least one service endpoint. It is possible to expose multiple objects in one service endpoint.

Use the following steps to create a service endpoint:

  1. Click the application menu in the upper left corner.

  2. Hover over Master Data.

  3. Click Service Endpoints.

    Configure master data service endpoints

  4. Click Create in the ribbon.

  5. Specify url part of the new service endpoint.

  6. Click Save in the ribbon.

    Configure master data service endpoints

Exposing an Object

Use the following steps to expose the object:

  1. Go to the object you want to expose.
  2. Click the Service Endpoints tab.
  3. Check the Enable For Service Endpoints checkbox.
  4. Select the correct service endpoint.
  5. Configure the methods you want to expose.
  6. Click Save in the ribbon.

Configure service endpoint on object

Where to Find the OData URL

When an object is enabled to use the OData protocol, it is possible to navigate to a specific url. The url exists of three dynamic parts:

https://[server name or hostname]:[port]/odata/runtime/[service endpoint]

The server name or hostname is the name of the server where the Generic REST Service is installed. The port is the port number used by the Generic REST Service. The service endpoint is the name of the service endpoint configured earlier above.

This will be the response of a web browser when navigating to the url:

{
  "@odata.context":"https://ometa-rest.example.com/odata/runtime/Products/$metadata",
  "value":[
    {
        "name":"Product",
        "kind":"EntitySet",
        "url":"Product"
    }
  ]
}
Note

Security applies to service endpoints by default. Refer to security best practices article for more information on how to obtain an access token. If you wish to test the endpoint without security, configure the object as anonymous. However, make sure to restore this afterwards.

Use in Microsoft Excel

Some client applications like Microsoft Excel are able to consume OData feeds. The framework generates OData version 4 feeds. This means that the client application must support this version.

In Excel it is possible to consume the OData feed by following the next steps:

  1. Open Excel.
  2. Click the Data tab.
  3. Click the New Query button.
  4. Click the From Other Sources menu item.
  5. Click the From OData Feed menu item.
  6. Enter the URL, e.g.: http://ometa-rest.example.com/odata/runtime/[service%20endpoint]

Use OData in Excel

Requesting data

If you want to request the data, you must follow the conventions from the OData protocol.

Request all information:

https://[server name or hostname]:[port]/odata/runtime/[service endpoint]/[object name]

Using the equals filter:

https://[server name or hostname]:[port]/odata/runtime/[service endpoint]/[object name]?$filter=[field name] eq '[value]'

Keep in mind that using a filter does not set any input fields which match those filters. Filtering is done after the results have been fetched from the data system.

Supported OData Features

The following OData features are supported. Any other features are currently not implemented.

  • Requesting resources (Multi Get - GET)
    • An entire entity set can be requested. Any query options (like filtering, sorting, selecting, ...) are applied after the data has been fetched
  • Requesting an individual resource (Single Get - GET)
    • A single entity can be fetched by specifying the unique identifiers in the url following the OData conventions
  • Creating a new resource (Insert - POST).
    • An entity can be created by using the url of the entity set and posting the needed data following the OData conventions
  • Updating an existing resource (Update - PUT / PATCH).
    • An entity can be updated by using the url of that entity (the Single Get url) and posting the needed data following the OData conventions.
      • When using the PATCH verb, the single get method will be executed (and therefore must be enabled) and its results will be used to set the current entity data before setting the specified PATCH data on the update method.
  • Removing an existing resource (Delete - DELETE).
  • When applicable, the following query options can be used:
    • $filter
    • $orderby
    • $select
    • $skip
    • $top
  • When using the $filter option, the following filters can be used (depending on the field's type):
    • StartsWith
    • EndsWith
    • Contains
    • Eq
    • Neq
    • Gt
    • Geq
    • Lt
    • Leq
    • And / Or
  • OData normally doesn't support the usage of whitespaces in field names. Our framework however supports fields with whitespaces in their name. To be able to use these fields in query options, replace a whitespace character with 'x0020'.
    • Example:
      • https://[server name or hostname]:[port]/odata/runtime/[service endpoint]/[object name]?$filter=Postal_x0020_Code eq 'a value'

  • Custom query option |context.
    • When you want to set additional input fields on your methods, you can use the custom query option |context in this format.
      • https://[server name or hostname]:[port]/odata/runtime/[service endpoint]/[object name]?|context=YourInputField eq 'a value' and [Another input field] eq "another value".

      • Keep in mind that you have to specify the field values using the invariant culture when the field is a Number, DateTime, Boolean or anything other than a string.
  • Batch Requests using $batch.
    • Previously mentioned requests can be sent as one batch request. Each call within the batch is processed using the configuration on the service endpoint. Multiple calls to the same configuration within the batch are processed as context records.
    • $filter is not supported in batches.

Requests

Below are some examples of requests to the runtime service endpoint for the Product object created earlier. The Products service endpoint is used for all requests.

$metadata

https://[generic rest]/odata/runtime/Products/$metadata

Multi Get

The following request will retrieve the first 3 products.

https://[generic rest]/odata/runtime/Products/Product?$top=3

Multi Get With Query Options

The following request will retrieve all products with a rating greater than 3, ordered by the price.

https://rest.ometa.net:50601/odata/runtime/Products/Product?$filter=Rating gt 3&$orderby=Price

Single Get

The following request will retrieve the Product with ID 1.

https://[generic rest]/odata/runtime/Products/Product(1)

Insert

The following request will create a new Product.

https://[generic rest]/odata/runtime/Products/Product

Update (Patch)

The following request will replace fields passed in the body for Product with ID 5.

https://[generic rest]/odata/runtime/Products/Product(5)

Update (Put)

The following request will replace the contents of the Product with ID 7, with the passed body.

https://[generic rest]/odata/runtime/Products/Product(6)

Delete

The following request will delete the Product with ID 7.

https://[generic rest]/odata/runtime/Products/Product(7)

Batch

Below are a few examples of batch requests towards the generic REST service endpoint. All batch requests should approach the service through the $batch endpoint (https://[generic rest]/odata/runtime/Products/Product/$batch) with a POST request. The body of the request must then contain the individual requests.

Insert In Batch

The following request will create 2 new products within the same batch.

Request

POST https://rest.ometa.net:50601/odata/runtime/Products/$batch HTTP/1.1
Authorization: Bearer eyJhbGciO....f8z6Ew
Content-Type: multipart/mixed; boundary=batch_eeee3814-617f-4e06-a094-81e30bdd6ccf
Host: rest.ometa.net:50601
Content-Length: 1357

Request Body

--batch_eeee3814-617f-4e06-a094-81e30bdd6ccf
Content-Type: multipart/mixed; boundary=changeset_3542b1d1-ad9f-4d8e-a625-1b121c4b28c7

--changeset_3542b1d1-ad9f-4d8e-a625-1b121c4b28c7
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 1

POST https://rest.ometa.net:50601/odata/runtime/Products/Product HTTP/1.1
Content-ID: 1
Prefer: return=representation
OData-Version: 4.0
Content-Type: application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8

{"@odata.type":"#ns.Product","ID":40,"Name":"Apple","Description":"A pack of six apples.","Release Date":"2021-06-28T16:12:37.5987104+02:00","Rating":4,"Price":3.0}
--changeset_3542b1d1-ad9f-4d8e-a625-1b121c4b28c7
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 2

POST https://rest.ometa.net:50601/odata/runtime/Products/Product HTTP/1.1
Content-ID: 2
Prefer: return=representation
OData-Version: 4.0
Content-Type: application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8

{"@odata.type":"#ns.Product","ID":41,"Name":"Banana","Description":"ProductDescription2","Release Date":"2021-06-28T16:12:37.8967242+02:00","Rating":2,"Price":2.0}
--changeset_3542b1d1-ad9f-4d8e-a625-1b121c4b28c7--
--batch_eeee3814-617f-4e06-a094-81e30bdd6ccf--

Update In Batch

The following request will update the price of 2 products within 1 batch.

Request

POST https://rest.ometa.net:50601/odata/runtime/Products/$batch HTTP/1.1
Authorization: Bearer eyJhbGciO....f8z6Ew
Content-Type: multipart/mixed; boundary=batch_1609d7ba-93b9-48ad-abb9-37ba978ff192
Host: rest.ometa.net:50601
Content-Length: 1120

Request Body

--batch_1609d7ba-93b9-48ad-abb9-37ba978ff192
Content-Type: multipart/mixed; boundary=changeset_411776bc-36c2-44f2-82e1-422a01d7dfcb

--changeset_411776bc-36c2-44f2-82e1-422a01d7dfcb
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 1

PATCH https://rest.ometa.net:50601/odata/runtime/Products/Product(1) HTTP/1.1
Content-ID: 1
Prefer: return=representation
OData-Version: 4.0
Content-Type: application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8

{"@odata.type":"#ns.Product","Price":3.2}
--changeset_411776bc-36c2-44f2-82e1-422a01d7dfcb
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 2

PATCH https://rest.ometa.net:50601/odata/runtime/Products/Product(2) HTTP/1.1
Content-ID: 2
Prefer: return=representation
OData-Version: 4.0
Content-Type: application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8

{"@odata.type":"#ns.Product","Price":2.2}
--changeset_411776bc-36c2-44f2-82e1-422a01d7dfcb--
--batch_1609d7ba-93b9-48ad-abb9-37ba978ff192--

Delete In Batch

The following request will delete 2 products within 1 batch.

Request

POST https://rest.ometa.net:50601/odata/runtime/Products/$batch HTTP/1.1
Authorization: Bearer eyJhbGciO....f8z6Ew
Content-Type: multipart/mixed; boundary=batch_339280e5-22ab-4dff-8205-39a7d9d67486
Host: rest.ometa.net:50601
Content-Length: 680

Request Body

--batch_339280e5-22ab-4dff-8205-39a7d9d67486
Content-Type: multipart/mixed; boundary=changeset_0d93910f-8eea-4e32-bc5e-d065771cfe18

--changeset_0d93910f-8eea-4e32-bc5e-d065771cfe18
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 1

DELETE https://rest.ometa.net:50601/odata/runtime/Products/Product(1) HTTP/1.1


--changeset_0d93910f-8eea-4e32-bc5e-d065771cfe18
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 2

DELETE https://rest.ometa.net:50601/odata/runtime/Products/Product(2) HTTP/1.1


--changeset_0d93910f-8eea-4e32-bc5e-d065771cfe18--
--batch_339280e5-22ab-4dff-8205-39a7d9d67486--