No todos los datos empresariales caben perfectamente en tablas planas. Los catálogos de productos, los organigramas y las estructuras de cuentas a menudo se basan en relaciones entre padres e hijos que los modelos de datos estándar no pueden representar bien.
Por ejemplo, en un escenario de venta minorista de comestibles, es posible que sea necesario agrupar los productos en varios niveles, como departamento, categoría, subcategoría y artículo, para que los usuarios comerciales puedan mantener estructuras de productos de manera consistente en una aplicación.
Esta es una buena opción para el Modelo de programación de aplicaciones ABAP RESTful (RAP), porque RAP proporciona una forma estructurada de modelar objetos comerciales transaccionales, definir composiciones padre-hijo, permitir el manejo de borradores, exponer servicios OData V4 y generar un SAP Fiori Experiencia de usuario basada en elementos con menos código personalizado.
Considere un artículo comestible común como «Gala Apple 1kg». El siguiente ejemplo muestra cómo se puede modelar y gestionar su jerarquía en el sistema.
|
Este tipo |
Este valor |
Padre |
Ruta de jerarquía calculada |
|
DEPARTAMENTO |
Alimento |
— |
Alimento |
|
GATO |
Productos frescos |
Alimento |
Alimentos → Productos frescos |
|
SUBCATE |
frutas |
Productos frescos |
Alimentos → Productos frescos → Frutas |
|
ARTÍCULO |
manzanas |
frutas |
Alimentos → Productos frescos → Frutas → Manzanas |
Debido a que cada nodo de jerarquía puede ser hijo de un nodo de nivel superior y padre de nodos de nivel inferior, el modelo es recursivo. Un modelo de datos planos estándar no puede representar esta estructura de forma eficaz. La solución requiere una tabla de autorreferencia y un marco que pueda gestionar de forma segura la complejidad transaccional de la edición de datos jerárquicos.
Esta publicación explicará cómo se puede aplicar RAP a este caso de uso de jerarquía de productos de una tienda de comestibles: un escenario práctico y con el que se puede identificar que demuestra los conceptos clave sin agregar complejidad innecesaria al dominio.
La aplicación que usaremos sigue la arquitectura estándar en capas RAP. Cada capa tiene una responsabilidad clara, lo que hace que la solución sea más fácil de mantener, probar y ampliar, al mismo tiempo que se alinea con los principios básicos limpios de SAP para el desarrollo personalizado.
|
Capa |
Artefacto |
Objetivo |
|
Persistencia |
ZPRODUCT_HDR ZPRODUCT_HIER |
Almacenamiento de bases de datos para productos y nodos de jerarquía. |
|
CDS básicos |
ZI_Product_B ZI_ProductHierarchy_B |
Alias de campos semánticos + cálculo de ruta de jerarquía |
|
Interfaz CDS |
ZI_Product_I ZI_ProductHierarchy_I |
Entidad raíz RAP + composición + asociaciones |
|
CDS de consumo |
ZC_Product ZC_ProductHierarchy |
Proyección preparada para SAP Fiori + redirecciones de asociación |
|
Definición de comportamiento. |
BDEF en ZI_Product_I |
CRUD, ciclo de vida del borrador, numeración gestionada |
|
Capa de servicio |
ZUI_PRODUCT_O4 (Def. + Encuadernación) |
Exposición de OData V4 para elementos de SAP Fiori |
|
Anotaciones de la interfaz de usuario |
MDE en ZC_Product MDE en ZC_ProductHierarchy |
Metadatos de diseño de elementos de SAP Fiori |
En RAP, las vistas CDS de la interfaz definen el límite del objeto comercial. Las vistas de CDS de consumo dan forma a los datos para la interfaz de usuario. La definición de comportamiento controla qué operaciones están permitidas y cómo se conservan los datos. Estas tres preocupaciones siempre se mantienen en artefactos separados.
La solución se basa en dos tablas de bases de datos. La tabla de encabezado de producto almacena el registro maestro del producto, mientras que la tabla de jerarquía almacena nodos de jerarquía con una clave externa autorreferenciada que establece la relación padre-hijo entre nodos.
Tenga en cuenta que los borradores de tablas (sufijo _D) para ambas tablas son generados automáticamente por el ABAP sistema cuando se activa la definición de comportamiento. No es necesario crearlos manualmente.
Las vistas CDS desempeñan un papel central en la definición de la estructura jerárquica. El siguiente ejemplo ilustra cómo se pueden modelar y gestionar eficazmente las jerarquías de productos.
Vistas de la interfaz RAP
Las vistas de interfaz definen la estructura del objeto comercial RAP. La entidad raíz declara la composición a la entidad secundaria, mientras que la entidad secundaria declara asociaciones inversas y autoasociaciones para la navegación principal e secundaria.
ZI_Product_I — Entidad raíz
define root view entity ZI_Product_I
as select from ZI_Product_B
composition [0..*] of ZI_ProductHierarchy_I as _Hierarchy
association [0..*] to ZI_Product_B as _ProductType
on $projection.ProductType = _ProductType.ProductType
{
key ProductID,
ProductName,
@ObjectModel.foreignKey.association: '_ProductType'
ProductType,
ProductImageUrl,
LastChangedAt,
LocalLastChangedAt,
_Hierarchy,
_ProductType
}
la composicion [0..*] La declaración convierte a ZI_ProductHierarchy_I en una entidad secundaria de esta raíz. Todos los nodos de jerarquía de un producto se gestionan como parte del mismo objeto comercial transaccional y comparten el mismo bloqueo.
ZI_ProductHierarchy_I — Entidad secundaria
La vista secundaria expone los datos del nodo de la jerarquía y declara tres asociaciones: una asociación principal con el producto raíz y dos autoasociaciones para la navegación hacia arriba (_Parent) y hacia abajo (_Children) dentro de la jerarquía.
define view entity ZI_ProductHierarchy_I
as select from ZI_ProductHierarchy_B
association to parent ZI_Product_I as _Product
on $projection.ProductID = _Product.ProductID
association [0..1] to ZI_ProductHierarchy_I as _Parent
on $projection.ParentHierID = _Parent.HierID
and $projection.ProductID = _Parent.ProductID
association [0..*] to ZI_ProductHierarchy_I as _Children
on $projection.HierID = _Children.ParentHierID
and $projection.ProductID = _Children.ProductID
{
key HierID,
ProductID,
ParentHierID,
HierType,
HierValue,
HierarchyPath,
LastChangedAt,
LocalLastChangedAt,
_Product,
_Parent,
_Children
}
Vistas de consumo
Las vistas de consumo se proyectan desde vistas de interfaz y redirigen asociaciones a sus contrapartes de consumo. Esto completa la cadena de composición de RAP y prepara las entidades para SAP Fiori.
ZC_Producto
@Metadata.allowExtensions: true
@UI.headerInfo: {
typeName: 'Product',
typeNamePlural: 'Products',
title: { value: 'ProductName' },
description: { value: 'ProductType' },
imageUrl: 'ProductImageUrl'
}
define root view entity ZC_Product
provider contract transactional_query
as projection on ZI_Product_I
{
key ProductID,
ProductName,
ProductType,
@Semantics.imageUrl: true
ProductImageUrl,
_Hierarchy : redirected to composition child ZC_ProductHierarchy
}
ZC_ProductHierarchy
@Metadata.allowExtensions: true
define view entity ZC_ProductHierarchy
as projection on ZI_ProductHierarchy_I
{
@ObjectModel.text.element: [ 'HierValue' ]
key HierID,
ProductID,
@ObjectModel.text.element: [ 'ParentHierValue' ]
ParentHierID,
_Parent.HierValue as ParentHierValue,
HierType,
HierValue,
HierarchyPath,
_Product : redirected to parent ZC_Product,
_Parent : redirected to ZC_ProductHierarchy,
_Children : redirected to ZC_ProductHierarchy
}
La definición de comportamiento especifica las capacidades transaccionales del objeto comercial RAP. Esta solución utiliza una implementación administrada con soporte para borradores. Las dos entidades (Producto como raíz y Nodo de jerarquía como hijo) desempeñan funciones diferentes y, por lo tanto, requieren diferentes configuraciones de comportamiento.
|
Aspecto |
Entidad de producto |
Entidad de jerarquía |
|
Entidad |
ZI_Producto_I (Producto) |
ZI_ProductHierarchy_I (nodo de jerarquía) |
|
Role |
Lock master: posee el borrador del ciclo de vida |
Dependiente del bloqueo: hereda el bloqueo del Producto |
|
Tabla persistente |
ZPRODUCT_HDR |
ZPRODUCT_HIER |
|
Borrador de tabla |
ZPRODUCT_HDR_D (generado automáticamente) |
ZPRODUCT_HIER_D (generado automáticamente) |
|
Operaciones |
crear, actualizar, eliminar |
actualizar, eliminar (crear mediante composición) |
|
Proyectos de acciones |
Editar, Reanudar, Preparar, Activar optimizado, Descartar |
Heredado de raíz; con borrador en _Producto |
|
Numeración de claves |
product_id — proporcionado por el usuario |
hier_id — administrado (UUID generado automáticamente por RAP) |
|
Asociación |
_Jerarquía { crear; con borrador; } |
_Producto, _Padres, _Niños |
|
Estrategia de bloqueo |
etiqueta total en LastChangedAt |
etiqueta maestra en LocalLastChangedAt |
Las decisiones de diseño más importantes en la definición de comportamiento son:
- Borrador con «Activar optimizado»: Reduce las operaciones de escritura en la base de datos durante el guardado mediante cambios por lotes. Recomendado para todas las nuevas implementaciones de borradores de RAP.
- asociación _Jerarquía { crear; con borrador; }: Permite crear nodos de jerarquía dentro de la misma sesión de edición del producto, haciendo que el producto y sus nodos de jerarquía sean una única operación atómica.
- campo (numeración: administrado) HierID: El marco genera automáticamente un UUID para cada nuevo nodo de jerarquía. Los usuarios nunca ven ni ingresan esta clave.
- bloqueo dependiente de _Producto: La entidad de jerarquía hereda su bloqueo de la raíz del producto. Sólo un editor puede modificar un producto y su jerarquía a la vez.
Las extensiones de definición de servicio y anotación de metadatos completan la pila de aplicaciones. La definición de servicio especifica qué entidades se exponen a través de OData V4, mientras que las extensiones de anotación definen cómo los elementos de SAP Fiori representan esas entidades en el informe de lista y la página de objetos.
A continuación se muestra un ejemplo de una página de lista:

