mcpField
G
generate-rap-service

generate-rap-service

github.com/arc-mcp开发239254 次安装2 天前更新
代码仓库

关于 generate-rap-service

generate-rap-service 根据业务对象的自然语言描述,为 SAP RAP 生成表、CDS 视图、行为定义和 OData UI 服务等完整构件栈,面向 SAP 开发工作。它采用托管场景等默认设置,并可按系统能力和约束调整生成流程。

主要功能

  1. 01从描述生成 RAP 构件栈
  2. 02创建表、CDS 视图和行为定义
  3. 03生成元数据扩展与服务绑定
  4. 04检测 SAP 系统能力与约束
  5. 05应用 SAP 命名和类型惯例

适用场景

  1. 01从业务需求构建 RAP 服务
  2. 02为 Fiori Elements 准备 OData UI 服务
  3. 03按 SAP 系统版本适配生成流程

MCP 相关

技能通过 ARC-1 访问 SAP 系统,并可结合 mcp-sap-docs 查询文档。若官方 abap-mcp 服务已连接,符合条件时也可委托其生成构件。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/arc-mcp/arc-1 --skill generate-rap-service

安装后在 Claude Code 中输入/generate-rap-service确认已加载。

详细介绍

生成 RAP OData UI 服务

根据业务对象的自然语言描述,生成完整的 RAP OData UI 服务。创建完整的构件栈:数据库表、CDS 视图、行为定义、元数据扩展、服务定义和行为池类。

此技能通过结合 ARC-1(SAP 系统访问)和 mcp-sap-docs(文档与最佳实践),复现 SAP Joule 的“RAP 服务生成”能力。

v1 防护措施(快速路径):仅限托管场景、UUID 内部提前编号、默认单个根实体、优先实现标准 CRUD,可选草稿,优先使用 OData V4。对于多实体组合或大量自定义操作,优先使用 generate-rap-service-researched。

智能默认值(静默应用,不要询问)

设置默认值理由
包用户的 Z* 包及传输请求可用于生产环境;仅在用户明确要求时使用 $TMP
键策略UUID(sysuuid_x16),托管编号最简单,无冲突风险
行为场景托管框架处理 CRUD
OData 版本V4当前 SAP 标准
草稿对事务型 Fiori Elements UI 服务优先启用;根据版本和约束验证是可编辑 FE 应用的最佳默认选择,但并非所有 RAP 服务都需要草稿
管理字段(本地部署)syuname/timestampl,或(BTP)abp_* 类型适用于相应系统
严格模式strict ( 2 ),除非系统模式或 SAP 约束要求其他设置当前 RAP 最佳实践,但并非通用要求
实体前缀Z + 实体名称(例如 ZTRAVEL)SAP 标准 Z 命名空间
命名SAP 标准:ZI_、ZC_、ZSD_、ZSB_、ZBP_I_与 SAP 文档保持一致
服务公开方式默认使用 OData V4 UI 提供程序契约最适合 Fiori Elements,除非用例以 API 为先

输入

用户提供业务对象的自然语言描述(例如,“一个包含代理机构、客户、目的地、开始/结束日期、总价、币种和状态字段的旅行预订应用”)。

只需提供业务对象描述。如果用户只提供描述,则应用智能默认值并立即继续。

用户也可以选择指定:

  • 实体名称前缀(默认:根据描述自动生成)
  • 包(必填——如果未提供则询问;仅当用户明确要求时才默认使用 $TMP)
  • 传输请求(仅非 $TMP 包需要——参见步骤 1b)
  • 是否启用草稿(默认:BTP 上启用,本地部署上不启用)
  • OData 版本(默认:V4)

步骤 1:检查系统功能

验证 SAP 系统是否支持 RAP/CDS,并检测系统类型。

SAPManage(action="probe")

如果需要更明确地确认语法和格式化程序行为的基准,也请读取:

SAPRead(type="SYSTEM")
SAPLint(action="list_rules")
SAPLint(action="get_formatter_settings")

**关键门槛:**如果探测明确报告 RAP/CDS 不可用,则停止并告知用户:在修复端点/系统设置之前,无法通过 ARC-1 创建 RAP 对象。

确定系统属于 BTP 还是本地部署——这会影响命名约定、语言版本和草稿处理。

步骤 1b:确定包和传输请求

如果用户未提供目标包,请询问。然后确定传输请求(仅当包为 $TMP 时跳过):

SAPTransport(action="check", objectType="DDLS", objectName="<first_object_name>", package="<package>")

此步骤会检查是否需要传输请求,并返回该包的现有传输请求。如果需要传输请求:

  1. 用户提供了传输请求:所有创建操作均使用该请求
  2. 找到现有传输请求:列出并请用户选择一个
  3. 没有可用的传输请求:创建一个:
    SAPTransport(action="create", description="RAP Service: <Entity>", package="<package>")
    

