About CAP

The SAP Cloud Application Programming Model is a framework of languages, libraries, and tools for building enterprise-grade services and applications. It guides developers along a ‘golden path’ of proven best practices and a great wealth of out-of-the-box solutions to recurring tasks.

CAP-based projects benefit from a primary focus on domain. Instead of delving into overly technical disciplines, we focus on accelerated development and safeguarding investments in a world of rapidly changing cloud technologies.

Overview & Design Principles

The CAP framework features a mix of proven and broadly adopted open-source and SAP technologies, as highlighted in the figure below.

On top of open source technologies, CAP mainly adds:

  • Core Data Services (CDS) as our universal modeling language for both domain models and service definitions.

  • Service SDKs and runtimes for Node.js and Java, offering libraries to implement and consume services as well as generic provider implementations serving many requests automatically.

Agnostic Design Safeguarding Investments

Keeping pace with a rapidly changing world of cloud technologies and platforms is a major challenge when having to hardwire too many things to today’s technologies, which might soon become obsolete. CAP avoids such lock-ins through higher-level concepts and APIs, which abstract low-level platform features and protocols to a large extent. In particular, this applies to things like:

  • Platform-specific deployment approaches and techniques
  • Platform-specific identity providers and authentication strategies
  • On/Off-boarding of tenants in SaaS solutions and tenant isolation
  • Synchronous protocols like REST, OData, or GraphQL 1
  • Asynchronous channels and brokers like Enterprise Messaging, MQ, or Kafka 1
  • Different database technologies including SQL and NoSQL

These abstractions allows us to quickly adapt to new emerging technologies or platforms, without affecting application code, thus safeguarding your investments.

CAP is Open and Opinionated → Zero Lock-in

That might sound like a contradiction, but isn’t: While CAP certainly gives opinionated guidance, we do so without sacrificing openness and flexibility. At the end of the day, you stay in control of which tools or technologies to choose, or which architecture patterns to follow as depicted in the table below.

CAP is Opinionated in… CAP is Open as…
Higher-level concepts and APIs abstracting from and avoiding lock-ins to low-level platform features and protocols All abstractions follow a glass-box pattern that allows unrestricted access to lower-level things, if required
Best Practices served out-of-the-box with generic solutions for many recurring tasks You can always handle things your way in custom handlers, decide whether to adopt CQRS or Event Sourcing, for example … while CAP simply tries to get the tedious tasks out of your way.
Out-of-the-box support for
SAP Fiori and SAP HANA
You can also choose other UI technologies, like Vue.js, or databases, by providing new database integrations.
Dedicated tools support provided in SAP Business Application Studio, and Visual Studio Code or Eclipse. CAP doesn’t depend on those tools. Everything in CAP can be done using the @sap/cds-dk CLI and any editor or IDE of your choice.

Key Concepts & Paradigms

The following chapters highlight key concepts of CAP, which are based on two major paradigms: A declarative paradigm using CDS to capture knowledge about problem domains, and a service-centric paradigm, with ubiquitous notions of Services, Events, and Queries.

Focus on Domain, Powered by CDS

CAP places primary focus on domain, by capturing domain knowledge and intent instead of imperative coding — that means, What, not How — thereby promoting:

  • Close collaboration of developers and domain experts in domain modeling.
  • Out-of-the-box implementations for best practices and recurring tasks.
  • Platform-agnostic approach to avoid lock-ins, hence protecting investments.

The figure below illustrates the prevalent use of CDS models (in the left column), which fuel generic runtimes, like the CAP service runtimes or databases.

Anatomy of a Typical Application
Core Data Services (CDS)

CDS serves as our universal modeling language to capture static, as well as behavioral aspects of problem domains in conceptual, concise, and comprehensible ways, and hence is the very backbone of CAP.

Domain Models in CDS

Domain Models capture static aspects of problem domains as well-known entity-relationship models.

Associations capture relationships. Compositions extend that to easily model document structures.

Annotations allow you to semantically enrich models with use case-specific metadata, such as for UIs, Input Validation or Authorization.

CDS Aspects & Mixins

Aspects allow you to flexibly extend models in same or separate modules, packages, or projects; at design time or dynamically at runtime.

This greatly promotes [extensibility], verticalization, feature toggling, and separation of concerns.

The latter keeps domain models clean, and comprehensible, by factoring out technical concerns.

Dynamic Querying & Views