Y aquí hay un ejemplo de una página de objeto:

Entidades de servicio (ZUI_PRODUCT_O4)
La definición del servicio expone cuatro entidades. Dos son transaccionales y dos sirven únicamente para fines de ayuda económica:
|
Entidad |
Role |
Objetivo |
|
ZC_Producto |
Transaccional (raíz) |
Principal punto de entrada para la aplicación SAP Fiori. Expone el informe de lista de productos y la página de objetos. |
|
ZC_ProductHierarchy |
Transaccional (niño) |
Expone nodos de jerarquía dentro de la página del objeto del producto a través de la asociación de composición. |
|
ZI_Producto_B |
Ayuda de valor |
Proporciona la ayuda de valor ProductType en los formularios de creación y edición de productos. |
|
ZI_ParentHierVH |
Ayuda de valor |
Proporciona la selección del nodo de la jerarquía principal, cuyo ámbito es ProductID para evitar asignaciones entre productos. |
Una práctica recomendada es exponer solo las entidades que la interfaz de usuario realmente necesita. La exposición innecesaria de entidades aumenta la superficie de ataque del servicio y puede degradar el rendimiento de los metadatos de OData en entornos grandes.
Patrones de anotación de la interfaz de usuario
Los archivos de extensión de metadatos aplican anotaciones de UI a las vistas de consumo sin modificar las vistas CDS mismas. La siguiente tabla muestra algunos ejemplos de anotaciones utilizadas en la aplicación.
|
Anotación |
Aplicado a |
Valor/Configuración |
Efecto en SAP Fiori Elements |
| @UI.faceta | Ambas vistas |
#IDENTIFICACIÓN_REFERENCIA #LINEITEM_REFERENCE |
Agrupa campos en secciones de página de objetos. |
| @UI.lineItem | Ambas vistas | posición: 10, 20, 30 | Controla qué campos aparecen como columnas en la tabla del informe de lista y en la tabla integrada de elementos de jerarquía. |
| @UI.selectionField | Ambas vistas | posición: 10, 20, 30 | Agrega campos a la barra de filtro encima del informe de lista. |
| @identificación UI | Ambas vistas | posición: 10, 20, 30 | Coloca campos en la sección Información general en la página del objeto. |
| @UI.textArrangement |
Tipo de producto ParentHierID |
#TEXT_ONLY | Oculta el valor de la clave sin formato y muestra solo el texto descriptivo en el campo de la interfaz de usuario. |
| @Consumo.valorAyudaDefinición |
Tipo de producto ParentHierID |
ZI_Producto_B ZI_ParentHierVH |
Muestra un cuadro de diálogo de ayuda para entradas del campo. La ayuda de la jerarquía principal utiliza enlaces adicionales para alcanzar el alcance por ID de producto. |
| @UI.oculta | PadreHierValue | verdadero | Mantiene el campo de texto derivado invisible en la interfaz de usuario mientras aún está disponible para la resolución de texto a través de @ObjectModel.text.element. |
| @Semántica.imageUrl | URL de imagen del producto | Indica a los elementos de SAP Fiori que representen el valor del campo como una URL de imagen y muestren la miniatura de la imagen en la lista. |
Los siguientes puntos resaltan los aspectos más importantes de esta solución.
- Las jerarquías recursivas sólo necesitan una tabla. Una única clave externa autorreferenciada (parent_hier_id → hier_id) es suficiente para modelar una profundidad ilimitada. La capa CDS maneja el cálculo de rutas; no se necesitan tablas adicionales.
- CDS une automáticamente rutas de cálculo de forma declarativa. Se pueden recorrer hasta cuatro niveles ancestrales utilizando autouniones externas izquierdas y expresiones CASE/CONCAT en una vista CDS base. No se necesita ningún código ABAP para el cálculo de la ruta.
- Las vistas CDS están organizadas en tres capas. Las vistas base proporcionan el modelo semántico y los campos calculados, las vistas de interfaz definen el objeto de negocio RAP y las vistas de consumo dan forma a los datos de SAP Fiori. Cada capa tiene una responsabilidad claramente definida.
- El RAP administrado con borrador elimina el texto repetitivo personalizado. El bloqueo, las tablas de borrador, la activación y el descarte se gestionan mediante el marco. El desarrollador declara su intención en la definición de comportamiento; el marco lo ejecuta.
- La composición hace que las jerarquías sean transaccionales. Declarar una composición entre el Producto y el Nodo de jerarquía significa que todos los cambios en ambas entidades se confirman o revierten juntos en una acción de Activar.
- Las extensiones de metadatos mantienen la interfaz de usuario y el modelo de datos separados. Los archivos de anotaciones pueden evolucionar de forma independiente, transportarse por separado y ajustarse a diferentes escenarios de interfaz de usuario sin tocar las vistas CDS.
Esta publicación se publicó originalmente el 7/2026.
