Search

    Bootstrapping Process

    A Node.js CAP server process is started with the cds serve CLI command, with cds run and cds watch as convenience variants.

    Besides, handling command line arguments and adding log output, cds serve essentially loads a built-in server.js module, which can be accessed through cds.server.

    You can plug-in custom logic to the default bootstrapping choreography using a custom server.js in your project.

    cds.server (options) => {…}

    This is essentially a shortcut getter to require('@sap/cds/server'), that is, it loads and returns the built-in server.js implementation. You’d mainly use this in custom server.js to delegate to the default implementation, for example:.

    const cds = require('@sap/cds')
    // ... some custom bootstrapping ...
    module.exports = cds.server //> delegate to default server.js
    

    Built-in server.js

    The built-in server.js constructs an express.js app, and bootstraps all CAP services using cds.connect and cds.serve. Its implementation essentially is as follows:

    const cds = require('@sap/cds')
    const express = require('express')
    module.exports = async function cds_server (o) {    //> o = options from CLI
    
        const app = cds.app = o.app || express()
        cds.emit ('bootstrap',app)                      //> hook for project-local server.js
    
        // mount static resources and logger middleware
        if (o.static)    app.use (express.static (o.static))  //> defaults to ./app
        if (o.favicon)   app.use ('/favicon.ico', o.favicon)  //> if none in ./app
        if (o.index)     app.get ('/',o.index)                //> if none in ./app
        if (o.correlate) app.use (o.correlate)                //> request correlation
        if (o.logger)    app.use (o.logger)                   //> basic request logging
    
        // load specified models or all in project
        const csn = await cds.load (o.from||'*')
        cds.model = o.from = cds.linked (cds.compile.for.odata(csn))
    
        // connect to essential framework services if required
        // note: cds.deploy() is not a public API
        const _init = o.in_memory && (db => cds.deploy(csn).to(db,o))
        if (cds.requires.db) cds.db = await cds.connect.to ('db') .then (_init)
        if (cds.requires.messaging) await cds.connect.to ('messaging')
        if (cds.requires.multitenancy) await cds.mtx.in (app)
    
        // serve all services declared in models
        await cds.serve (o.service,o).in (app)
        cds.emit ('served', cds.services)               //> hook for listeners
    
        // start http server
        const port = (o.port !== undefined) ? o.port : (process.env.PORT || 4004)
        return app.listen (port)
    

    Custom server.js

    The CLI command cds serve optionally bootstraps from project-local ./server.js or ./srv/server.js. In there, register own handlers to bootstrap events emitted to the cds facade object as below:

    const cds = require('@sap/cds')
    // react on bootstrapping events...
    cds.on('bootstrap', ...)
    cds.on('served', ...)
    module.exports = cds.server //> delegate to default server.js
    

    Provide an own bootstrapping function if you want to access and process the command line options. This also allows you to override certain options before delegating to the built-in server.js. In the example below, we construct the express.js app ourselves and fix the models to be loaded.

    const cds = require('@sap/cds')
    // react on bootstrapping events...
    cds.on('bootstrap', ...)
    cds.on('served', ...)
    // handle and override options
    module.exports = (o)=>{
      o.from = 'srv/precompiled-csn.json'
      o.app = require('express')()
      return cds.server(o) //> delegate to default server.js
    }
    

    cds.once (‘bootstrap’, (express.js app)=>{})

    A one-time event, emitted immediately after the express.js app has been created and before any middleware or CDS services are added to it.

    const cds = require('@sap/cds')
    cds.on('bootstrap', (app)=>{
      // add your own middleware before any by cds are added
    })
    

    cds.on (‘loaded’, (csn)=>{})

    Emitted whenever a CDS model got loaded using cds.load()

    cds.on (‘serving’, (service)=>{})

    Emitted for each service constructed by cds.serve.

    cds.on (‘connect’, (service)=>{})

    Emitted for each service constructed through cds.connect.

    cds.on (‘subscribe’, (service,event)=>{})

    Emitted whenever a handler is registered for a declared event with [srv.on].

    cds.once (‘served’, (services)=>{})

    A one-time event, emitted when all services have been bootstrapped and added to the express.js app.

    const cds = require('@sap/cds')
    cds.on('served', ()=>{
      // add more middleware after all CDS services
    })
    

    cds.once (‘listening’, ({server,url})=>{})

    A one-time event, emitted when the server has been started and is listening to incoming requests.

    Show/Hide Beta Features