All data access in CAP is through dynamic queries, which allows clients to request the exact information that they really need. These powerful intrinsic querying capabilities are also key enablers for serving requests automatically as well as for dynamic extensibility.

In particular, the querying-based approach to process data is in strong contrast to Object-Relational Mapping (→ see also Related Concepts: CAP != ORM)

Core Query Language (CQL)

CQL is CDS’s advanced query language, which essentially enhances standard SQL with elements to easily query deeply nested object graphs and document structures. For example, here’s a query in CQL:

SELECT ID, from Employees

… and the same in plain SQL:

SELECT Employees.ID, FROM Employees
 LEFT JOIN Addresses ON Addresses.emp_ID=Employees.ID
 LEFT JOIN Countries AS Countries ON Addresses.country_ID = Countries.ID
Queries as first-order Objects (CQN)

Queries are first-order objects – using CQN as a plain object notation – sent to local services directly, to remote services thru protocols like OData or GraphQL1, or to database services, which translate them to native database queries for optimized execution with late materialization.

Projections at Design Time

We also use CQL in CDS to declare de-normalized views on the underlying domain model, such as in tailored service APIs.

Services & Events

All behavioral aspects in CAP are based on ubiquitous notions of Services and Events, as expressed in this manifest:

  1. All active things are Services — local ones, remote ones, as well as databases
  2. Services are declared in CDS — reflected and used in generic service providers
  3. Services provide uniform APIs — consumed by other services or frontends
  4. Services react on Events — covering synchronous and asynchronous APIs
  5. Services consume other Services — in event handler implementations
  6. All data is passive — that is, without its own behavior, adhering to REST

Services in CAP are stateless and with a minimal footprint, which allows you to modularize solutions into single-purposed (nano) services or functions-as-a-service.

Hexagonal Architecture à la CAP
Service Definitions in CDS

Services are declared in CDS models, used to serve requests automatically. They embody the behavioral aspects of a domain in terms of exposed entities, actions, and events.

Uniform Consumption

Every active thing in CAP is a service, including local services or remote ones — even databases are represented as services.

All services provide a uniform API for programmatic consumption. Thus, application code stays agnostic to underlying protocols.

Late-cut µ services — This protocol-agnostic API allows mocking remote services, as well as late changes to service topologies, for example, co-locating services in a single process or deploying them to separate micro services later on.

Ubiquitous Events

Everything in CAP happens in response to events. CAP features a ubiquitous notion of events, which represent both, requests coming in through synchronous APIs, as well as asynchronous event messages, thus blurring the line between both worlds.

We add custom logic in event handlers, registered to implement service operations. In the same way, we subscribe to asynchronous events emitted by other services.

Domain-level Eventing — Instead of talking to message brokers, services in CAP simply emit events on themselves, and consumers subscribe to events from services. Everything else is handled behind the scenes.

Generic Providers → Best Practices out-of-the-box

The CAP Service SDKs and runtimes in Node.js and Java provide several generic out-of-the-box implementations for best practices and recurring tasks, which greatly accelerate development, minimize boilerplate code and increase quality through single points to fix and optimize.

Following is an excerpt of generic features provided:

Automatically Serving Requests
Handling Recurring Tasks
Enterprise Best Practices

CAP-based applications also greatly benefit from the proven best practices we distilled from successful SAP applications, such as:

See also the Features Overview

Jumpstart & Grow-as-you-go

Following the principle of convention over configuration, there’s no need to set up things upfront. CAP allows you to jumpstart projects within seconds and have a team starting development right away, using generic providers, on top of a lightweight in-memory database → see Getting Started in a Nutshell.

CAP also offers mocks for many platform features, which allow fast dev-test-run cycles with minimal development environment complexity — aka Airplane Mode. Similarly, CAP greatly facilitates integration scenarios by simply importing an API from, say, an SAP S/4 backend or from SAP API Hub and running mocks for this locally.

Over time, you add things gradually, only when they’re needed. For example, you can move ahead to running your apps in close-to-productive setups for integration tests and delivery, without any change in models or code. → see Grow-as-you-Go.

Finally, projects are encouraged to parallelize workloads. For example, following a contracts-first approach, a service definition is all that is required to automatically run a full-fledged REST or OData service. So, projects could spawn two teams in parallel: one working on the frontend, while the other one works on the backend part. A third one could start setting up CI/CD and delivery in parallel.

See also…

1 GraphQL and Kafka aren’t supported out-of-the-box today, but might be added in future.