Use cds watch for hot-reload development, explore the built-in Fiori launchpad, and test endpoints with REST clients.
Everything about the cds watch development server — hot reload, the Fiori launchpad, the CAP REPL, testing with REST Client, and the mock authentication system for testing secured services locally.
cds watch — your daily drivercds watch starts a development server that watches all .cds and .js files and restarts automatically when you save:
cds watch
[cds] - model loaded from 3 file(s)
[cds] - connect to db > sqlite { database: ':memory:' }
[cds] - serving CatalogService { path: '/odata/v4/catalog' }
[cds] - serving AdminService { path: '/odata/v4/admin' }
[cds] - server listening on { url: 'http://localhost:4004' }
.cds files into an in-memory modeldb/data/ as seed dataOpen http://localhost:4004 — you'll see:
Welcome to cds.services
Web Applications
/webapp → (your Fiori app if configured)
Service Endpoints
/odata/v4/catalog → CatalogService
$metadata → Full OData metadata
⚙ Fiori Preview available
Click any service endpoint to open the OData service document.
CAP includes a built-in Fiori preview for annotated services:
http://localhost:4004/$fiori-preview?service=CatalogService&entity=Books
This gives you a real Fiori List Report UI backed by your service — useful for testing Fiori annotations before connecting a real UI app.
Create a file test/catalog.http (the .http extension activates the REST Client plugin):
### Get all books
GET http://localhost:4004/odata/v4/catalog/Books
### Filter books under $20
GET http://localhost:4004/odata/v4/catalog/Books?$filter=price lt 20
### Get a single book by ID
GET http://localhost:4004/odata/v4/catalog/Books(guid'f1f1f1f1-0000-0000-0000-000000000001')
### Create a book
POST http://localhost:4004/odata/v4/catalog/Books
Content-Type: application/json
{
"title": "Clean Architecture",
"author": "Robert C. Martin",
"price": 39.99,
"stock": 25
}
### Update a book
PATCH http://localhost:4004/odata/v4/catalog/Books(guid'...')
Content-Type: application/json
{ "price": 34.99 }
### Delete a book
DELETE http://localhost:4004/odata/v4/catalog/Books(guid'...')
Click Send Request above each block to execute it.
When your service uses @requires, you need to pass a user for local testing:
In .cdsrc.json:
{
"requires": {
"auth": {
"kind": "mocked",
"users": {
"alice": { "roles": ["admin", "viewer"] },
"bob": { "roles": ["viewer"] },
"guest": { "roles": [] }
}
}
}
}
In REST Client — send as Basic Auth:
### Test as admin
GET http://localhost:4004/odata/v4/admin/Books
Authorization: Basic alice:alice
### Test as regular viewer
GET http://localhost:4004/odata/v4/catalog/Books
Authorization: Basic bob:bob
The password for mocked users is the same as the username. This only works in development mode.
The REPL lets you interact with your CAP model programmatically:
cds repl
// In the REPL:
> await SELECT.from('com.bookshop.Books')
// Returns all books from the local SQLite
> await INSERT.into('com.bookshop.Books').entries({
title: 'REPL Test Book',
price: 9.99,
stock: 10
})
// Inserts a record
> cds.model.definitions['com.bookshop.Books']
// Inspect the compiled model definition
This is extremely useful for debugging queries without needing a running service.
By default, cds watch uses an in-memory SQLite database — data resets every time you restart. For persistent local data:
.cdsrc.json:
{
"requires": {
"db": {
"kind": "sqlite",
"credentials": { "database": "db/bookshop.db" }
}
}
}
# Deploy schema to the SQLite file (run once)
cds deploy --to sqlite
# Then watch — data persists across restarts
cds watch
Tip: Add
db/*.dbto your.gitignore— you don't want to commit the local database.
# Run on a different port
cds watch --port 4005
# Watch only (no browser auto-open)
cds watch --open false
# Run in production mode (no mock auth, no hot reload)
cds serve --production
# Build all (compiles CDS for deployment)
cds build/all
# Show compiled model
cds compile db/schema.cds --to json
cds compile srv/catalog-service.cds --to edmx # OData EDMX
cds watch and browse to the service at localhost:4004?In Lesson 9 we explore OData V4 — what's actually happening when CAP handles those $filter, $expand, and $select queries.