如果需要传输请求但无法获取,请停止——对于非 $TMP 包,没有有效的传输请求,所有写入操作都会失败。

如果包尚不存在,且用户想要新建一个,请先创建:

SAPManage(action="create_package", name="<package>", description="<description>", transport="<transport_if_required>")
BTP 与 On-Prem 的差异
方面BTP(ABAP Cloud)On-Prem(ABAP Platform)
命名空间仅限 Z*/Y*Z*/Y* 或客户命名空间
语言版本ABAP for Cloud Development(严格模式)Standard ABAP 或 ABAP for Cloud
草稿表必须显式创建(框架管理数据,而非表)必须显式创建
OData 版本优先使用 V4V2 或 V4
行为池ABSTRACT 类,仅限 ABAP CloudABSTRACT 类,允许使用经典 ABAP
表实体DEFINE TABLE ENTITY DDL 语法经典 DDIC 表(SE11)或表实体
On-Prem 7.5x 快速检查要点
  • 在 TABL 源代码中,使用 syuname + timestampl(而非 abap.uname / abap.utclong)。
  • 在 TABL 中,将 abap.char(1) 用于类似布尔值的标志(而非 abap.boolean)。
  • 每个 abap.curr(...) 字段上方都需要添加 @Semantics.amount.currencyCode。
  • 保持投影 BDEF 标头为 projection;(不要添加 use etag 标头行)。
  • 保持启用 RAP 预检(默认设置),以便在激活操作反复尝试前拦截确定性的 TABL/BDEF/DDLX 问题。仅将 preflightBeforeWrite=false 用作本地临时绕过方案。
  • 如果行为池完整类写入因通用保存错误而失败,先使用 SAPWrite(action="scaffold_rap_handlers", ...) 推导并应用签名,然后使用 quickfix 回退方案 + SAPWrite(action="edit_method") 编写方法主体。

第 2 步:设计数据模型

根据用户的描述,设计完整的制品栈。遵循 SAP 命名约定:

命名约定
制品模式示例
数据库表(表实体)Z<ENTITY>_DZTRAVEL_D
接口 CDS 视图ZI_<Entity>ZI_TRAVEL
投影 CDS 视图ZC_<Entity>ZC_TRAVEL
元数据扩展ZC_<Entity>ZC_TRAVEL
接口行为定义ZI_<Entity>ZI_TRAVEL
投影行为定义ZC_<Entity>ZC_TRAVEL
访问控制(DCL)ZI_<Entity>_DCLZI_TRAVEL_DCL
服务定义ZSD_<Entity>ZSD_TRAVEL
服务绑定ZSB_<Entity>_V4ZSB_TRAVEL_V4
行为池类ZBP_I_<Entity>ZBP_I_TRAVEL
草稿表(如果启用草稿)Z<ENTITY>_DDZTRAVEL_DD
字段设计规则

每个实体都包含以下标准字段:

字段类型用途
key_uuidsysuuid_x16UUID 主键(内部早期编号)
created_bysyuname / abp_creation_user管理:创建者
created_attimestampl / abp_creation_tstmpl管理:创建时间
last_changed_bysyuname / abp_locinst_lastchange_user管理:最后修改者
last_changed_attimestampl / abp_locinst_lastchange_tstmpl管理:最后修改时间(本地实例)
local_last_changed_attimestampl / abp_lastchange_tstmpl管理:总 ETag 字段

根据用户描述添加业务字段。选择适当的 ABAP 类型:

  • 文本:abap.char(N) 或 abap.sstring(N)
  • 金额:abap.curr(15,2),并配有货币代码字段(abap.cuky(5))
  • 日期:abap.dats
  • 状态:abap.char(1),使用固定值
  • 数量:abap.quan(13,3),并配有单位字段(abap.unit(3))
  • 整数:abap.int4
面向用户的输出

将完整设计以表格形式呈现:

Proposed artifact stack for "Travel Booking":

| # | Type | Name | Description |
|---|------|------|-------------|
| 1 | TABL | ZTRAVEL_D | Database table entity |
| 2 | DDLS | ZI_TRAVEL | Interface CDS view entity |
| 3 | DCLS | ZI_TRAVEL_DCL | CDS access control (authorization rules) |
| 4 | BDEF | ZI_TRAVEL | Interface behavior definition |
| 5 | DDLS | ZC_TRAVEL | Projection CDS view entity |
| 6 | BDEF | ZC_TRAVEL | Projection behavior definition |
| 7 | DDLX | ZC_TRAVEL | Metadata extension (UI annotations) |
| 8 | SRVD | ZSD_TRAVEL | Service definition |
| 9 | CLAS | ZBP_I_TRAVEL | Behavior pool class |
| 10 | SRVB | ZSB_TRAVEL_V4 | Service binding |

