Search

    Events and Requests

    Class cds.EventContext

    Class cds.EventContext represents the invocation context of incoming request and event messages.

    ctx.timestamp Date

    Returns a stable timestamp for the current request being processed.

    The first invocation on a request or any nested request calls and returns the response of new Date(). Subsequent invocations return the formerly determined and pinned value.

    The CAP framework uses that to fill in values for the CDS pseudo variable $now, with the guaranteed same timestamp value.

    Learn more in the Managed Data guide. Learn more on Date in the MDN docs.

    ctx.user cds.User

    Learn more in the Authentication guide.

    ctx.locale string

    ctx.on (event, handler)

    Use this method to register handlers, executed when the whole request is finished.

    req.on('succeeded', () => {...}) // request succeeded
    req.on('failed', () => {...}) // request failed
    req.on('done', () => {...}) // request succeeded/failed
    

    Inside the handlers, you don’t have access to a database connection and can’t veto a commit, etc.

    Transactional Boundary

    The previously listed request lifecycle events (succeeded, failed, and done) are emitted based on the transactional boundary of the respective request. That is, for an individual request (incl. requests inside OData batch requests without an atomicity group assignment), the events are emitted once the request was completed. For requests that are part of a changeset (that means, requests with an atomicity group assignment), the events are emitted once the entire changeset was completed. Following the atomicity property (“all or nothing”), if at least one of the requests in the changeset fails, all requests fail.

    A request or changeset is completed successfully, once the respective transaction was committed (given a database). Hence, the succeeded event handler can’t be used for anything that shall lead to a rejection of the request, for example, additional validity checks. For such cases, use service-level event handlers as shown in the following example:

    const AdminService = await cds.connect.to('AdminService')
    AdminService.after('UPDATE', 'Orders', function(data, req) {
      if ([...]) {
        req.reject(new Error("Veto UPDATE Orders!"))
      }
    })
    
    const DatabaseService = await cds.connect.to('db')
    DatabaseService.before('COMMIT', function(req) {
      if ([...]) {
        req.reject(new Error("Veto entire transaction!"))
      }
    })
    

    Class cds.Event

    Class cds.Event represents event messages in asynchronous messaging, providing access to the event name, target, payload data, and headers. It also serves as the base class for cds.Request and hence for all synchronous interaction.

    msg.event string

    The name of the incoming event, which can be one of:

    • The name of an incoming CRUD request like CREATE
    • The name of an emitted CRUD event like UPDATED
    • The name of a custom operation like cancelOrder.
    • The name of a custom event like cancelledOrder

    msg.data {…} or […]

    Contains the request payload if CREATE and UPDATE requests, which can either be a single object or an array of objects in case of bulk operations (example: await CatalogService.create('Books').entries([...])).
    Contains the keys of the entity if DELETE and READ requests on a single entity through OData or REST.
    Contains parameters for functions and payload for actions.

    msg.headers {…}

    Provides access to headers of the event message or request. In case of asynchronous event messages, it’s the headers information sent by the event source. If HTTP requests, it’s the standard Node.js headers of class IncomingMessage.

    Class cds.Request

    Class cds.Request extends cds.Event with additional features to represent and deal with synchronous requests to services in [event handlers], such as the query, additional request parameters, the authenticated user, and methods to send responses.

    req._ {…}

    Provides access to original inbound protocol-specific request objects. For events triggered by an HTTP request, it contains the original req and res objects as obtained from express.js.

    req.method string

    The HTTP method of the incoming request:

    msg.event msg.method
    CREATE POST
    READ GET
    UPDATE PATCH
    DELETE DELETE

    req.target [def]

    Refers to the current request’s target entity definition, if any; undefined for unbound actions/functions and events. The returned definition is a linked definition as reflected from the CSN model.

    In case of OData navigation requests along associations, msg.target refers to the last target. For example:

    OData Request req.target
    Books AdminService.Books
    Books/201/author AdminService.Authors
    Books(201)/author AdminService.Authors

    See also req.path to learn how to access full navigation paths. See Entity Definitions in the CSN reference. Learn more about linked models and definitions.

    req.path string

    Captures the full canonicalized path information of incoming requests with navigation. If requests without navigation, req.path is identical to req.target.name (or req.entity, which is a shortcut for that).

    Examples based on cap/samples/bookshop AdminService:

    OData Request req.path req.target.name
    Books AdminService.Books AdminService.Books
    Books/201/author AdminService.Books/author AdminService.Authors
    Books(201)/author AdminService.Books/author AdminService.Authors

    See also req.target

    req.entity string

    This is a convenience shortcut to msg.target.name.

    req.params iterable

    Provides access to parameters in URL paths as an iterable with the contents matching the positional occurrence of parameters in the url path. In case of compound parameters, the respective entry is the key value pairs as given in the URL.

    For example, the parameters in an HTTP request like that:

    GET /catalog/Authors(101)/books(title='Eleonora',edition=2)`
    

    The provided parameters can be accessed as follows:

    const [ author, book ] = req.params
    // > author === 101
    // > book === { title: 'Eleonora', edition: 2 }
    

    req.query cqn

    Captures the incoming request as a CQN query object. For example, an HTTP request like GET http://.../Books would be captured as follows:

    req.query = {SELECT:{from:{ref:['Books']}}}
    

    If bound custom operations req.query contains the query to the entity, on which the bound custom operation is called. For unbound custom operations req.query contains an empty object.

    req.reply (results)

    Stores the given results in req.results, which will then be sent back to the client, rendered in a protocol-specific way.

    req.reject (code?, msg, target?, args?)

    Rejects the request with the given HTTP response code and single message. No additional handlers will be executed once req.reject has been invoked. If called multiple times in the same handler, the last call wins (LIFO).

    Arguments are the same as for req.error

    req.error, notify, info, warn (code?, msg, target?, args?)

    Use these methods to collect messages or error and return them in the request response to the caller. The method variants reflect different severity levels, use them as follows:

    Variants

    Method Collected in Typical UI Severity
    req.notify req.messages Toasters 1
    req.info req.messages Dialog 2
    req.warn req.messages Dialog 3
    req.error req.error Dialog 4

    Note: messages with severity < 4 a collected and accessible in property req.messages, while error messages are collected in property req.errors. The latter allows to easily check, whether errors occurred with:

    if (req.errors) //> get out somehow...
    

    Arguments

    • code Number, that means, HTTP status codes
    • msg String | Object | Error → see below for details on the non-string version.
    • target the name of an input field/element a message is related to.
    • args array of placeholder values → see Localized Messages for details.

    Using an Object as Argument

    You can also pass an object as the sole argument, which then contains the properties code, message, target, and args. Additional properties are preserved until the error or message is sanitized for the client. In case of an error, the additional property status (or statusCode) can be used to specify the HTTP status code of the response.

    req.error ({
      code: 'Some-Custom-Code',
      message: 'Some Custom Error Message',
      target: 'some_field',
      status: 418
    })
    

    In OData responses, notifications get collected and put into header sap-messages as a stringified array, while the others are collected in the respective response body properties (→ see OData Error Responses).

    Show/Hide Beta Features