Search

    July 2021

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

    Find bugfixes and enhancements in the Changelog.


    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.

    cds-ts serve world.cds
    
    cds-ts watch
    

    Learn more about using TypeScript.

    Swagger UI Made Easier

    For Node.js apps, less code is now needed to serve exported OpenAPI definitions in Swagger UI. Just install the new cds-swagger-ui-express package:

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

    And add a server.js file:

    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

    Learn more about OpenAPI publishing.

    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

    Try out the SFLIGHT app.

    New End-to-End Tutorials

    Try out step by step our new tutorials to Build an Application End-to-End using CAP, Node.js, and VS Code. You will develop a business application using CAP, enhance it with an SAP Fiori UI, and add business logic to it. Furthermore, you will add a Launch Page to start the UIs, add roles and authorization checks, and deploy your application to SAP Business Technology Platform using SAP HANA Cloud Service and Launchpad Service.

    CAP Mission

    As a next step you can Configure and Run a Predefined SAP Continuous Integration and Delivery (CI/CD) Pipeline for your developed CAP application.

    Command Line / Toolkit

    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

    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:

    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 → 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

    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:

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

    and the compiler will translate it to the corresponding 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.

    Define Views with the Exists Predicate

    Use the Exists Predicate with path expressions and infix filters as a simplified way to define views with correlated exists subqueries:

    SELECT from Authors where exists books[year=2000]
    

    unfolds to:

    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.

    Node.js Runtime

    This release focuses on quality and incremental steps towards larger feature packages. See the changelog for more details.

    Merged Runtime Packages ❗️

    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 ❗️

    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 → 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

    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 for more details.

    Java SDK

    Important Changes ❗️

    Spring Boot 2.5 Support

    • Please 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 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 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, for example:

    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:

    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 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 is disabled) are not implicitly sorted anymore to improve performance.

    Improved Development Turnaround Times

    The CDS Maven Plugin helps improving development roundtrips:

    • It automatically creates JavaDoc for the generated Data Accessor 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:

    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:

    /**
     * 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;
    }
    

    → produces this Java output:

    /**
     * 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 for more details.
    • The interface EventContext now exposes the keySet() method to iterate over all event parameter keys.
    • Support SAP proprietary local 3Q (en-US-x-saprigi)
    Show/Hide Beta Features