Grouping and Bundling
Quick Summary
ORD offers multiple ways how resources are grouped or bundled together. Some of them have a specific intended usage, while others offer the application providers complete freedom.
Predefined Grouping Concepts
- The Product is an optional high-level grouping concept for software portfolio structure.
- Packages and individual resources can be assigned to 0..n Products via
partOfProducts. - Products represent the portfolio and marketing view of a software offering — independent of technical concerns.
- Products can be arranged hierarchically (a Product can reference a
parentProduct).
- Packages and individual resources can be assigned to 0..n Products via
- The Package is the only mandatory bundling concept.
- Every ORD Resource MUST be assigned to exactly one Package.
- The concerns of a Package are:
- What is published together
- How the published information is presented on a catalog, e.g. in SAPs case the Business Accelerator Hub
- The Consumption Bundle
- API or Event Resources MAY be assigned to 0..n Consumption Bundles
- The concern is technical: What resources can be consumed together with the same set of credentials and auth mechanism
- The Entity Type may not be perceived as a grouping mechanism, but in practice it is very useful to group APIs, Events and other resources by a shared Business Object / Business Term.
- API Resources, Event Resources, Capabilities, Data Products and other Entity Types can be assigned to 0..n Entity Types.
Generic Grouping Concepts
- Tags (via the
tagsarray property) can be used to freely tag all kinds of ORD resources in Folksonomy style. - Labels are similar to tags, but they allow to also define the "key" and are mostly useful for simplifying querying / selecting resources on an API level.
- Groups allow to define custom Group Types that can be published via ORD as well.
- This concept is very flexible, but still well governed and machine-readable.
- It works similar to Packages or Consumption Bundles, but allows the ORD Provider to define their own group categories and their semantics.
Namespaces
While ORD IDs contain namespaces that can include optional sub-context namespaces, these should NOT be used for grouping purposes. Changing sub-context namespaces creates incompatible changes by altering ORD IDs. Use groups for grouping instead.
Sub-context namespaces should only be used if they are expected to be stable and are necessary to ensure conflict-free ORD IDs. A valid use case is enabling sub-teams to work independently with isolated, conflict-free sub-namespaces.
ORD Documents
ORD Documents are only used to transport ORD information to the aggregator and have no impact on grouping and bundling. However, there are still some Considerations on the granularity of ORD Documents.
Choosing the Right Concept
The following table summarizes all grouping options and helps decide which one to use:
| Concept | Level | Assignment | Key Question |
|---|---|---|---|
| Product | Portfolio | Package / resource → 0..n Products | What named software product or service offering does this belong to? |
| Package | Publishing | Every resource MUST have exactly one | What is published together and shown in a catalog? |
| Consumption Bundle | Technical access | API / Event → 0..n Bundles | What can be consumed with the same auth mechanism and credentials? |
| Entity Type | Semantic | API / Event / Data Product → 0..n Entity Types | What business object or domain concept does this relate to? |
| Group | Custom taxonomy | Any resource → 0..n Groups | Custom, governed grouping and taxonomy assignment beyond the predefined ORD concepts |
| Tags | Free tagging | Any resource → 0..n tags | Flexible keyword tagging for search and navigation |
| Labels | Key-value metadata | Any resource → 0..n labels | Structured metadata for programmatic querying and filtering |
Best Practices and Recommendations
- Avoid using namespaces for the purpose of grouping, if possible.
- For end-user-facing taxonomy, use groups rather than tags or labels. Tags and labels lack human-readable labels and are optimized for machine processing.
- Packages are less flexible for grouping than groups, so the latter are recommended and can be complementary. Use packages to group ORD resources published together and for information reuse.
Detailed Explanations
Product
A Product in ORD represents a software product or service offering (whether commercial or free). It is a high-level entity for structuring a software portfolio from a portfolio and software-logistics perspective. While the system type is a technical concept, a product covers the portfolio and marketing view — these concerns are intentionally kept separate.
The ORD concept of a Product is deliberately simple: there is no distinction between products and services, and concepts like product versions or variants are out of scope. ORD assumes that specialized systems handle those concerns; ORD only provides the means to correlate resources with them.
Products are assigned via the partOfProducts property on a Package or directly on individual resources.
Product assignments on a Package are inherited by all resources inside that Package.
Products can also be arranged hierarchically using the optional parent reference.
Typical use cases:
- Indicate which software product (e.g. SAP S/4HANA Cloud) a set of APIs belongs to.
- Express a product hierarchy (e.g. a sub-product that is part of a broader product family).
- Enable catalog tooling to filter, group or attribute resources by product.
ℹ Products are primarily useful for organizations with a large software portfolio where resources span multiple products. For single-product applications the concept can often be omitted.
Package
Every ORD Resource MUST be assigned to exactly one Package. The Package is primarily motivated by publishing and API catalog presentation concerns, including human-readable documentation and presentation. It can also express information about the resource providers, terms of use of the APIs, pricing for the usage of the packages, APIs, Events, etc.
Several Package properties — such as vendor, partOfProducts, tags, labels and policyLevel — are inherited by all resources within the Package. This makes the Package a convenient place to define shared metadata once, rather than repeating it on every resource.
The granularity of Packages is driven by all of the following concerns:
- The resources are created by the same vendor or customer, exposed by the same described system.
- The resources are published together. They share the same publishing ownership.
- The resources share certain aspects/taxonomy that is inherited down to them (e.g.
vendor). - If applicable: The resources are meant to be used by only a particular target platform / software.
When a package groups resources that are shared across multiple system types, the package itself SHOULD normally use the same owning namespace as the grouped resources. See Namespace Ownership for guidance on choosing the correct namespace.
All resources that are not created by the described systems vendor MUST be put into separate packages. This is the case, when:
- The resources are created by the customer (user) of the system.
All such resources MUST be assigned to a dedicated Package, where
vendoris set tocustomer:vendor:Customer:. - The resources are created by partners or third parties.
All such resources MUST be assigned to a dedicated Package for each partner / third party.
The
vendorMUST be set to a registered, matching Vendor ID (implies also a registered namespace).
ℹ At SAP, the Business Accelerator Hub defines how the Package concept is to be used to fit its publishing flow and Catalog UI/UX. See sap:core:v1 policy level for additional SAP specific constraints.
Consumption Bundle
The Consumption Bundle groups APIs and Events together that can be consumed with the same credentials and auth mechanism. Ideally it also includes instructions and details on how to request access and credentials for resources.
Important: A Consumption Bundle is a template that describes how to obtain access, not which credentials are already available. It provides instructions, not instances.
API and Event resources MAY be assigned to 0..n Consumption Bundles. Consumption Bundles are only applicable to APIs and Events where the described application itself manages the access and credentials.
All resources that are part of the same Consumption Bundle MUST theoretically be accessible through the same set of credentials. In practice however, there are usually more fine-grained access control permissions like RBAC that further restrict access based on user / client identity. Those are currently not described in ORD and the Consumption Bundle should therefore describe the "maximum possible scope" that is theoretically possible.
In the future, Consumption Bundles may provide more machine-readable information to help understand and automate the steps needed to get access.
For example, how credentials can be programmatically obtained could be described via credentialExchangeStrategies.
🚧 Please note that the Consumption Bundle concept is still in a rather basic form and may be extended in the future.
Entity Type
An Entity Type describes an underlying conceptual model (e.g. a business object / domain model). In special cases, the entity type could just be a term, describing the semantics but without an actual model behind it.
Entity Types are part of the ORD taxonomy and represent an "internal" concept. They should not leak internal implementation details, but can be used to relate external resources and capabilities to "business semantics".
Relationships to entity types can be assigned to API & Event resources, data products and other entity types:
Entity Types can serve two roles:
-
Conceptual models — they relate to internal application models that usually have structure (properties, behavior). Ideally (see DDD), they represent the ubiquitous language and have consistent semantics within the domain / bounded context. In other contexts, they might be called conceptual or logical (data) models or just internal models. Such models may have a lifecycle, so the ORD ID major version may be of relevance.
-
Business terms — they describe domain objects like a glossary of nouns that are consistently used. Such entity types usually have no lifecycle, and the ORD ID will have to set
v1as major version.
The same entity type can be related to one or multiple API and events resources, data products or other entity types. The entity type does NOT represent a consumer contract, but describes an internal artifact / concept within the described application. However, it's an important concept for the domain language and structure of the application and can be very useful to put other ORD concepts into relation with it.
⚠ Entity Types are not meant to provide a consumer contract! To get a clearly defined contract for working with entity types (getting data, triggering behavior), APIs and Events should be used.
Tags
Tags (via the tags array property) can be used to freely tag all kinds of ORD resources in Folksonomy style.
Tags defined on a Package are inherited by all resources it contains.
Please be aware that there is no global governance of tags and they also do not have namespaces. This will inevitably lead to inconsistent usage of tags. Since they are usually used for enhancing search or navigation, the simplicity of tags is often still a good trade-off.
For governed, human-readable categorization, prefer Groups over tags.
Labels
Labels are similar to Tags, but define key-value pairs instead of plain strings. They are optimized for machine-readability and can be used to query, select and filter resources programmatically (similar to Kubernetes labels). Labels defined on a Package are inherited by all resources it contains (duplicate keys are merged).
Groups
Groups and the corresponding Group Types can be used to define and apply your own taxonomy in a generic, extensible way.
The concept has three parts: The Group Type defines the semantics / meaning of a particular type of group assignments. An example would be to have a Group Type for a "part of a CDS Service" or "part of a Process".
Second, the Group itself defines the actual group things can be assigned to. In the examples before, this would be the "Employee Service" or the "Hire to Retire" Process.
Lastly, we need to state the partOfGroup assignment of a particular ORD Resource. E.g. a particular OData API for Employee Management can be part of both the "Employee Service" group (of type CSN Service) and the "Hire to Retire" group of type "Process".
The Group Type could even be defined globally. If the Group Type is shared across different applications, it should use the namespace of the owner that governs the taxonomy (see Namespace Ownership).
The Group Instances can potentially be globally defined, too. In this case it works like a global taxonomy with a predefined list of values and can use the system-independent perspective. It's also possible for the application itself to define and assign its own Group Types and Instances.
See Shared Taxonomy, Resources and Contracts for choosing between system-scoped and system-independent publication.
The Group concept is the correct choice when ORD resources need to be grouped by additional concerns, beyond the predefined concepts from ORD (like Package).
Examples
Bundling CAP APIs by CSN Service:
{
// Defines that there is a concept for grouping "CDS Service", owned by the sap.cds authority namespace
"groupTypes": [{
"groupTypeId": "sap.cds:service",
"title": "CAP CDS Service",
"description": "Description of the CDS Service concept and how its correctly used for grouping..."
}]
}
{
// Describes the actual CDS Service, as it was created in an application (of namespace "customer.bookshop")
"groups": [{
"groupId": "sap.cds:service:customer.bookshop:incidents.IncidentsService",
"groupTypeId": "sap.cds:service",
"title": "Incidents Service"
}]
}
{
"apiResources": [{
// Assignment of one API to the CSN Service it is derived from
"partOfGroups": [
"sap.cds:service:customer.incidents:incidents.IncidentsService"
]
}]
}