Search

October 2020

Welcome to the notes for the October 2020 release for the CAP framework. Find the most noteworthy news and changes in the following sections.

See also: Latest Changelog

Documentation

Authorization and Access Control

Cookbook > Authorization → greatly revised and improved

You can use the / key to show the search box. Hit the Escape key to hide it again.

The first search result is now focused, so that you can hit Enter to get to it. Use Tab to cycle through further search results.

New Sitemap

Our new sitemap page now shows you where things are on this site.

Command Line / Toolkit

sap/cds-dk Has Pinned Versions Again

To guarantee reproducible builds, @sap/cds-dk now comes with pinned dependencies again. This is in line with our general recommendations on managing dependencies.

Creation of Manifest Files for Native Cloud Foundry Deployment

You can now use cds add cf-manifest to create a Cloud Foundry manifest.yml file. In addition, a services-manifest.yaml is created which integrates with the Create-Service-Push plugin of the cf CLI. This plugin can create the listed Cloud Foundry services before the actual application deployment.

A typical workflow is:

# one time
cf install-plugin Create-Service-Push

# create the manifest and services-manifest
cds add cf-manifest
# ... adjust them to your needs

# finally deploy the app and create the services in one go
cf create-service-push

Unlike the manifest files generated by cds build in the gen folders, these new manifests are genuine sources that can be adjusted to your needs.
The current implementation supports single tenant Node.js and Java applications. You can edit the created files, for example, to fit multitenant applications.

CDS Editors & Tools

The following features are available for all editors based on our language server implementation for CDS in SAP Business Application Studio, Visual Studio Code, and Eclipse. The plugins are available for download for Visual Studio Code at Visual Studio Marketplace and for Eclipse at https://tools.hana.ondemand.com.

Welcome Page

Release notes page shows loading text while loading content.

A user setting cds.releaseNotes.showAutomatically to enable or disable automatic display of CAP Release Notes when a new version is available.

Support for Mono Repos

The editor now supports mono repos like CAP samples. Used components like @sap/cds/common can now be located above the workspace root.

Fiori/OData Annotation Support Enablement

Processing for Fiori/OData annotations takes some time for larger models. It can now be disabled through user setting cds.contributions.enablement.odata.

When enabled, there’s also an automatic detection for long running annotation support. It allows you to disable the annotation support temporarily. The detection can be disabled through user setting cds.contributions.enablement.longRunning.detect.

Node.js Runtime

Important Changes ❗️

  • On PATCH and PUT, an UPDATE event is followed by a CREATE event if there was no matching entity. Hence, on a single PATCH/PUT, custom handlers for UPDATE and CREATE may be invoked.

  • On PUT, entity properties that weren’t provided in the request payload nulled, or set to their default value, respectively.

Ignore Where Clause of View Definition During CREATE, UPDATE, and DELETE

If an entity based on a SELECT with a WHERE clause, this WHERE clause is ignored during CREATE, UPDATE, and DELETE events. In previous versions, an error was thrown if the entity was part of a remote service.

Request Lifecycle Events with Transactional Boundary

Request lifecycle events are emitted based on the transactional boundary of the respective request.

Support for Structured Types as Key in OData Services

The Node.js runtime now supports structured types as entity key, for example:

  entity E {
    key k {
      num: Integer;
      txt: String;
    }
    [...]
 }

InsertResult

On INSERT, DatabaseServices return an instance of InsertResult.

Miscellaneous

  • Support for CQN partials in SELECT.orderBy()
  • messages_<locale>.properties files are now looked for in all i18n folders
  • Service-level @requires are checked in protocol adapter (excluding metadata requests) instead of ApplicationService.
  • On CREATE and UPDATE, values for virtual properties returned by custom handlers are included in response payload.
  • Additional properties in request payload are preserved for entities with @cds.persistence.skip when served to rest.
  • New authentication kind xsuaa provides access to SAML attributes.
  • Default messaging kind local-messaging removed for development profile. As a result, no messaging service is started automatically on cds run, cds watch, etc., but needs to be configured explicitely.

Java Runtime

Important Changes ❗️

where conditions in @restrict annotations (instance-based authorization) are now validated. This could lead to the following error when using older @sap/cds versions in combination with the MTX sidecar:

No CXN expression found for where condition '​...' used for instance-based authorization of entity '​​...​​​​​'

Therefore, if you use multitenancy with MTX sidecar, please update the @sap/cds dependency in the package.json file of the MTX sidecar application to at least version 4.2.4!

  • You can now get a reflection object of an application service instance by means of the getDefinition() method:
com.sap.cds.reflect.CdsService cdsService = myService.getDefinition();

Please use this method in favor of looking up the reflection object by name in the CDS model, for example:

// Outdated!
com.sap.cds.reflect.CdsService cdsService = cdsModel.getService(myService.getName());

This way, your code stays invariant even when reconfiguring the name of CDS services by means of the application configuration.

SAP HANA-Specific Data Types

The SAP HANA-Specific Data Types TINYINT, SMALLINT, SMALLDECIMAL, REAL, CHAR, NCHAR, VARCHAR, CLOB, and BINARY are now supported by the runtime.

Default Values of View Parameters

The default values of parameterized views are now automatically set by the Java runtime.

Builder Methods for Standard Aggregate Functions

The Query Builder API now offers dedicated builder methods for the standard aggregate functions min, max, sum, average, and countDistinct. They’re available as static methods on the CQL helper class as well as postfix methods on the Value interface:

Select.from(ORDERS).columns(o -> o.amount().sum().as("total"));

or

import static com.sap.cds.ql.CQL.average;

Select.from(BOOKS).columns(o -> average(o.price()).as("averagePrice"));

Typed CQN Literals

Temporal and binary values are now serialized as CQN val nodes with a literal modifier:

CQL.literal(Instant.parse("2020-11-02")).toJson(); // { "val":"2020-11-02", "literal":"date" }

Cqn Analyzer - Extract non-key Filter Values

The CqnAnalyzer now also allows to extract non-key filter values from CQN statements:

--CQL query
SELECT from Books[year =  2000] where stock = 0
CqnSelect select = context.getCqn();
Map<String, Object> targetValues = cqnAnalyzer.analyze(select).targetValues();
Integer year = (Integer) targetValues.get("year");   // 2000
Integer stock = (Integer) targetValues.get("stock"); // 0

Cqn Modifier

In a SELECT from subquery, the CqnModifier now also allows modifying the inner queries.

Updatable Views

Path expressions navigating to to-one associations that are used in projections can now be resolved during insert and update operations. For example, the following view can be updated now:

view HeaderWithCountry as projection on bookshop.Header { 
    *, shippingAddress.country as shippingCountry };

OData V2 (Beta)

It’s now possible to configure the EDMX location for each OData adapter:

cds.odata-v2.edmx-path: ...
cds.odata-v4.edmx-path: ...

This way, it’s possible to run both protocol adapters at the same time, which enables migrating V2 services to V4 iteratively.

In addition, added support for nested expands in OData V2 (for example, Orders?$expand=items/book).

OData V4

Use the virtual property $count in the aggregate transformation of $apply to get the count of entities the input set.

CDS Features

The annotation @assert.notNull: false can now be used to skip server-side checks of elements marked with not null.

The length of string elements is now validated when running insert, update or upsert statements on the persistence service. In case the length is exceeded, an HTTP Bad request is returned.

Multitenancy

The multitenancy subscription API endpoints now return error responses with localizable error texts.