const { RestRemoteService } = require("cap-remote-service-rest");
class PetstoreService extends RestRemoteService {}
module.exports = PetstoreService;namespace db;
using {
Country,
cuid
} from '@sap/cds/common';
type Address : {
country : Country;
city : String;
postalCode : String(10);
addressLine : String;
}
entity Sites : cuid {
name : String;
postalAddress : Address;
}using {db} from '../db/schema';
service FacilityService {
type Weather : {
condition : String;
temparature : Decimal(5, 2);
humidity : Decimal(5, 2);
windSpeed : Decimal(5, 2);
}
entity Sites as projection on db.Sites actions {
function getCurrentWeather() returns Weather;
}
};"cds": {
"requires": {
"OpenWeatherMap.API": {
"kind": "rest",
"model": "srv/external/OpenWeatherMap.API"
}
}
}"OpenWeatherMap.API.weather": {
"kind": "function",
"params": {
"q": {
"type": "cds.String",
"@openapi.in": "query"
},
"id": {
"type": "cds.String",
"@openapi.in": "query"
},
"lat": {
"type": "cds.String",
"@openapi.in": "query"
},
"lon": {
"type": "cds.String",
"@openapi.in": "query"
},
"zip": {
"type": "cds.String",
"@openapi.in": "query"
},
"units": {
"type": "cds.String",
"@assert.range": true,
"enum": {
"standard": {},
"metric": {},
"imperial": {}
},
"@openapi.in": "query"
},
"lang": {
"type": "cds.String",
"@assert.range": true,
"enum": {
...
},
"@openapi.in": "query"
},
"mode": {
"type": "cds.String",
"@assert.range": true,
"enum": {
"json": {},
"xml": {},
"html": {}
},
"@openapi.in": "query"
}
},
"@openapi.path": "/weather",
"returns": {
"type": "OpenWeatherMap.API_types._200"
}
}class FacilityService extends cds.ApplicationService {
async init() {
const { Sites } = this.entities;
this.on("getCurrentWeather", Sites, async (req) => {
const sites = await req.query;
if (!sites.length) {
return req.reject(404);
}
const { postalCode, country_code: country } = sites[0].postalAddress;
const weatherSrv = await cds.connect.to("OpenWeatherMap.API");
const weatherData = await weatherSrv.send("weather", {
q: null,
id: null,
lat: null,
lon: null,
zip: `${postalCode},${country}`,
units: "metric",
lang: "en",
mode: "json",
});
return {
condition: weatherData.weather[0]?.description ?? null,
temparature: weatherData.main.temp,
humidity: weatherData.main.humidity,
windspeed: weatherData.wind.speed,
};
});
await super.init();
}
}class OpenApiRemoteService extends cds.RemoteService {
async init() {
this.before("*", "*", (req) => {
const fullyQualifiedName = this.namespace + "." + req.event;
const definition = this.model.definitions[fullyQualifiedName];
req.method = this._getMethod(definition);
req.path = this._getPath(definition, req.data || {});
req.data = {};
req.event = undefined;
});
await super.init();
}
_getMethod(definition) {
return definition["@openapi.method"] || definition.kind === "action"
? "POST"
: "GET";
}
_getPath(definition, data) {
// Maps the parameters to path segments
const mapPathSegment = (segment) => {
const match = segment.match(/(?<=\{)(.*)(?=\})/g); // matches e. g. {placeholder}
if (!match) {
// No placeholder
return segment;
}
const param = match[0];
const paramValue = data[param];
if (paramValue === undefined || paramValue === null) {
throw new CapError(
400,
`Value for mandatory parameter '${param}' missing`
);
}
return paramValue.toString();
};
// Construct the path to the endpoint by replacing placeholders with actual parameter values
const path = definition["@openapi.path"]
.split("/")
.map(mapPathSegment)
.join("/");
const queryString = this._getQueryParams(definition, data).toString();
return path + (queryString.length ? "?" + queryString : "");
}
_getQueryParams(definition, data) {
const queryParams = new URLSearchParams();
Object.entries(data)
.filter(([key]) => definition.params?.[key]?.["@openapi.in"] === "query")
.filter(([, value]) => value !== undefined && value !== null)
.forEach(([key, value]) => queryParams.set(key, value.toString()));
return queryParams;
}
}{
"@odata.context": "$metadata#Sites/$entity",
"ID": "3ee63bcf-68ec-4645-8ed1-eac74eb5c6c3",
"name": "SAP Innovation Center",
"postalAddress": {
"city": "Potsdam",
"postalCode": "14469",
"addressLine": "Konrad-Zuse-Ring 10",
"country": {
"code": "DE"
}
}
}{
"@odata.context": "../$metadata#FacilityService.Weather",
"condition": "broken clouds",
"temparature": 30.62,
"humidity": 22
}You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
| User | Count |
|---|---|
| 48 | |
| 23 | |
| 20 | |
| 18 | |
| 16 | |
| 16 | |
| 13 | |
| 13 | |
| 13 | |
| 12 |