---
versions:
  cdsjs: 5.3.2
  cdsdk: 4.3.3
  cdsc: 2.4.4
  cdsmtx: 2.1.2
  java: 1.17.0

---
# July 2021

<ReleaseBadges />

[[toc]]

<span id="afterstarttop" />

<span id="beforetypescript" />

## On-the-fly TypeScript with `cds-ts`

Use the `cds-ts` CLI command instead of `cds` to avoid having to precompile TypeScript files to JavaScript each time and speed up development.

```sh
cds-ts serve world.cds
```

```sh
cds-ts watch
```

[Learn more about using TypeScript.](/@external/node.js/typescript){ .learn-more}

## Swagger UI Made Easier

For Node.js apps, less code is now needed to serve [exported OpenAPI definitions](/@external/guides/protocols/openapi) in Swagger UI.  Just install the new [`cds-swagger-ui-express`](https://www.npmjs.com/package/cds-swagger-ui-express) package:

```sh
npm add --save-dev cds-swagger-ui-express
```

And add a [`server.js`](/@external/node.js/cds-server#custom-server-js) file:

```js
const cds = require ('@sap/cds')
module.exports = cds.server

if (process.env.NODE_ENV !== 'production') {
  const cds_swagger = require ('cds-swagger-ui-express')
  cds.on ('bootstrap', app => app.use (cds_swagger()) )
}
```

Follow the _Open API preview_ links on the index page and see your API definitions in action:
![Swagger UI](assets/july21/cds-swagger-ui.png){ style="margin:5px auto;width:75%"}

[Learn more about OpenAPI publishing.](/@external/guides/protocols/openapi){ .learn-more}

## New CAP/SAP Fiori Sample

SFLIGHT is a new sample app for the travel reference scenario, built with CAP and SAP Fiori elements.

The purpose of this sample app is to demonstrate SAP Fiori annotations, compare SAP Fiori features on various stacks (CAP Node.js, CAP Java SDK, ABAP) and run UI test suites on various stacks.

Currently the app is only available for the CAP Node.js runtime. A version for CAP Java SDK will follow soon.

![SFLIGHT App](assets/july21/sflight.png)

[Try out the **SFLIGHT app**.](https://github.com/SAP-samples/cap-sflight){ .learn-more}


## Command Line / Toolkit { #cds-dk}

### Best Guess for Unknown Commands

The command line interface (CLI) of `@sap/cds-dk` offers you a best guess in case a command can't be found or if your input is ambiguous, for example, due to a typing mistake.

The following screenshot shows `cds` output for the unknown command **logu**.

![CDS message for unknown command](./assets/july21/cds_unknown_cmd.png)

### Importer Improvements

##### OData V4 Support

In much the same way as with OData v2, `cds import` now supports input documents for OData V4.

##### Preserved Documentation

If your imported EDMX documents contain tags like `<Documentation><Summary>`, `<LongDescription>` (OData V2), or `Core.Description/LongDescription` annotations (OData V4), these are now preserved in the resulting _.csn_ file.

To carry this documentation over to your provided services, generate EDMX files with the respective `Core.Description` annotations:

```sh
cds compile --to edmx --docs
```

## CDS Editors Speedup

> The following applies to CDS editors in SAP Business Application Studio and Visual Studio Code.

More and more users create models with hundreds of files. With this release, we introduce some settings to improve the editor performance and also changed some defaults.
Notable settings:

| Setting                                     | Description                      |
|---------------------------------------------|----------------------------------|
| _Cds: Workspace Validation Mode_          | New default: _OpenEditorsOnly_ |
| _Cds > Workspace: ScanCsn_                | New setting. Default: _off_    |
| _Cds > Quickfix: ImportArtifact_          | New setting. Default: _off_    |
| _Cds > Contributions > Enablement: Odata_ | New setting. Default: _on_     |

Best performance is achieved with default CDS settings, except for the last one in the list above &rarr; Switch it _off_ to speed up compilation, if you can do without Editor support for Fiori annotations.

Additionally, you may want to adjust some non-CDS settings to further increase performance:

| Setting                                                  | Description                                                                |
|----------------------------------------------------------|----------------------------------------------------------------------------|
| _Editor > Goto Location: Alternative Definition Command_ | Don't use _goToReferences_ to avoid unnecessary recompilations.          |
| _Workbench > Editor > Limit: Value_                      | Limit the number of recompilations in related editors (`using` statements) |
| _Workbench > Editor > Limit: Enabled_                    | Enable the _Limit: Value_ setting.                                       |

## CDS Language & Compiler { #cds}

### Dynamic Expressions in SAP Fiori Annotations

In particular, when writing annotations for SAP Fiori UIs, you may want to make use of
dynamic expressions in annotation values. They are evaluated in the front end and can,
for example, be used to avoid status mapping in the backend.

Provide an expression in the _EDM JSON representation_, like:

```cds
@UI.Hidden: {$edmJson: {$If: [{$Eq: [{$Path: 'status'}, 'visible']}, false, true]}}
```

and the compiler will translate it to the corresponding XML:

```xml
<Annotation Term="UI.Hidden">
  <If>
    <Eq>
      <Path>status</Path>
      <String>visible</String>
    </Eq>
    <Bool>false</Bool>
    <Bool>true</Bool>
  </If>
</Annotation>
```

[Learn more about Dynamic Expressions.](/@external/guides/protocols/odata#dynamic-expressions){ .learn-more}

### Define Views with the Exists Predicate

Use the [Exists Predicate](/@external/cds/cql#exists-predicate) with path expressions and infix filters as a simplified way to define
views with correlated _exists_ subqueries:

```sql
SELECT from Authors where exists books[year=2000]
```

unfolds to:

```sql
SELECT name FROM Authors AS a WHERE EXISTS (
  SELECT 1 FROM Books AS b WHERE b.author_id = a.id AND b.year = 2000
)
```

[Learn more about the Exists Predicate in CQL.](/@external/cds/cql#exists-predicate){ .learn-more}

## Node.js Runtime { #cds-js}

<!--// TODO: can we somehow make this only appear in external docs? We have enough beef for internal notes (cf. all the beta stuff)... or do we want to make some of it "external beta", i.e., "<topic> <Beta />"?-->
This release focuses on quality and incremental steps towards larger feature packages.

### Merged Runtime Packages ❗️ { #changes-in-nodejs .important }

We merged the former package `@sap/cds-runtime` into `@sap/cds`.

As `@sap/cds-runtime` was always an internal package, this should not affect you.
Yet, if, for any reason, you had `@sap/cds-runtime` in your list of dependencies, you should remove it.

### Important Changes ❗️ { #changes-in-node-js .important }

> The following changes affect undocumented internal implementations, and hence **shouldn't** affect CAP-based projects. Nevertheless, they're listed here for your reference.

- Cascade delete order reverted from leaves to root &rarr; Fixes an issue in cascading delete where a child entity has more than one parent, for example, Books and Restaurants both have a composition of many Reviews

- Always use flag `u` during input validation via `@assert.format`

### Kibana-Ready Logging Out of the Box <Beta />

We now provide a Kibana-friendly log formatter to use with [cds.log()](/@external/node.js/cds-log). Currently, the formatter must be activated via `cds.env.features.kibana_formatter = true` (additional to `NODE_ENV === 'production'`), but it will become the default in the future.
::: tip
Note that the formatter is in beta state and feedback is welcome!
:::

<span id="beforeodatareturn" />

### OData Return Formats

The Node.js runtime now supports the prefer header `return` with values `minimal` and `representation`. The default value for the server is configurable at `cds.env.odata.prefer.return`. If not configured, the default is `representation`.

Further, annotation `@Core.ContentDisposition.Filename` is now supported. See
[Serving Media Data](/@external/guides/services/media-data) for more details.

## Java SDK { #cds-java}

### Important Changes ❗️ { .important #important-changes-in-java}

#### Spring Boot 2.5 Support

- Update the CAP Java SDK to version 1.17.0 if you want to use Spring Boot 2.5. This Spring Boot version came with [incompatible changes](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.5-Release-Notes) that were adopted by the CAP Java SDK.
- Note that CAP Java 1.17.0 now _requires_ Spring Boot 2.5. Therefore, please update your Spring Boot dependency if you adopt this CAP Java version!

### Enhanced Media Streaming Support

You can now use the [@Core.ContentDisposition.Filename](/@external/guides/services/media-data) annotation to enable web browsers to handle the media data as an attachment download.

### Enhanced Remote Service Consumption

You can now use aliases in projections you define on entities used in [remote OData queries](/@external/java/cqn-services/remote-services), for example:

```cds
entity Addresses as projection on external.A_BusinessPartnerAddress {
  key AddressID as ID,
  key BusinessPartner as businessPartner,
  CityName as city,
  StreetName as street,
  HouseNumber as houseNumber
}
```

These projections can then be used to retrieve data from a Remote Service:

```java
bupa.run(Select.from("Addresses")).stream().map(a -> a.get("city"));
```

In addition, the `IN` operator is now supported in remote OData queries. In OData V2, which doesn't natively support `IN` the query is transformed into multiple comparisons concatenated by `OR`.

### Alter Single Entity Properties

You can read and modify a property of an entity directly by sending `GET`, `POST`, `PUT`, and `DELETE` requests to the properties URL, for example `POST .../odata/v4/Person/name`. Primitive and complex collections are also supported.

### Reliable Implicit Sorting

[Implicit Sorting](/@external/guides/services/served-ootb#implicit-sorting) now works reliably when aggregation functions are used in queries. Also, queries that don't use a limit (top/skip, for example when [Implicit Pagination](/@external/guides/services/served-ootb#implicit-pagination) is disabled) are not implicitly sorted anymore to improve performance.

### Improved Development Turnaround Times

The [CDS Maven Plugin](/@external/java/developing-applications/building#cds-maven-plugin) helps improving development roundtrips:

<div id="afterimproveddevelopmentturnaroundtimes" />

- It automatically creates JavaDoc for the generated [Data Accessor](/@external/java/cds-data#generated-accessor-interfaces) interfaces based on doc comments in the CDS model.
- A new goal `cds:build` combines the existing goals `cds:cds` and `cds:generate`.

### Path Expressions on Outer References in EXISTS

You can now use path expressions based on `outer` referenced in an `exists` subquery.
This query selects all books where the publisher's city is the same as the author's city of birth:

```java
Select.from(BOOKS).where(b -> b.exists(outer ->
   Select.from(AUTHOR).where(a -> outer.publisher().city().eq(a.cityOfBirth()))));
```

### Support Doc Comments in Code Generation

Doc comments in CDS are now converted to Javadoc comments in generated Java artifacts:

```cds
/**
 * A medium for recording information in the form of writing
 */
entity Books {
  key id : GUID;

  /**
   * A name for the book which is usually chosen by the author
   */
  title : String;
}
```

&rarr; produces this Java output:

```java
/**
 * A medium for recording information in the form of writing
 */
interface Books {
  String getID();

  /**
   * A name for the book which is usually chosen by the author
   */
  String getTitle();
}
```

### Miscellaneous

- Virtual elements can now be set by client requests. See section [Virtual Elements](/@external/cds/cdl#virtual-elements) for more details.
- The interface [EventContext](/@external/java/event-handlers/#eventcontext) now exposes the `keySet()` method to iterate over all event parameter keys.
- Support SAP proprietary local `3Q` (`en-US-x-saprigi`)
