Diferenças e Semelhanças entre CAP e RAP
Duas línguas da mesma família
Você abre um projeto CAP pela primeira vez e encontra isto:
using { cuid, managed } from '@sap/cds/common';
entity Books : cuid, managed {
title : localized String;
author : Association to Authors;
}Parece CDS. É CDS — mas não é o seu CDS. Cadê o define view entity as select from? Cadê a tabela transparente por baixo? O que são esses dois nomes depois dos dois-pontos? E localized na frente do tipo?
A confusão tem raiz histórica: ABAP CDS e o CDS do CAP são dialetos irmãos da mesma ideia (Core Data Services como linguagem declarativa de modelos), mas evoluíram para mundos com premissas diferentes. No ABAP, o CDS nasceu em cima de um dicionário de dados que já existia há 30 anos — toda view aponta para algo. No CAP, o CDS é a origem de tudo: das entidades nasce o schema do banco, o serviço OData e até a tipagem do código. Este post é o guia de tradução — o que muda, o que engana e o que o ABAPista ganha de graça do outro lado.
Primeiro, os nomes: CDS, CDL e CSN
No capire (a documentação oficial do CAP), CDS é o termo guarda-chuva. A linguagem legível que você escreve nos arquivos .cds chama-se CDL — Conceptual Definition Language, descrita como "um derivado conciso e mais expressivo do SQL DDL". E o que o compilador produz é CSN (Core Schema Notation): uma notação JSON dos modelos, consumida pelos runtimes.
E aqui vem o primeiro choque cultural: não existe ativação. Nada de DDIC, nada de "objeto ativo/inativo", nada de SE11. Você salva o arquivo, o cds watch recompila em memória e o servidor já serve o modelo novo. O cds compile --to csn mostra o resultado; o cds deploy gera o schema no banco. O ciclo editar-ativar-testar do ABAP vira editar-salvar-pronto.
A tabela de tradução
No ABAP CDS / DDIC | No CDL do CAP | A diferença que importa |
|---|---|---|
Tabela transparente (SE11/ADT) + view entity por cima |
| A entity É a persistência — o schema do banco é gerado dela; não há camada DDIC separada |
|
| Projeção existe, mas é a exceção (camada de serviço), não a regra |
Data element / domínio |
|
|
|
| Herança múltipla componível: |
Abstract entity (tipos, payloads) |
| ⚠️ |
Associação com |
| Sem on-condition: a foreign key é gerada automaticamente |
|
| Mesma semântica de documento; backlink via |
Metadata extension (arquivo separado de anotações) | Diretiva | Mesma filosofia de separar anotação de modelo — aqui, para qualquer coisa |
Extension include / BDEF extension | Diretiva | Qualquer um estende qualquer definição — inclusive as do |
DCL (access control) |
| Autorização declarada por anotação no modelo (e por default nada é autorizado!) |
Service definition + service binding |
| Uma construção da própria linguagem; os protocol adapters servem OData automaticamente |
|
| Vocabulários diferentes; |
Choque cultural nº 1: a entity é a tabela
No ABAP, o caminho é tabela → view básica → view de composição → projeção. No CAP, você declara a entity no domain model (por convenção, na pasta db/) e ela vira tabela no deploy — HANA, SQLite, PostgreSQL, tanto faz, o compilador gera o DDL de cada banco. A "camada de views" do VDM não existe como obrigação: o que existe é o service expondo projeções do domínio:
// db/schema.cds — o domínio (vira tabela)
namespace sapiente.bookshop;
using { cuid, managed } from '@sap/cds/common';
entity Books : cuid, managed {
title : String(111);
stock : Integer;
author : Association to Authors;
}
entity Authors : cuid {
name : String;
books : Association to many Books on books.author = $self;
}// srv/cat-service.cds — a camada de serviço (vira OData)
using { sapiente.bookshop as db } from '../db/schema';
service CatalogService {
@readonly entity Books as projection on db.Books;
}Traduzindo para o seu mapa mental RAP: o db/schema.cds faz o papel da tabela + interface view; o service faz o papel de projection + service definition + binding — três artefatos ABAP em uma construção, com o servidor OData de brinde.
Choque cultural nº 2: associação sem on-condition (e a FK que se materializa sozinha)
No ABAP CDS, toda associação carrega sua on-condition. No CAP, a managed association to-one dispensa isso: author : Association to Authors e pronto — o compilador gera a coluna de foreign key na tabela, com o nome <elemento>_<chave-do-alvo>. No exemplo, nasce a coluna author_ID em Books, sem você declarar campo nenhum.
A on-condition só aparece quando precisa — no backlink to-many: books : Association to many Books on books.author = $self. O $self é o "esta instância" do CDL, primo do $projection mental do ABAP, mas apontando para a entidade inteira.
O mesmo vale para os reuse types do pacote comum: declare country : Country num endereço e a tabela ganha a coluna country_code, com a code list de países (dados inclusos, via @sap/cds-common-content) e value help de graça.
Choque cultural nº 3: aspects — e o destino irônico da abstract entity
O : cuid, managed da primeira linha do post é o mecanismo mais idiomático do CDL: aspects, blocos de elementos e anotações que você mistura nas entidades como herança múltipla. Os dois mais usados vêm do @sap/cds/common e valem decorar:
// o que "cuid" e "managed" expandem por baixo dos panos:
entity Foo {
key ID : UUID; // cuid: chave canônica,
// preenchida automaticamente
createdAt : Timestamp @cds.on.insert : $now; // managed: os quatro
createdBy : User @cds.on.insert : $user; // campos de auditoria,
modifiedAt : Timestamp @cds.on.insert : $now // mantidos pelo runtime
@cds.on.update : $now; // sem uma linha de código
modifiedBy : User @cds.on.insert : $user
@cds.on.update : $user;
}É o papel que include e as views de interface fazem no ABAP — mas componível, extensível e com comportamento de runtime amarrado. A doc chama a filosofia de aspect-oriented modeling: separar as preocupações transversais (auditoria, chave, temporalidade) do domínio, inclusive em arquivos e pacotes diferentes.
A ironia da abstract entity: quem leu o guia de abstract entities do hub RAP sabe que lá ela é peça central (payloads, parâmetros). No CDS do CAP, abstract entity também existe — mas usar gera warning de deprecated. O motivo, segundo a própria doc: o recurso era usado majoritariamente para o anti-pattern da "super classe base", e foi descontinuado para empurrar todo mundo para aspects de reuso separados. Mesma palavra, destinos opostos nos dois mundos — não leve o hábito de um para o outro.
Choque cultural nº 4: localized — a text table que você não cria
Viu o title : localized String lá no começo? Esse qualificador dispara, na compilação, a geração de uma entidade .texts (com locale), as views de leitura com fallback de idioma e todo o encanamento de tradução — o equivalente ao par "tabela + text table + associação com @Semantics.text" que no ABAP você monta à mão. Uma palavra, o pacote inteiro. O mesmo espírito vale para o aspect temporal (dados com vigência/time slices, incluindo time travel) — anotou, ganhou.
Choque cultural nº 5: composition of aspects (o documento inline)
Para itens que só existem dentro do pai, o CDL tem um atalho que não existe no ABAP CDS: compor sobre um aspect anônimo, inline — sem criar a entidade filha explicitamente:
entity Projects : cuid {
title : String;
members : Composition of many { key user : Association to Users };
}Por baixo, o compilador gera a entidade de ligação (Projects.members, com o backlink up_) — é também o jeito recomendado de modelar many-to-many, que o CDS (dos dois mundos!) não suporta diretamente: duas one-to-many com uma link entity no meio.
Onde o mapa mental ABAP ajuda — e onde atrapalha
Ajuda | Atrapalha |
|---|---|
Entidade-relacionamento, composições, projeções, anotações como metadado — a gramática conceitual é a mesma | Procurar "a tabela por baixo da view" — não há; a entity é a origem |
Disciplina de camadas (domínio vs. consumo) — o CAP tem a mesma separação db/ vs. srv/ | Escrever on-condition em toda associação — managed association resolve to-one sozinha |
Separar anotações do modelo (metadata extension ≈ annotate em arquivo próprio) | Reusar |
Pensar em contrato: o service expõe o mínimo | Esperar ativação/transporte — o ciclo é save → watch → git |
Boas práticas (as que a própria doc crava)
Chave primária: simples, imutável, canônica. A doc recomenda o aspect
cuid(UUID único) — chaves compostas de vários campos degradam joins, e chave que muda quebra referências. Não interprete UUIDs, não use binário como chave.Capture intenção, não implementação. "What, not How":
localized,managed,temporaldeclaram o quê; os providers genéricos entregam o como.Aspects para preocupações transversais, em arquivos separados — não polua o domínio com dezenas de anotações de UI.
Evite delimited identifiers (
![Nome Com Espaço]) e caracteres não-ASCII — interoperabilidade agradece.Reuse o
@sap/cds/common(Country, Currency, Language, managed, cuid) em vez de reinventar — é interoperabilidade entre apps CAP e dados prontos via@sap/cds-common-content.KISS, citado literalmente pela doc: o modelo de domínio é um serviço aos consumidores dele, não um monumento do autor.
Perguntas frequentes
Cadê a SE11? Onde vejo "a tabela"?
Não há dicionário separado: a entity do db/ é compilada em DDL na hora do cds deploy (HANA em produção; SQLite em desenvolvimento, sem instalar nada). Quer ver o resultado? cds compile --to sql mostra o DDL gerado; --to csn mostra a representação interna.
Preciso "ativar" alguma coisa?
Não. O cds watch recompila e recarrega a cada save. O conceito de objeto inativo não existe — versionamento e transporte são papel do git e do pipeline de deploy.
Abstract entity existe no CAP?
Existe e está deprecated — usar gera warning. O caminho idiomático são aspects (para reuso estrutural) e types (para tipos nomeados, inclusive estruturados). O contraste com o RAP, onde a abstract entity é protagonista de payloads e parâmetros, é total: mesma palavra, papéis opostos.
Como faço many-to-many?
Como no ABAP: não há suporte direto; resolve-se com duas associações one-to-many e uma link entity — que no CAP pode ser gerada por você via composition of aspects inline, sem declarar a entidade do meio explicitamente.
O CDL vira ABAP CDS em algum momento? Os dois conversam?
Não há conversão — são linguagens de plataformas distintas. A conversa acontece nos protocolos: um app CAP consome o OData do S/4 (via cds import do EDMX) e escuta os eventos do RAP pelo Event Mesh — os dois caminhos já têm guia aqui no hub.
E o "managed" do CAP tem a ver com o managed do RAP?
Só o nome. No RAP, managed é o tipo de implementação do BO (framework provê buffer e persistência). No CAP, managed é um aspect de auditoria (created/modified by/at) e "managed association" é a associação sem on-condition com FK gerada. Três conceitos, uma palavra — cuidado nas conversas de arquitetura.
Conclusão
O CDS do CAP não é um ABAP CDS "portado" — é a mesma filosofia declarativa levada às últimas consequências num mundo sem dicionário legado: a entity gera a tabela, a associação gera a foreign key, o qualificador gera a text table, o aspect compõe o que o include nunca sonhou, e o service embrulha projeção, definição e binding numa construção só. Para o ABAPista, a curva não é aprender uma linguagem nova — é desaprender meia dúzia de reflexos. Feita essa tradução, o resto da trilha CAP (eventos, plugins, outbox) fica com a porta aberta.
Referências oficiais
Comentários 0
Ainda sem comentários
Seja o primeiro a comentar este artigo.
Entre na conversa
Faça login para deixar seu comentário neste artigo.