Fields: key_uuid, agency_id, customer_id, destination, begin_date, end_date,
        total_price, currency_code, status, created_by, created_at,
        last_changed_by, last_changed_at, local_last_changed_at

询问用户:“是否要按此设计继续?(是 / 修改字段 / 更改名称)”

第 3 步:(可选)研究 RAP 模式

如果 mcp-sap-docs 可用,获取最新的 RAP 最佳实践。先使用参考类查询(includeSamples=false),然后仅在需要时使用示例(includeSamples=true):

search(query="RAP projection BO vs RAP BO interface", includeSamples=false, abapFlavor="<cloud|standard>")
search(query="RAP draft handling total etag draft-enabled associations", includeSamples=false, abapFlavor="<cloud|standard>")
search(query="service definition provider contracts odata_v4_ui odata_v4_webapi", includeSamples=false, abapFlavor="<cloud|standard>")
search(query="metadata-driven UI metadata extension RAP Fiori Elements", includeSamples=false, abapFlavor="<cloud|standard>")

使用返回的文档,确保注解模式、草稿处理、提供方契约和行为定义语法正确。

步骤 3b:(可选)委托给 SAP 官方 ABAP 生成器构建

如果 SAP 官方 ABAP MCP 服务与 ARC-1 一起连接(它随 VS Code 的 ABAP Development Tools 提供,并在 Eclipse ADT 3.60+ 中启用,在那里显示为 abap-mcp 服务),你可以将单根构建交给 SAP 自己的 Generate ABAP Repository Objects 框架,并跳过步骤 4–13 中的手动模板。这是 可选项——下面的每个步骤都有 ARC-1 备选方案,而且该生成器仅适用于有限的结构。

仅在以下条件全部满足时使用该生成器(否则跳到下方的 批量创建):

  • 恰好 一个根实体——该生成器“最多生成一个实体”,不支持组合或层级结构。
  • 托管模式 + 草稿模式——这是它唯一能生成的模式。
  • 基表包含现代时间戳字段 last_changed : abp_lastchange_tstmpl 和 local_last_changed : abp_locinst_lastchange_tstmpl(生成器要求这些字段),或者使用 从头开始 的变体,由它为你生成表。
  • 你接受这是 一次性操作——“并非为生成后修改而设计”。重新运行不会扩展现有 BO;后续更改需手动完成(这正是 ARC-1 的职责)。
3b-1. 探测服务

如果没有名为 abap_generators-list_generators 的工具(即官方 abap-mcp 服务),则表示它未连接 → 跳到 批量创建。不要询问用户——直接静默回退。

3b-2. 确定生成器 ID(ID 因版本而异——切勿硬编码)

调用 abap_generators-list_generators,选择 显示名称为 "OData UI Service"(用于 Fiori UI 应用)或 "OData Web API Service"(用于无界面 API)的生成器,然后使用它返回的 id。ID 因版本而异——以下为实时验证结果:

版本UI 服务Web API 服务从头开始(也会生成表)
S/4HANA 2023 (SAP_BASIS 758)uiservicewebapiservice—
ABAP Platform 2025 (SAP_BASIS 816)ui-servicewebapi-servicex-ui-service

如果未列出匹配的生成器,则此版本没有该框架 → 跳到 批量创建。

3b-3. 读取输入架构

abap_generators-get_schema 需要五个输入,且如果没有真实引用表就会报错:

abap_generators-get_schema(
  generatorId          = "<id from 3b-2>",
  packageName          = "<target package>",       // your allowlisted package, or $TMP
  referencedObjectType = "TABL",
  referencedObjectName = "<existing base table>")

(从头开始的 x-ui-service 不需要引用表——请根据它返回的架构确认。)返回的架构中常见的配置项包括:软件包、数据模型(根实体名称 + EML 别名)、行为(草稿表名称)、服务投影名称、服务定义、服务绑定(OData 服务名称)、传输请求。读取实际架构并填写所有必填字段——不要假设本文档中的字段名称;它们因版本而异。

S/4HANA 2023(uiservice,引用表 ZARC1_DEMO_BOOK)上观察到的结构——已实时验证;你的情况可能不同,因此请读取实时响应:

dataModelEntity.cdsName  → ZR_ARC1_DEMO_BOOK      (root CDS)
implementationClass      → ZBP_ARC1_DEMO_BOOK     (behavior pool class)
draftTable               → ZARC1_DEMO_BOOKD
serviceProjection.name   → ZC_ARC1_DEMO_BOOK       (projection CDS, exposed by the service)
serviceDefinition.name   → ZUI_ARC1_DEMO_BOOK_O4
serviceBinding.name      → ZUI_ARC1_DEMO_BOOK_O4   (binding type: OData V4 - UI)
3b-4. 生成

