Dear experts,
is this the correct approach to interact programmatically with the SAP CAP framework without starting a server?
I am working on a script to interact with the SAP Cloud Application Programming (CAP) framework programmatically without starting a server. Below is the code snippet I am using. Please note that the script is in a subfolder of my CAP project.
const path = require('path')
// 1. Use the node process environment to specify the CDS profile to be used
// or default to 'hybrid-dev'
process.env.CDS_ENV = process.env.CDS_ENV || 'hybrid-dev'
// 2. Require the CDS module which also initializes the whole CDS environment
const cds = require('@sap/cds')
// 3. Safely change `cds.root`, that is used by all CAP runtime file access as the root directory
// see https://cap.cloud.sap/docs/node.js/cds-test#test-in-folder
cds.test.in(path.resolve(__dirname, '..'))
// 4. Verify the CDS environment
console.log(cds.root)
console.log(cds.env.profiles)
console.log(cds.env.requires.db)
My goal is to interact with the CAP framework for tasks such as database operations and service interactions without the need to start an HTTP server. Is this the recommended way to achieve this? Are there any best practices or potential pitfalls I should be aware of when using this approach?
Unfortunately I couldn't find anything related to my requirement in the documentation.
Thank you for your insights!
Cheers,
Michael
Request clarification before answering.
Hi,
please check out the discussion Start CAP without express to run a Cloud Foundry task that I've posted in February. I came up with this solution: srv/cap-startup.js. I wanted to avoid to use cds.test.
Best Regards
Gregor
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thanks for your suggestion Gregor! It looked promising and I tried it, but unfortunately it didn't work for my use-case. Mine differs to yours in the following ways:
I wanted to run my script in a subfolder with a given configuration profile:
cd migration
node interact-with-cap.js --profile my-profileMy project layout looks like this:
<project root> ├── app ├── db ├── migration │ └── interact-with-cap.js └── srv
Currently I'm stuck and not sure if it makes sense to proceed with my approach. It seems to me the CAP startup process is rather entangled and not easy to get right without deep knowledge about inner workings and reading the framework's sourcecode. Especially when reading comments like these in several places:
My hope was that I could do something like const myenv = cds.init(__dirname + '../', { profile: 'my-profile' }) and interact with CAP like a configured library. But I looks like spinning up the whole server is the only official entry point to the framework.
The cds bind command was the missing piece! Thanks Gregor!
Using it, profile selection and binding resolution don't have to be part of my script logic anymore. Only had to change how I call my script, not from within my subfolder anymore, but from my CAP modules' root folder.
# Execute in CAP module root (where your package.json is) cds bind --profile hybrid-dev --exec -- node migration/cap-startup-test2.js
//file: migration/cap-startup-test2.js
const cds = require('@sap/cds')
async function capStartup() {
const app = cds.app
cds.emit('bootstrap', app)
// load model from all sources
const csn = await cds.load('*').then(cds.minify)
cds.model = cds.compile.for.nodejs(csn)
cds.emit('loaded', cds.model)
// connect to prominent required services
if (cds.requires.db) cds.db = await cds.connect.to('db')
if (cds.requires.messaging) await cds.connect.to('messaging')
// serve own services as declared in model
cds.serve('all').from(csn).in(app)
await cds.emit('served', cds.services)
}
async function main() {
// Startup CAP Framework
await capStartup()
// Do your thing
const { MyEntity } = cds.db.entities('my.namespace')
console.log(await SELECT.from(MyEntity).columns('count(ID) as cnt'))
// Shutdown CAP Framework
cds.exit()
}
main()
| User | Count |
|---|---|
| 5 | |
| 4 | |
| 4 | |
| 3 | |
| 2 | |
| 2 | |
| 2 | |
| 2 | |
| 2 | |
| 2 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.