{"status":"success","message":"","http_code":200,"data":{"type":"message","id":"14321990","href":"/messages/14321990","view_href":"https://community.sap.com/t5/technology-blog-posts-by-sap/declarative-programming-in-cap-less-code-more-value/ba-p/14321990","author":{"type":"user","id":"41902","href":"/users/41902","view_href":"https://community.sap.com/t5/user/viewprofilepage/user-id/41902","login":"BirgitS"},"subject":"Declarative Programming in CAP: Less Code, More Value","body":"<H2 id=\"toc-hId-1789499361\"><SPAN>The Declarative Approach</SPAN></H2><P><SPAN>Ever found yourself writing repetitive validation handlers or debugging complex imperative code? Declarative programming in SAP Cloud Application Programming Model (CAP) offers a better way.&nbsp;</SPAN><SPAN>Declarative programming means describing what you want to achieve rather than how to achieve it. Instead of writing step-by-step instructions, you express the problem itself and let the system determine the solution automatically. </SPAN></P><P><SPAN>There are a couple of benefits using a declarative approach:</SPAN></P><UL><LI><SPAN>Improved Readability: Code that focuses on intent rather than implementing step-by-step instructions is clearer and easier to understand</SPAN></LI><LI><SPAN>Enhanced Maintainability: When rules live close to the data they govern, logic is easier to find and update</SPAN></LI><LI><SPAN>Reduced Boilerplate: Minimize repetitive code, streamline development, and reduce bug potential</SPAN></LI></UL><P><SPAN>In CAP, developers can declaratively define numerous CAP features - including queries and view definitions, input validations or annotation based constraints. The result? Less imperative code, consistent validations between backend and OData annotations, and logic that is intuitive to understand. This post walks you through the core concepts of declarative programming in CAP, covering declarative expressions, different kinds of input validations, how to use expressions as annotation values and the new @assert feature. These techniques work in both CAP Java and CAP Node.js.</SPAN></P><P><SPAN>&nbsp;</SPAN></P><H2 id=\"toc-hId-1592985856\"><SPAN>Declarative Programming in CAP: Core Concepts</SPAN></H2><H3 id=\"toc-hId-1525555070\"><SPAN>Declarative Expressions</SPAN></H3><P>With CAP, you can use declarative expressions in queries, view definitions, and calculated elements by defining them directly in your model. For example, you can use the <FONT face=\"courier new,courier\">exists</FONT> predicate to select only those authors whose associated books contain elements with a price greater than 20:</P><pre class=\"lia-code-sample language-markup\"><code>Select from Authors { name } where exists books[price &gt; 20.00]</code></pre><P><SPAN>In another example, you can use declarative expressions to compute free seats on a flight:</SPAN></P><pre class=\"lia-code-sample language-markup\"><code>entity Flights : cuid {\n  ...\n  max_seats : Integer;\n  occupied_seats : Integer;\n  free_seats : Integer = max_seats - occupied_seats;\n}</code></pre><P><SPAN>In all cases you can reduce the need for imperative code by using declarative expressions.</SPAN></P><P><SPAN>Please read our documentation for further information about <A href=\"https://cap.cloud.sap/docs/cds/cdl#views-projections\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">views and projections</A> and <A href=\"https://cap.cloud.sap/docs/cds/cdl#calculated-elements\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">calculated elements</A>. </SPAN></P><H3 id=\"toc-hId-1329041565\"><SPAN>Input Validations</SPAN></H3><P><SPAN>Instead of writing custom event handlers for every validation, CAP provides several built-in annotations that handle common scenarios declaratively. These validations are executed at the database layer, reducing round trips and enabling efficient error aggregation:</SPAN></P><UL><LI><STRONG><SPAN>@assert.format&nbsp;</SPAN></STRONG><SPAN>– validates that data matches regular expressions</SPAN></LI><LI><STRONG><SPAN>@assert.range&nbsp;</SPAN></STRONG><SPAN>– validates that data is within a given range</SPAN></LI><LI><STRONG><SPAN>@assert.target&nbsp;</SPAN></STRONG><SPAN>– validates that the target of an association exists</SPAN></LI><LI><STRONG><SPAN>@mandatory&nbsp;</SPAN></STRONG><SPAN>– validates that a value is provided</SPAN></LI><LI><SPAN><STRONG>@​readonly&nbsp;</STRONG>– ensures that a value is not modified</SPAN></LI><LI><SPAN>The<STRONG>&nbsp;.message&nbsp;</STRONG>suffix allows custom error messages instead of generic text</SPAN></LI></UL><P><SPAN>In the following example, you check that a description has a minimum length of 3 characters:</SPAN></P><pre class=\"lia-code-sample language-markup\"><code>Description @assert.format: '.{3,}'  @assert.format.message: 'Description too short’</code></pre><P><SPAN>In CAP, Core Data Services (CDS) is used to define service definitions, data models, queries, and expressions. Using declarative annotations in CDS models reduces custom logic while keeping validations consistent across services and UI.</SPAN></P><P><SPAN>Learn more about <A href=\"https://cap.cloud.sap/docs/java/event-handlers/\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">event handlers in CAP Java</A> and <A href=\"https://cap.cloud.sap/docs/node.js/core-services#srv-on-before-after\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">events in CAP Node.js</A> &nbsp;, read our documentation on <A href=\"https://cap.cloud.sap/docs/guides/services/constraints\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">declarative constraints</A> and check out DJ Adams’ blog post <A href=\"https://qmacro.org/blog/posts/2026/01/27/constraints-expressions-and-axioms-in-action/\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">Constraints, expressions and axioms in action</A>.</SPAN></P><H3 id=\"toc-hId-1132528060\"><SPAN>Expressions as Annotation Values</SPAN></H3><P><SPAN>Annotations can use CXL (CDS Expression Language) expressions as values. This is particularly useful for instance-based authorizations. The following code snippet ensures that users can only read, update, or delete orders they created:</SPAN></P><pre class=\"lia-code-sample language-markup\"><code>annotate Orders with @(restrict: [\n  { grant: ['READ', 'UPDATE', 'DELETE'], where: (createdBy = $user) }\n]);</code></pre><P><SPAN>Using parentheses ensures that the CDS compiler can validate and optimize the expression.</SPAN></P><P><SPAN>You can also use dynamic expressions in UI annotations. The compiler translates these expressions automatically to the corresponding OData annotations:</SPAN></P><pre class=\"lia-code-sample language-markup\"><code> @​UI.Hidden: (status &lt;&gt; 'visible')</code></pre><P>Learn more about <SPAN><A href=\"https://cap.cloud.sap/docs/cds/cdl#expressions-as-annotation-values\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">expressions as annotation values</A></SPAN>.</P><P>If you are interested to learn more about CXL check out this <SPAN><A href=\"https://qmacro.org/blog/posts/2025/12/09/a-new-hands-on-sap-dev-mini-series-on-the-core-expression-language-in-cds/\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">mini-series on CXL</A></SPAN> by our Developer Advocate DJ Adams and Patrice Bender.</P><H3 id=\"toc-hId-936014555\"><SPAN>The New&nbsp;@assert&nbsp;Annotation</SPAN></H3><P><SPAN>The&nbsp;<STRONG>@assert</STRONG>&nbsp;annotation is a new feature in CAP, released in December 2025. It enables complex, custom validations using CXL. This annotation provides a powerful way to enforce specific checks on inputs and raise appropriate errors if those checks fail. Error messages can be configured as either static strings or i18n message keys. </SPAN></P><P><SPAN>The annotation takes the form&nbsp;</SPAN><FONT face=\"courier new,courier\">@assert: (&lt;constraints&gt;)</FONT><SPAN>, where&nbsp;</SPAN><FONT face=\"courier new,courier\">&lt;constraints&gt;</FONT><SPAN>&nbsp;are standard SQL case expressions containing one or more&nbsp;'when'&nbsp;branches. The following example shows how to validate that a description is specified correctly:</SPAN></P><pre class=\"lia-code-sample language-markup\"><code>annotate TravelService.Travels with {\n  Description @assert: (case\n    when Description is null then 'Description must be specified'\n    when trim(Description) = '' then 'Description must not be empty'\n    when length(Description) &lt; 3 then 'Description too short'\n  end);                                                              \n}</code></pre><P><SPAN>It is also possible to formulate complex validations that would typically require a lot of code. The following example validates that the end date of a trip is not before the begin date and that all flight bookings fall within the travel period:</SPAN></P><pre class=\"lia-code-sample language-markup\"><code>EndDate @assert: (case\n when EndDate &lt; BeginDate then 'End Date must be after Begin Date'\n when exists Bookings [Flight.date &gt; Travel.EndDate] then 'All bookings must be within the travel period'\nend);</code></pre><P><SPAN>The new&nbsp;<A href=\"https://cap.cloud.sap/docs/guides/services/constraints#assert-constraint\" target=\"_blank\" rel=\"noopener nofollow noreferrer\"><STRONG>@assert</STRONG>&nbsp;feature</A> enables you to leverage the full potential of the CXL expression language while ensuring that validations are executed efficiently directly on the database. It integrates tightly with the Fiori user interface, providing rich error feedback and reducing the need for custom code. &nbsp;</SPAN></P><P><SPAN>&nbsp;</SPAN></P><H2 id=\"toc-hId-610418331\"><SPAN>Conclusion</SPAN></H2><P><SPAN>Embracing declarative programming in CAP can transform the way you develop cloud applications. By reducing the need for custom code, ensuring consistency, and facilitating the expression of business logic, you can efficiently create applications that are easy to maintain and intuitive. Whether you're new to CAP or a seasoned developer, consider exploring the benefits of declarative programming. Start by reading our <A href=\"https://cap.cloud.sap/docs/guides/domain-modeling#capture-intent-%E2%80%94-what-not-how\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">documentation</A>.</SPAN></P><P><SPAN>Happy coding!</SPAN></P>","teaser":"<P>This post walks you through the core concepts of declarative programming in CAP, covering declarative expressions, different kinds of input validations, how to use expressions as annotation values and the new @assert feature. These techniques work in both CAP Java and CAP Node.js.</P>","board":{"type":"board","id":"technology-blog-sap","href":"/boards/technology-blog-sap","view_href":"https://community.sap.com/t5/technology-blog-posts-by-sap/bg-p/technology-blog-sap"},"conversation":{"type":"conversation","id":"14321990","href":"/conversations/14321990","view_href":"https://community.sap.com/t5/technology-blog-posts-by-sap/declarative-programming-in-cap-less-code-more-value/ba-p/14321990","style":"blog","thread_style":"blog","messages_count":2,"solved":false,"last_post_time":"2026-02-05T17:49:26.936+01:00","last_post_time_friendly":"2026 Feb 05"},"topic":{"type":"message","id":"14321990","href":"/messages/14321990","view_href":"https://community.sap.com/t5/technology-blog-posts-by-sap/declarative-programming-in-cap-less-code-more-value/ba-p/14321990"},"post_time":"2026-02-05T15:03:43.143+01:00","post_time_friendly":"2026 Feb 05","depth":0,"read_only":false,"edit_frozen":false,"language":"EN","can_accept_solution":false,"placeholder":false,"is_solution":false,"solution_data":{},"metrics":{"type":"message_metrics","views":2650},"current_revision":{"type":"revision","id":"14321990_43","last_edit_author":{"type":"user","id":"41902","href":"/users/41902","view_href":"https://community.sap.com/t5/user/viewprofilepage/user-id/41902","login":"BirgitS"},"last_edit_time":"2026-02-05T14:59:56.688+01:00"},"kudos":{"query":"SELECT * FROM kudos WHERE message.id = '14321990'"},"tags":{"query":"SELECT * FROM tags WHERE messages.id = '14321990'"},"labels":{"query":"SELECT * FROM labels WHERE messages.id = '14321990'"},"images":{"query":"SELECT * FROM images WHERE messages.id = '14321990'"},"videos":{"query":"SELECT * FROM videos WHERE messages.id = '14321990'"},"attachments":{"query":"SELECT * FROM attachments WHERE message.id = '14321990'"},"replies":{"query":"SELECT * FROM messages WHERE parent.id = '14321990'"},"ratings":{"query":"SELECT * FROM ratings WHERE message.id = '14321990'"},"custom_tags":{"query":"SELECT * FROM custom_tags WHERE messages.id = '14321990'"},"moderation_status":"approved","visibility_scope":"public","user_context":{"type":"user_context","kudo":false,"read":false,"can_reply":false,"can_kudo":false,"can_delete":false},"message_type":"blog_topic_message","popularity":2.385461813015015E-5,"excluded_from_kudos_leaderboards":false,"latest_version":{"type":"friendly_version","major":"1","minor":"0"},"include_hidden_messages":true,"content_workflow":{"type":"content_workflow","state":"publish","message_draft_history":{"query":"SELECT * FROM message_draft_history WHERE message.id = '14321990'"},"user_context":{"type":"message_workflow_context","can_edit":false,"can_schedule":false},"view_href":"https://community.sap.com/t5/blogs/blogworkflowpage/blog-id/technology-blog-sap/article-id/188131"},"is_promoted":false},"metadata":{}}