abap_generators-generate_objects(generatorId="<id>", <filled schema>)。这是一次 变更操作——请遵循与任何 ARC-1 写入相同的防护措施(使用允许列表中的软件包 + 真实传输请求,或 $TMP)。一次调用会创建 CDS 根实体 + 投影、BDEF + 行为类、元数据扩展(DDLX)、草稿表、服务定义和服务绑定。

3b-5. 验证,然后继续使用 ARC-1

使用 ARC-1(SAPActivate、SAPRead)或官方 abap_activate_objects 激活并验证。使用 ARC-1 发布服务绑定——SAPActivate(action="publish_srvb", name="<binding>")——因为在 7.5x 上,生成器会创建并激活 SRVB,但其自身的发布步骤会返回 406(发布作业内容协商失败),导致其保持 published:false 且没有运行时 URL。ARC-1 的 publish_srvb 会处理 758 内容类型,并将其设为 published:true(已在 S/4HANA 2023 上实时验证:生成的绑定从未发布变为已发布,随后 $metadata 返回 HTTP 200)。然后,对于单实体、一次性生成器无法完成的任何操作,使用 ARC-1——添加字段、组合/子项、操作及处理程序代码(SAPWrite action="edit_method")、判定、验证,以及所有后续编辑。

说明你采用了哪条路径(“通过 abap-mcp <id> 生成基础 BO,再通过 ARC-1 扩展”或“完全通过 ARC-1 构建”),以便让运行过程可审计。

批量创建(推荐)

与其在步骤 4-13 中逐个创建构件,不如使用批量创建,通过一次工具调用创建所有 RAP 构件:

SAPWrite(action="batch_create", objects=[
  {type: "TABL", name: "<table_name>", description: "<Entity> Table", source: "<table_ddl>"},
  {type: "DDLS", name: "ZI_<entity>", description: "<Entity> Interface View", source: "<interface_view_ddl>"},
  {type: "DCLS", name: "ZI_<entity>_DCL", description: "<Entity> Access Control", source: "<interface_dcl_source>"},
  {type: "DDLS", name: "ZC_<entity>", description: "<Entity> Projection View", source: "<projection_view_ddl>"},
  {type: "BDEF", name: "ZI_<entity>", description: "<Entity> Interface Behavior", source: "<interface_bdef>"},
  {type: "BDEF", name: "ZC_<entity>", description: "<Entity> Projection Behavior", source: "<projection_bdef>"},
  {type: "DDLX", name: "ZC_<entity>", description: "<Entity> Metadata Extension", source: "<ddlx_source>"},
  {type: "SRVD", name: "ZSD_<entity>", description: "<Entity> Service Definition", source: "<srvd_source>"},
  {type: "CLAS", name: "ZBP_I_<entity>", description: "<Entity> Behavior Pool", source: "<class_source>"},
  {type: "SRVB", name: "ZSB_<entity>_V4", description: "<Entity> Service Binding", serviceDefinition: "ZSD_<entity>", bindingType: "ODataV4-UI"}
], package="<package>", transport="<transport>")

对象按数组顺序创建并激活——请将依赖项放在前面(表在 CDS 视图之前、DCLS 在 DDLS 之后、CDS 视图在 BDEF 之前、行为池在接口 BDEF 之前)。批次会在首次失败时停止,并报告哪些对象成功、哪些失败。

如果所有构件共用相同的程序包和传输请求,请在顶层设置 package 和 transport。如果某个批次项需要覆盖其中任一值,请在该对象上设置 package 和/或 transport;对象级值优先。

对于存在跨同级引用的对象组,请传入 activateAtEnd: true(例如,组合关联的 DDLS 中,父项的 composition [0..*] of ZR_CHILD 引用了同一批次中的子项)。ARC-1 会为每个对象写入非活动草稿,然后发出一次最终的 activateBatch——SAP 激活器会看到整个对象图,并在一次处理中解析跨对象引用。不使用此标志时,父项的内联激活会失败,并显示 "data source ZR_CHILD does not exist or is not active"。

如果批量创建失败,请退回到以下顺序创建方式(步骤 4-13)。

步骤 4:创建数据库表(顺序创建回退方案)

通过 CDS DDL 创建表实体。

SAPWrite(action="create", type="TABL", name="<table_name>", package="<package>", transport="<transport>", source="<ddl_source>")
表实体 DDL 模板
@EndUserText.label : '<Entity description>'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table <table_name> {
  key client            : abap.clnt not null;
  key key_uuid          : sysuuid_x16 not null;
  <business_field_1>    : <type>;
  <business_field_2>    : <type>;
  // ... more business fields
  created_by            : syuname;
  created_at            : timestampl;
  last_changed_by       : syuname;
  last_changed_at       : timestampl;
  local_last_changed_at : timestampl;
}

