Contact Us 1-800-596-4880

Enhancing API Consumption and Minimizing Network Traffic

To reduce the amount of incoming network traffic and make APIs easier to consume, use the $expand system query option. Because API consumers request only inline representations of the related entities of query results, the returned information avoids multiple network roundtrips. Using this query option benefits metered and latency-sensitive consumers.

From APIkit for OData 1.3.0 onwards, this module supports automatic routing for ease of implementing the $expand system query option in the most common cases. Although this feature requires more preparation and configuration, it enables the reuse of implemented flows when processing the $expand requests.

See the OASIS specification for more information about the system query option.

Before You Begin

You must fulfill the following requirements to use the $expand feature:

  • APIkit for OData Module (version 1.3.0)

  • A <request-entity-collection-listener/> implementation for each expandable entity

  • Support for the in filter on the <request-entity-collection-listener/> flows

$expand Feature Example

In this example:

  • The Employee entity has a related Manager entity.

  • The Employees entity set is a collection of Employee entities.

  • The Managers entity set is a collection of Manager entities.

  • The API location is https://example.com/api/.

Given this setup, the following requests retrieve employees and their managers:

  • Use GET https://example.com/api/Employees to retrieve a list of employees.

  • Gather the Manager IDs through the ReferentialConstraint of their relationship.

  • Use GET https://example.com/api/Managers?$filter=ManagerID in (id1, id2, ..., idN) to retrieve a list of related managers.

  • Write a small program to merge the lists based on join criteria.

If you use the $expand feature, the request to retrieve a list of employees with their Manager navigation property expanded is GET https://example.com/api/Employees?$expand=Manager.

The generic expand Feature

Reuse existing flow implementations as a starting point for expanding requests by using the generic expand feature, which enables you to focus on the relevant data retrieval operations while the module performs the necessary steps to ensure that the $expand fields are complete.

An application with the generic expand feature enabled works like any other OData Mule application. However, during the flow execution, once the module retrieves information for the main entity set, it performs additional internal requests to gather the information for any expand field.

You can configure how the software handles errors during the expansion operation:

  • Fails the request with an error.

  • Replaces the failed expansion with a null value.

The generic expand Operation

The generic expand feature dispatches additional queries to the application when the original flow completes. Because this is done based on the application EDM, you must make extra annotations to add enough context to the module:

  • The EntitySet where the expansion takes place has a NavigationPropertyBinding for every expandable NavigationProperty of its Entity.

    This is used to select which <entity-collection-source/> is executed when expanding that property.

  • Each expandable NavigationProperty has a ReferentialConstraint attached.

    Internal requests use ReferentialConstraint when matching the value of Property against the value of ReferencedProperty.

Flow Execution

  1. The main flow is executed and completed resulting in a collection of entities.

  2. The OData module gathers all the properties that need expansion.

  3. For each NavigationProperty:

    1. Get the source property from its ReferentialConstraint.

    2. Get the referenced property from its ReferentialConstraint.

    3. Get the destination entity set from its NavigationPropertyBinding.

    4. For each of the entities get the resolved source property. Add these values to a source property list.

    5. Execute the internal request by invoking the <entity-collection-source/> for destination entity set with $filter=referenced property in (…​source property list).

Error Handling and Error Propagation

Error handling for OData v4 applications is local to each flow, whether you use generic expansion or not. Error handling code for a given EntitySet belongs to the flow implementations for that entity set, both for normal requests and for the internal requests observed during expansion processing.

Handling errors during the expansion process is not supported, because the expansion process runs after the execution of the flow finishes. There are two options available for handling errors:

  • Ignore errors during expansion: Errors during generic expansion are ignored.
    By default, the expansion of collections and single objects are resolved to empty lists and null values respectively.

  • Propagate errors during expansion: Errors arise during generic expansion.
    When an error reaches the OData v4 router, the original request is answered with an error response.

You can configure error handling per-source on the Capabilities tab.

Limitations

  • Only the first ReferentialConstraint is considered.

    Navigation properties that use compound keys are not supported.

  • Expansion is done field-by-field instead of EntitySet-by-EntitySet.

    This can cause more internal requests than necessary.

  • The expanded entities always have an <entity-collection-source/> implementation.

    Expansion using <entity-source/> implementations are not executed due to performance concerns.

Implementation Guidelines

To implement the generic expansion feature, you must annotate each source with the types that it can expand. Enabling $expand without restrictions enables API clients to write complex queries, which can create performance issues.

If you implement $expand manually for some relationships, leave these relationships out of the list on the Expandable Navigation Properties option. The navigation properties that don’t use the generic expansion feature need manual implementations in the flow.

Implementation Checklist

  1. Verify that your CSDL file and Mule application meet the expected requirements:

    • Every NavigationProperty has one ReferentialConstraint.

    • Every EntitySet has one NavigationPropertyBinding for each NavigationProperty of its entity type.

    • Every <entity-collection-source/> supports the in operator for the $filter system query option.

  2. For each source for which you enable generic expand support:

    1. Open the Capabilities tab.

    2. Edit inline the Expandable navigation properties field.

    3. Add the name of each navigation property to be expandable by using generic expand.

    4. Depending on your use case, select Ignore errors on expand to avoid errors during the generic expansion and to generate errors on the main flow.

  3. Verify that your existing flows support the $expand feature.