Skip to content
On this page

Serving Provided Services

Declaring Provided Services

Implementing Services

cds.serve... service(s)

Use cds.serve() to construct service providers from the service definitions in corresponding CDS models. As stated above, this is usually done automatically by the built-in cds.server.

Declaration:

ts
async function cds.serve (
  service        : 'all' | string | cds.Service | typeof cds.Service, 
  options        : { service = 'all', ... }
) .from ( model  : string | CSN )         // default: cds.model
  .to ( protocol : string | 'rest' | 'odata' | 'odata-v2' | 'odata-v4' | ... )
  .at ( path     : string )
  .in ( app      : express.Application )  // default: cds.app
.with ( impl     : string | function | cds.Service | typeof cds.Service )
async function cds.serve (
  service        : 'all' | string | cds.Service | typeof cds.Service, 
  options        : { service = 'all', ... }
) .from ( model  : string | CSN )         // default: cds.model
  .to ( protocol : string | 'rest' | 'odata' | 'odata-v2' | 'odata-v4' | ... )
  .at ( path     : string )
  .in ( app      : express.Application )  // default: cds.app
.with ( impl     : string | function | cds.Service | typeof cds.Service )

cds. services

All service instances constructed by cds.connect() or by cds.serve()are registered in the cds.services dictionary. After the bootstrapping phase you can safely refer to entries in there:

js
const { CatalogService } = cds.services
const { CatalogService } = cds.services

Use this if you are not sure whether a service is already constructed:

js
const CatalogService = await cds.connect.to('CatalogService')
const CatalogService = await cds.connect.to('CatalogService')

cds.serve (service, options) ⇢ fluent api... 

Initiates a fluent API chain to construct service providers; use the methods documented below to add more options.

Common Usages:
js
const { CatalogService } = await cds.serve ('my-services')
const { CatalogService } = await cds.serve ('my-services')
js
const app = require('express')()
cds.serve('all') .in (app)
const app = require('express')()
cds.serve('all') .in (app)
Arguments:
  • name specifies which service to construct a provider for; use all to construct providers for all definitions found in the models.
js
cds.serve('CatalogService')  //> serve a single service
cds.serve('all')             //> serve all services found
cds.serve('CatalogService')  //> serve a single service
cds.serve('all')             //> serve all services found

You may alternatively specify a string starting with './' or refer to a file name with a non-identifier character in it, like '-' below, as a convenient shortcut to serve all services from that model:

js
cds.serve('./reviews-service')  //> is not an identifier through './'
cds.serve('reviews-service')    //> same as '-', hence both act as:
cds.serve('all').from('./reviews-service')
cds.serve('./reviews-service')  //> is not an identifier through './'
cds.serve('reviews-service')    //> same as '-', hence both act as:
cds.serve('all').from('./reviews-service')

The method returns a fluent API object, which is also a Promise resolving to either an object with 'all' constructed service providers, or to the single one created in case you specified a single service:

js
const { CatalogService, AdminService } = await cds.serve('all')
const ReviewsService = await cds.serve('ReviewsService')
const { CatalogService, AdminService } = await cds.serve('all')
const ReviewsService = await cds.serve('ReviewsService')
Caching:

The constructed service providers are cached in cds.services, which (a) makes them accessible to cds.connect, as well as (b) allows us to extend already constructed services through subsequent invocation of cds.serve.

Common Usages and Defaults

Most commonly, you'd use cds.serve in a custom file to add all the services to your express.js app as follows:

js
const app = require('express')()
cds.serve('all').in(app)
app.listen()
const app = require('express')()
cds.serve('all').in(app)
app.listen()

This uses these defaults for all options:

OptionDescriptionDefault
cds.serve ...which services to construct'all' services
.frommodels to load definitions from'./srv' folder
.inexpress app to mount to--- none ---
.toclient protocol to serve to'fiori'
.atendpoint path to serve at@path or .name
.withimplementation function@impl or ._source.js

Alternatively you can construct services individually, also from other models, and also mount them yourself, as document in the subsequent sections on individual fluent API options.

If you just want to add some additional middleware, it's recommended to bootstrap from a custom server.js.

.from (model)

Allows to determine the CDS models to fetch service definitions from, which can be specified as one of:

  • A filename of a single model, which gets loaded and parsed with [cds.load]
  • A name of a folder containing several models, also loaded with [cds.load]
  • The string 'all' as a shortcut for all models in the './srv' folder
  • An already parsed model in CSN format

The latter allows you to [cds.load] or dynamically construct models yourself and pass in the CSN models, as in this example:

js
const csn = await cds.load('my-services.cds')
cds.serve('all').from(csn)...
const csn = await cds.load('my-services.cds')
cds.serve('all').from(csn)...

If omitted, './srv' is used as default.

.to (protocol)

Allows to specify the protocol through which to expose the service. Currently supported values are:

  • 'rest' plain http rest protocol without any OData-specific extensions
  • 'odata' standard OData rest protocol without any Fiori-specific extensions
  • 'fiori' OData protocol with all Fiori-specific extensions like Draft enabled

If omitted, 'fiori' is used as default.

.at (path)

Allows to programmatically specify the mount point for the service.

Note that this is only possible when constructing single services:

js
cds.serve('CatalogService').at('/cat')
cds.serve('all').at('/cat') //> error
cds.serve('CatalogService').at('/cat')
cds.serve('all').at('/cat') //> error

If omitted, the mount point is determined from annotation @path, if present, or from the service's lowercase name, excluding trailing Service.

cds
service MyService @(path:'/cat'){...}  //> served at: /cat
service CatalogService {...}           //> served at: /catalog
service MyService @(path:'/cat'){...}  //> served at: /cat
service CatalogService {...}           //> served at: /catalog

.in (express app)

Adds all service providers as routers to the given express app.

js
const app = require('express')()
cds.serve('all').in(app)
app.listen()
const app = require('express')()
cds.serve('all').in(app)
app.listen()

.with (impl function)

Allows to specify a function that adds [event handlers] to the service provider, either as a function or as a string referring to a separate node module containing the function.

js
cds.serve('./srv/cat-service.cds') .with ('./srv/cat-service.js')
cds.serve('./srv/cat-service.cds') .with ('./srv/cat-service.js')
js
cds.serve('./srv/cat-service') .with (srv => {
  srv.on ('READ','Books', (req) => req.reply([...]))
})
cds.serve('./srv/cat-service') .with (srv => {
  srv.on ('READ','Books', (req) => req.reply([...]))
})

Learn more about using impl annotations.Learn more about adding event handlers.

Note that this is only possible when constructing single services:

js
cds.serve('CatalogService') .with (srv=>{...})
cds.serve('all') .with (srv=>{...})  //> error
cds.serve('CatalogService') .with (srv=>{...})
cds.serve('all') .with (srv=>{...})  //> error

If omitted, an implementation is resolved from annotation @impl, if present, or from a .js file with the same basename than the CDS model, for example:

cds
service MyService @(impl:'cat-service.js'){...}
service MyService @(impl:'cat-service.js'){...}
sh
srv/cat-service.cds  #> CDS model with service definition
srv/cat-service.js   #> service implementation used by default
srv/cat-service.cds  #> CDS model with service definition
srv/cat-service.js   #> service implementation used by default

cds. middlewares

. context()

. auth()

. ctx_auth()

. ctx_models()

. trace()

. error()

cds. protocols