激活表:

SAPActivate(type="TABL", name="<table_name>")

回退方案:如果表实体创建失败(例如,在较旧的本地部署系统上),请指导用户通过 SE11 或 ADT 手动创建表,并提供字段列表和类型。

步骤 5:创建接口 CDS 视图

SAPWrite(action="create", type="DDLS", name="ZI_<entity>", package="<package>", transport="<transport>", source="<ddl_source>")
接口视图 DDL 模板
@AccessControl.authorizationCheck: #MANDATORY
@EndUserText.label: '<Entity description>'
define root view entity ZI_<Entity>
  as select from <table_name>
{
  key key_uuid              as KeyUuid,
      <business_field_1>    as <CamelCaseAlias1>,
      <business_field_2>    as <CamelCaseAlias2>,
      // ... more business fields

      @Semantics.amount.currencyCode: 'CurrencyCode'
      total_price            as TotalPrice,
      currency_code          as CurrencyCode,

      @Semantics.user.createdBy: true
      created_by             as CreatedBy,
      @Semantics.systemDateTime.createdAt: true
      created_at             as CreatedAt,
      @Semantics.user.localInstanceLastChangedBy: true
      last_changed_by        as LastChangedBy,
      @Semantics.systemDateTime.localInstanceLastChangedAt: true
      local_last_changed_at  as LocalLastChangedAt,
      @Semantics.systemDateTime.lastChangedAt: true
      last_changed_at        as LastChangedAt
}

激活:

SAPActivate(type="DDLS", name="ZI_<entity>")

步骤 5a:创建接口访问控制(DCLS)

为接口视图创建基本 CDS 访问控制角色。

SAPWrite(action="create", type="DCLS", name="ZI_<entity>_DCL", package="<package>", transport="<transport>", source="<dcl_source>")
接口 DCL 模板
@EndUserText.label: '<Entity description> Access Control'
@MappingRole: true
define role ZI_<Entity>_DCL {
  grant select on ZI_<Entity>
    where inheriting conditions from super;
}

激活:

SAPActivate(type="DCLS", name="ZI_<entity>_DCL")

步骤 5b:创建草稿表(启用草稿时)

如果启用了草稿,请先创建草稿表实体,再创建引用它的行为定义。RAP 框架会管理草稿数据在该表中的运行时持久化,但必须显式创建该表本身。

SAPWrite(action="create", type="TABL", name="<draft_table>", package="<package>", transport="<transport>", source="<ddl_source>")
草稿表实体 DDL 模板
@EndUserText.label : '<Entity description> - Draft'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table <draft_table> {
  key client            : abap.clnt not null;
  key key_uuid          : sysuuid_x16 not null;
  <business_field_1>    : <type>;
  <business_field_2>    : <type>;
  // ... same business fields as the main table
  created_by            : syuname;
  created_at            : timestampl;
  last_changed_by       : syuname;
  last_changed_at       : timestampl;
  local_last_changed_at : timestampl;
}

激活草稿表:

SAPActivate(type="TABL", name="<draft_table>")

注意:在 BTP ABAP Environment 上,仍必须显式创建草稿表——框架会在运行时管理草稿数据的持久化,而非表的存在。

步骤 6:创建接口行为定义

SAPWrite(action="create", type="BDEF", name="ZI_<entity>", package="<package>", transport="<transport>", source="<bdef_source>")
使用草稿
managed implementation in class ZBP_I_<Entity> unique;
strict ( 2 );
with draft;

define behavior for ZI_<Entity> alias <Entity>
persistent table <table_name>
draft table <draft_table>
etag master LocalLastChangedAt
lock master total etag LastChangedAt
authorization master ( instance )
{
  field ( readonly )
    KeyUuid,
    CreatedBy,
    CreatedAt,
    LastChangedBy,
    LastChangedAt,
    LocalLastChangedAt;

  field ( numbering : managed )
    KeyUuid;

  create;
  update;
  delete;

  draft action Resume;
  draft action Edit;
  draft action Activate optimized;
  draft action Discard;
  draft determine action Prepare;
}
不使用草稿
managed implementation in class ZBP_I_<Entity> unique;
strict ( 2 );

define behavior for ZI_<Entity> alias <Entity>
persistent table <table_name>
etag master LocalLastChangedAt
lock master
authorization master ( instance )
{
  field ( readonly )
    KeyUuid,
    CreatedBy,
    CreatedAt,
    LastChangedBy,
    LastChangedAt,
    LocalLastChangedAt;

  field ( numbering : managed )
    KeyUuid;

  create;
  update;
  delete;
}

请勿单独激活接口 BDEF——它引用尚不存在的行为池类(ZBP_I_)。创建类后,将在批量激活步骤中激活该定义。

