July 2023
Welcome to the July 2023 release of CAP. Find the most noteworthy news and changes in the following sections.Better Documentation Search
The search function in Capire got several improvements that lead to more accurate results.
- Java or Node.js pages get prioritized in the result list depending on the language toggle. For example, results for Fiori draft now show either Java or Node.js pages, but not a mixture of both.
TIP
If you haven't set the toggle to Node.js or Java, you can do so now at the top of this page. This toggle applies to all pages, so you only need to set it once.
- You can use more search terms to refine your search. They're now combined with AND to allow this. Note that exact searches (with terms in quotes for example) aren't possible at the moment.
- Ambiguity got reduced. For example, cds watch doesn't find patch or batch anymore.
CDS Language & Compiler
Calculated Elements
We closed a gap in the implementation of calculated elements: a calculated element "on-read" can now refer to a localized element.
Example:
entity Product {
// ...
description : localized String;
descr_len : Integer = length(description);
}
Learn more about Calculated Elements.
Aspects Without Elements
If you define an aspect solely for the purpose of carrying annotations and you don't intend to add elements to it, you can now define it without an elements list, that is, without curly braces.
Example:
@restrict: [ /*...*/ ]
aspect AuthorizationAnnotations;
We plan to enable applying such aspects to services and other objects without elements in the coming releases.
Simplified Subqueries
Until now, each select item needed to have a name, even if it was inside a subquery and the name was never used. You can now omit these unnecessary aliases in most cases.
Before:
select from Products {
// …
} where price < (select from Orders { 0.7 * amount as foo} )
After:
select from Products {
// …
} where price < (select from Orders { 0.7 * amount } )
Node.js
After the major release in June, we have a smaller maintenance release in July. However, there are the two following noteworthy additions.
cds.Service.endpoints
(Beta)
The new property .endpoints
of a served cds.Service instance is an array containing the information for all endpoints.
Consider the service definition:
@protocol: ['odata-v4', 'rest']
@path: 'browse'
service CatalogService { ... }
This exposes services via OData and REST with the schema <prefix>/<path>
and therefore the following value for CatalogService.endpoints
:
[
{ kind: 'odata-v4', path: '/odata/v4/browse' },
{ kind: 'rest', path: '/rest/browse' }
]
See cds.protocols for more details on how to configure exposures.
@restrict
for Services
The Node.js runtime now supports @restrict
annotations on service level. As described in the authorization guide, the properties grant
and where
aren't applicable to services so it's ignored. Learn more about @restrict
.
Java
Important Changes ❗️
Changed Search Behaviour
To achieve stable search performance, the default search behaviour has been changed. Now, only elements of the type String that aren't computed are searched. This can lead to observable differences in the search results. Example:
entity Persons : cuid {
firstName : String;
lastName : String;
fullName : String = firstName || ' ' || lastName; // not searched by default
}
Here, only elements firstName
and lastName
will be in the scope of a search by default, but the element fullName
will not be included anymore.
TIP
If required, use the @cds.search annotation to include computed String elements.
Localized Data
CAP Java by default now leverages session context variables for localized and temporal data on all databases including H2. Consequently, the property cds.sql.supportedLocales
now defaults to an empty list indicating that session variables should be used.
WARNING
- H2 needs to be updated to v2.2.220 or later
- SQLite requires the compiler configuration
{"cdsc": { "betterSqliteSessionVariables": true }}
in .cdsrc.json
Spring Boot 3.1
CAP Java now supports Spring Boot 3.1.
Better PostgreSQL Config
To facilitate running CAP Java with PostgreSQL on BTP a new feature cds-feature-postgresql
is available. The feature auto-configures the service bindings for PostgreSQL on BTP. Find detailed information in the documentation.
Order by Alias
You may now use an alias of a select list item in Order By to sort by the corresponding items. This is useful if you need to sort by a complex expression:
Select.from("bookshop.Person")
.columns(p -> p.get("name").toUpper().as("aliasForName"))
.orderBy(p -> p.get("aliasForName").asc());
H2 Session Context Vars
The H2 dialect now uses session context variables for localized and temporal data. These features can now be used without restrictions.
WARNING
This feature requires cds-dk 7.1 (cds-compiler 4.1) and H2 v2.2.220 or later
Improved Maven Plugin
This release brings some improvements for the CDS Maven Plugin:
- The
watch
goal of the CDS Maven Plugin can now be executed from the root directory of the CAP Java application. - The new
add
goal allows you to add different features to the CAP Java project. Supported features areSQLITE
,H2
, andMTXS
.
Fine-Tuned @Generated Annotation
The generate
goal of the CDS Maven Plugin allows you to fine-tune the verbosity of the @Generated
annotation the generated java sources with the parameter annotationDetailLevel
. You can choose to include full information (FULL
), omit the generation timestamp (MINIMAL
), or suppress the @Generated
annotation (NONE
).
Native Executables beta
CAP Java now supports GraalVM Native Image, which enables you to compile a CAP Java application to a native executable. Native Image applications have faster startup times and require less memory.
Learn more about using GraalVM Native Image with CAP Java.
cds-typer: Enums, Arrays
We've added documentation for cds-typer
to Capire. It features a quick start guide and has detailed explanations on how to use the generated types.
The package has also gone open source and is available on npm and GitHub.
Feedback, bug reports, and contributions are welcome!
Now cds-typer
also supports the array of
/ many
syntax, as well as enums. For your convenience, the Enum values are available at runtime .
For Example, if this is your source:
namespace issuetracker;
type Priority: String enum {
LOW = 'Low';
MED = 'Medium';
HIGH = 'High';
}
entity Issues {
priority: Priority;
tags: array of String;
categories: many String;
}
The cds-typer will generate:
const Priority = {
LOW: "Low",
MED: "Medium",
HIGH: "High",
}
class Issue {
priority: Priority
tags: Array<string>
categories: Array<string>
}
Finally, this is how it can be used:
const { Priority, Issue } = require('#cds-models/issuetracker')
service.before('CREATE', Issue, ({data}) => {
data.priority = Priority.LOW
})