Path, Query Parameter and Paging
Path Variable
A Path Variable is a dynamic value embedded directly within the URL path that is used to identify, locate, or operate on a specific resource in an application.
In SAP CAP, a path variable is a value passed in the URL path that uniquely identifies a specific resource (entity instance). In OData services, path variables are typically represented by the entity key inside parentheses.
Path Variable must have Primary Key field atleast.
CAP provides inbuild path variable feature which we can consume directly.
For Example -
GET http://localhost:4004/odata/v4/warehouse/Warehouses(550e8400-e29b-41d4-a716-446655440009)
Content-Type: application/jsonOR
GET http://localhost:4004/odata/v4/warehouse/Warehouses(ID=550e8400-e29b-41d4-a716-446655440008)
Content-Type: application/jsonAnd we can customize the custom logic based on request.params.
What is next in cap ..?
next is a function available in CAP on event handlers that passes control to the next handler in the processing chain or to CAP's built-in Generic Provider.
So, since we know CAP automatically provides CRUD operations through its Generic Provider without any custom logic. When we implement any custom logic then we are affecting CAP normal flow.
At that point CAP does not know whether you want to completely replace the READ operation OR you only want to add validation and continue.
next() resolves this ambiguity.
So without next(), Your handler becomes responsible for everything.
Request
↓
Custom Handler
↓
STOPand with next(), your handler act as a validation check.
Request
↓
Custom Handler
↓
next()
↓
CAP Generic Provider
↓
Database
↓
Responseand we can use next() in custom handler like-
srv.on('READ', 'Warehouses', async (request, next) => {
try {
// console.log(JSON.stringify(request.query, null, 2));
return next();
}
catch (error) {
return request.error({
code: 500,
message: 'Internal Server Error'
});
}
});Remember, if you are using next and also performing some CRUD operation on DB through custom logic, then you are already reading the database once and then next() causes CAP to read it again.
So there will be two database calls, Hence we should appropriately use the next function.
When Should we Use next() ..?
Use it when we want to:
- Validate input and still use standard CRUD.
- Check authorization.
- Log requests.
- Enrich responses.
- Add business rules before or after CAP processing.
When Should You Avoid next() ..?
Avoid it when:
- We want complete control over the response.
- We are replacing CAP's default CRUD behavior.
- We are reading from an external API instead of the database.
- We are building a completely custom query.
Query Parameter
A Query Parameter is a key-value pair appended to the URL after a ? symbol and is used to filter, search, sort, paginate, or modify the behavior of an API request without changing the resource path.
Path parameters identify a resource, while query parameters refine or filter the result.
Different Query Params provided by CAP are -
- $select
- $search
- $filter
- $orderby
- $top
- $skip
- $count
1. $select
If we want to display only specific fields in the response, we can use the $select query option.
Example -
GET http://localhost:4004/odata/v4/warehouse/Warehouses?$select=ID,name
Content-Type: application/json2. $search
If we want to search for a specific value in the response data, we can use the $search query option.
Example -
GET http://localhost:4004/odata/v4/warehouse/Warehouses?$search=Warehouse
Content-Type: application/json3. $filter
The $filter query option is used to retrieve data that matches a specified condition.
Example, filter the result where name is equals Elite Storage -
GET http://localhost:4004/odata/v4/warehouse/Warehouses?$filter=name eq 'Elite Storage'
Content-Type: application/jsonExample, filter the result where ID is greater than certain value -
GET http://localhost:4004/odata/v4/warehouse/Warehouses?$filter=ID gt 550e8400-e29b-41d4-a716-446655440004
Content-Type: application/jsonExample, filter the result where ID is greater than certain value and name equals to certain value -
GET http://localhost:4004/odata/v4/warehouse/Warehouses?$filter=ID gt 550e8400-e29b-41d4-a716-446655440004 and name eq 'Elite Storage'
Content-Type: application/json4. $orderby
The $orderby query option is used to sort the response data in ascending or descending order based on a specified field.
Example -
GET http://localhost:4004/odata/v4/warehouse/Warehouses?$orderby=name desc
Content-Type: application/json5. $top
The $top query option is used to limit the number of records and return specific number of response data.
Example -
GET http://localhost:4004/odata/v4/warehouse/Warehouses?$top=5
Content-Type: application/json6. $skip
Use the $skip query option to ignore the first N records in the response. It is typically combined with $top to implement paging.
Example -
GET http://localhost:4004/odata/v4/warehouse/Warehouses?$top=5&$skip=2
Content-Type: application/json7. $count
The $count query parameter allows us to obtain the total count of records that match the query criteria.
Example -
GET http://localhost:4004/odata/v4/warehouse/Warehouses?$top=5&$skip=2&$count=true
Content-Type: application/jsonPaging
Paging in SAP CAP is the process of retrieving data in smaller chunks instead of fetching the entire dataset at once.
CAP supports paging through the OData query options $top and $skip.
1. Client-Side Paging
Client-side paging can be implemented by using the $top and $skip OData query options to retrieve a specific subset of records from the complete dataset.
Example -
GET http://localhost:4004/odata/v4/warehouse/Warehouses?$top=5&$skip=2
Content-Type: application/json2. Server-Side Paging (Default Page Size)
We can configure a default and maximum page size in our service definition in service.cds file.
We can use @cds.query.limit.default and @cds.query.limit.max annotation on the service file.
like -
service WarehouseService @(path : 'warehouse') {
@cds.query.limit.default: 5
@cds.query.limit.max: 8
entity Warehouses as projection on schema.Warehouse;
function getWarehouseCount() returns Integer ;
action updateWarehouseOwner(warehouseId : String, newOwner : String) returns String ;
}and then request data will return default of 5 records using -
GET http://localhost:4004/odata/v4/warehouse/Warehouses
Content-Type: application/jsonand will return max of 8 records if we try to fetch more than 8 records -
GET http://localhost:4004/odata/v4/warehouse/Warehouses?$top=12
Content-Type: application/json3. Global Paging Configuration
You can define limits for all services of the application and can define define it in package.json.
like -
"cds": {
"query": {
"limit": {
"default": 5,
"max": 8
}
}
}and then request data will return default of 5 records using -
GET http://localhost:4004/odata/v4/warehouse/Warehouses
Content-Type: application/jsonand will return max of 8 records if we try to fetch more than 8 records -
GET http://localhost:4004/odata/v4/warehouse/Warehouses?$top=12
Content-Type: application/json!!! Its Done !!!