步骤 7:创建投影 CDS 视图

SAPWrite(action="create", type="DDLS", name="ZC_<entity>", package="<package>", transport="<transport>", source="<ddl_source>")
投影视图 DDL 模板
@AccessControl.authorizationCheck: #MANDATORY
@EndUserText.label: '<Entity description> - Projection'
@Metadata.allowExtensions: true
@Search.searchable: true
define root view entity ZC_<Entity>
  provider contract transactional_query
  as projection on ZI_<Entity>
{
  key KeyUuid,

      @Search.defaultSearchElement: true
      <BusinessField1>,
      @Search.defaultSearchElement: true
      <BusinessField2>,
      // ... more business fields

      TotalPrice,
      CurrencyCode,

      CreatedBy,
      CreatedAt,
      LastChangedBy,
      LastChangedAt,
      LocalLastChangedAt
}

使用 @Search.defaultSearchElement: true 标记最重要的业务字段(通常是名称、ID 和描述)。

激活:

SAPActivate(type="DDLS", name="ZC_<entity>")

步骤 8:创建投影行为定义

SAPWrite(action="create", type="BDEF", name="ZC_<entity>", package="<package>", transport="<transport>", source="<bdef_source>")
带草稿
projection;
strict ( 2 );
use draft;

define behavior for ZC_<Entity> alias <Entity>
{
  use create;
  use update;
  use delete;

  use action Resume;
  use action Edit;
  use action Activate;
  use action Discard;
  use action Prepare;
}
不带草稿
projection;
strict ( 2 );

define behavior for ZC_<Entity> alias <Entity>
{
  use create;
  use update;
  use delete;
}

不要单独激活投影 BDEF——它使用 use create、use update、use delete,这些语句引用接口 BDEF(ZI_),而该 BDEF 尚未激活。所有构件创建完成后,它将在批量激活步骤中激活。

步骤 9:创建元数据扩展(DDLX)

SAPWrite(action="create", type="DDLX", name="ZC_<entity>", package="<package>", transport="<transport>", source="<ddlx_source>")
元数据扩展模板
@Metadata.layer: #CUSTOMER
@UI: {
  headerInfo: {
    typeName: '<Entity Name>',
    typeNamePlural: '<Entity Name Plural>',
    title: { type: #STANDARD, value: '<MainBusinessField>' },
    description: { type: #STANDARD, value: '<SecondaryField>' }
  }
}
annotate view ZC_<Entity> with
{
  @UI.facet: [
    {
      id: 'idIdentification',
      type: #IDENTIFICATION_REFERENCE,
      label: 'General Information',
      position: 10
    }
  ]

  @UI.hidden: true
  KeyUuid;

  @UI: {
    lineItem: [{ position: 10, importance: #HIGH }],
    identification: [{ position: 10 }],
    selectionField: [{ position: 10 }]
  }
  <BusinessField1>;

  @UI: {
    lineItem: [{ position: 20, importance: #HIGH }],
    identification: [{ position: 20 }],
    selectionField: [{ position: 20 }]
  }
  <BusinessField2>;

  // ... more business fields with incrementing positions

  @UI: {
    lineItem: [{ position: 50, importance: #MEDIUM }],
    identification: [{ position: 50 }]
  }
  TotalPrice;

  @UI.hidden: true
  CreatedBy;

  @UI.hidden: true
  CreatedAt;

  @UI.hidden: true
  LastChangedBy;

  @UI.hidden: true
  LastChangedAt;

  @UI.hidden: true
  LocalLastChangedAt;
}

位置编号:每次递增 10。为最相关的业务字段(在窄屏上显示)分配 importance: #HIGH,为次要字段分配 #MEDIUM。为用户可能要筛选的字段添加 @UI.selectionField。

激活:

SAPActivate(type="DDLX", name="ZC_<entity>")

步骤 10:创建服务定义

SAPWrite(action="create", type="SRVD", name="ZSD_<entity>", package="<package>", transport="<transport>", source="<srvd_source>")
服务定义模板
@EndUserText.label: '<Entity description> Service'
define service ZSD_<Entity>
  provider contracts odata_v4_ui
{
  expose ZC_<Entity> as <Entity>;
}

如果主要使用场景是 API/集成,而不是 Fiori Elements,请同时切换提供方契约和绑定类型:

define service ZSD_<Entity>
  provider contracts odata_v4_webapi
{
  expose ZC_<Entity> as <Entity>;
}

激活:

SAPActivate(type="SRVD", name="ZSD_<entity>")

步骤 11:创建行为池类

请在批量激活之前创建行为池类——接口 BDEF 通过 implementation in class ZBP_I_<Entity> 引用此类。

编写代码前,可选择运行 SAP PrettyPrinter,使类源代码符合系统的关键字样式和缩进规范:

SAPLint(action="format", source="<class_source>", name="ZBP_I_<entity>")
SAPWrite(action="create", type="CLAS", name="ZBP_I_<entity>", package="<package>", transport="<transport>", source="<class_source>")
行为池类模板
CLASS zbp_i_<entity> DEFINITION
  PUBLIC ABSTRACT FINAL
  FOR BEHAVIOR OF zi_<entity>.
ENDCLASS.

CLASS zbp_i_<entity> IMPLEMENTATION.
ENDCLASS.

激活:

SAPActivate(type="CLAS", name="ZBP_I_<entity>")

步骤 12:批量激活所有构件

首先,可选择检查是否有可能造成干扰的未激活对象:

SAPRead(type="INACTIVE_OBJECTS")

**注意:**在某些系统中,如果 /sap/bc/adt/activation/inactive 端点不可用,此检查可能会返回 404。如果是这样,请跳过此检查并继续。

一起激活所有构件,以解决跨对象依赖关系:

SAPActivate(objects=[
  {type:"TABL", name:"<table_name>"},
  {type:"DDLS", name:"ZI_<entity>"},
  {type:"DCLS", name:"ZI_<entity>_DCL"},
  {type:"CLAS", name:"ZBP_I_<entity>"},
  {type:"BDEF", name:"ZI_<entity>"},
  {type:"DDLS", name:"ZC_<entity>"},
  {type:"BDEF", name:"ZC_<entity>"},
  {type:"DDLX", name:"ZC_<entity>"},
  {type:"SRVD", name:"ZSD_<entity>"}
])

**注意:**激活会返回结构化响应,其中包含详细的错误/警告消息,包括行号和 URI。错误会阻止激活;警告不会阻止激活,但应予以检查。

如果批量激活失败,请按依赖顺序逐个激活:

  1. 表实体
  2. 接口 CDS 视图
  3. 接口访问控制(DCLS)
  4. 行为池类
  5. 接口行为定义
  6. 投影 CDS 视图
  7. 投影行为定义
  8. 元数据扩展
  9. 服务定义

如果由于缺少 METHODS ... FOR ... 签名导致行为池激活失败:

  • 使用 SAPWrite(action="scaffold_rap_handlers", type="CLAS", name="<bp_class>", bdefName="ZI_<entity>") 列出缺失的签名。
  • 如有需要,使用 autoApply=true 重新运行,以便将签名注入类声明并生成空方法桩。
  • 如果仍无法解析签名,并且有可用的建议,请使用 SAPDiagnose(action="quickfix", ...) 和 SAPDiagnose(action="apply_quickfix", ...)。
  • 如果以上方法均无效,请使用 ADT 编辑器生成快速修复,然后使用 SAPWrite(action="edit_method", ...) 修改方法体。

对于任何激活失败的对象,请运行语法检查以定位问题:

SAPRead(type="SYNTAX", objectType="<type>", name="<name>")

步骤 13:创建并发布服务绑定

创建服务绑定:

SAPWrite(action="create", type="SRVB", name="ZSB_<entity>_V4", package="<package>", transport="<transport>",
  serviceDefinition="ZSD_<entity>", bindingType="ODataV4-UI", description="<Entity> OData V4 Service")

激活服务绑定:

SAPActivate(type="SRVB", name="ZSB_<entity>_V4")

发布服务绑定(使 OData 服务可用):

SAPActivate(action="publish_srvb", name="ZSB_<entity>_V4")

检查发布状态和服务 URL:

SAPRead(type="SRVB", name="ZSB_<entity>_V4")

⚠️ 检查点:确认 SRVB 读取结果显示 published: true、预期的绑定类型和服务 URL。对于 OData V4 绑定,发布/取消发布操作作用于整个绑定。

步骤 14:验证完整服务

读取关键构件并运行最终检查:

SAPRead(type="DDLS", name="ZI_<entity>")
SAPRead(type="DCLS", name="ZI_<entity>_DCL")
SAPRead(type="BDEF", name="ZI_<entity>")
SAPRead(type="DDLS", name="ZC_<entity>")
SAPRead(type="SYNTAX", objectType="CLAS", name="ZBP_I_<entity>")

提供摘要检查清单:

RAP Service Generation Complete!

Created artifacts:
  [x] Database table entity: <table_name>
  [x] Interface CDS view: ZI_<Entity>
  [x] Interface access control: ZI_<Entity>_DCL
  [x] Interface behavior definition: ZI_<Entity>
  [x] Projection CDS view: ZC_<Entity>
  [x] Projection behavior definition: ZC_<Entity>
  [x] Metadata extension: ZC_<Entity>
  [x] Service definition: ZSD_<Entity>
  [x] Behavior pool class: ZBP_I_<Entity>
  [x] Service binding: ZSB_<Entity>_V4
  [x] Service binding published

Next steps:
  - Add validations and determinations (use generate-rap-logic skill)
  - Add value helps for business fields
  - Add custom actions if needed
  - Generate unit tests (use generate-abap-unit-test skill)
  - Register in FLP launchpad (use SAPManage flp_create_catalog, flp_create_tile, flp_create_group)
  - Create proper DOMA/DTEL for reusable typing (use SAPWrite with type=DOMA/DTEL)
  - Attach SKTD documentation to the service or BDEF (optional)
  - Review later iterations with `SAPTransport(action="history", type=…, name=…)` for current lock/assignment status plus `SAPRead(type="VERSIONS", ...)` for actual revision history

错误处理

常见问题与修复方法
错误原因修复方法
DDLS/BDEF 上出现 415 Unsupported Media TypeRAP/CDS 端点未按预期响应使用 SAPManage(action="probe") 检查系统信息。确认 ICF 服务已激活。尝试在 ADT 中创建对象,以确认系统功能是否可用。
创建时出现 Resource X does already exist对象已存在或与存根冲突改用 SAPWrite(action="update", ...) 并重新发送完整源代码。不要盲目重试创建。
激活错误:未找到依赖项对象激活顺序错误按依赖顺序依次激活(回退方案见步骤 12)
未找到草稿表尚未创建草稿表先创建草稿表实体,或从 BDEF 中移除 with draft
字段映射不完整BDEF 字段名与 CDS 别名不匹配确认 CDS 字段别名与 BDEF 字段引用完全一致
未找到 ETag 字段缺少 LocalLastChangedAt 或名称拼写错误确认 CDS 视图中存在管理字段,且别名正确
未找到行为池类名与 BDEF 的 implementation in class 不匹配确保 BDEF 中的类名与创建的类完全一致
创建/保存 BDEF 时出现通用错误 [?/011]对于 RAP 处理程序声明,行为池完整类的保存路径不稳定保持类定义精简,使用快速修复生成签名(MCP 或 ADT),然后使用 edit_method 编写方法体
Lint 阻止写入生成的代码存在 lint 警告检查 lint 发现的问题,调整代码模式以通过 lint 规则
不支持创建表实体本地旧版系统手动通过 SE11 创建表,并提供字段列表
需要传输请求非 $TMP 包未关联传输请求使用 SAPTransport(action="check") 查找或创建传输请求——参见步骤 1b
创建时发生锁冲突对象被其他用户/传输请求锁定等待或使用其他名称;使用 SAPTransport(action="list") 检查是否存在冲突的传输请求
缺少货币引用注解abap.curr 字段没有货币语义注解在每个金额字段上方添加 @Semantics.amount.currencyCode,并确保存在 abap.cuky 字段
预期为 "draft or side",而不是 "etag"7.5x 上的投影 BDEF 头部语法无效头部仅保留 projection;

说明

BTP 与本地部署系统概要
  • BTP:仅允许 Z*/Y* 命名空间,强制使用 ABAP Cloud 语法,必须显式创建草稿表(框架在运行时管理草稿数据),优先使用 V4 OData,BDEF 中使用 strict ( 2 ),采用表实体 DDL 语法,仅使用已发布的 SAP API。
  • 本地部署系统:命名空间限制较少,行为池中允许使用经典 ABAP(不推荐),可能需要显式创建草稿表,可使用 V2 或 V4,strict 级别取决于版本。
此技能不会执行的操作(v1)
  • 复杂组合/子层级结构:对于多实体 BO 和分两阶段推出,请使用 generate-rap-service-researched。
  • 自定义操作:除了草稿操作外,不声明 action。之后请使用 generate-rap-logic 技能。
  • 确定和验证:不包含业务逻辑。之后请使用 generate-rap-logic 技能添加这些内容。
  • 值帮助:不添加 @Consumption.valueHelpDefinition 注解。请手动添加。
  • 特性控制/副作用:除标准 CRUD 外,不添加由后端驱动的 UI 行为。当 UI 需要动态启用或重新计算提示时,请手动添加。
  • 非托管/抽象 BO:仅支持带 UUID 键的托管场景。
  • DOMA/DTEL 创建:使用内联类型。对于生产服务,请随后使用 SAPWrite(type="DOMA"/"DTEL") 创建合适的域和数据元素。
  • FLP 注册:不会自动注册到 Fiori Launchpad。之后请使用 SAPManage FLP 操作。
何时使用此技能
  • 从头开始创建新的 RAP 应用时
  • 用户用自然语言描述业务对象时
  • 快速搭建 Fiori Elements 应用原型时
  • 不适用于扩展现有 RAP 服务(请使用手动编辑或 generate-rap-logic)
  • 不适用于包含多个实体的复杂数据模型(v1 仅支持单个根实体)

评论

支持 Markdown