diff --git a/xmpl/package.json b/xmpl/package.json index b79f885..805eb19 100644 --- a/xmpl/package.json +++ b/xmpl/package.json @@ -1,14 +1,22 @@ { - "name": "@capire/ord-sample", - "description": "this is a xmpl application description", - "version": "1.0.0", - "dependencies": { - "@cap-js/ord": "*", - "@capire/incidents": "*", - "@sap/cds": "*" - }, - "devDependencies": { - "@cap-js/sqlite": "*" - }, - "private": true + "name": "@capire/ord-sample", + "description": "this is a xmpl application description", + "version": "1.0.0", + "dependencies": { + "@cap-js/ord": "*", + "@capire/incidents": "*", + "@sap/cds": "*" + }, + "devDependencies": { + "@cap-js/sqlite": "*" + }, + "private": true, + "cds": { + "requires": { + "SAP ORD Service": { + "model": "@cap-js/ord/srv/ord-service", + "service": "OrdService" + } + } + } } diff --git a/xmpl/srv/ord-service.cds b/xmpl/srv/ord-service.cds new file mode 100644 index 0000000..c464d1d --- /dev/null +++ b/xmpl/srv/ord-service.cds @@ -0,0 +1,12 @@ +// @requires: 'ORDconsumer' +@rest @path:'/ord/v1' +service OrdService { + @readonly entity documents { + key id: String; + } + @readonly entity csn { + key id: String; + } + + function api (service: String, format: String) returns {}; +} \ No newline at end of file diff --git a/xmpl/srv/ord-service.mjs b/xmpl/srv/ord-service.mjs new file mode 100644 index 0000000..644cb3c --- /dev/null +++ b/xmpl/srv/ord-service.mjs @@ -0,0 +1,78 @@ +import cds from '@sap/cds' +export class OrdService extends cds.ApplicationService { + init(){ + + this.on('READ','documents', req => { + let csn = cds.context?.model || cds.model + return { ord: csn } + }) + + /** + * Just an example to do something with id, if given. + * Try it out with URLs like that: + * + * - http://localhost:4004/ord/v1/documents + * - http://localhost:4004/ord/v1/documents/CatalogService + * - http://localhost:4004/ord/v1/documents/CatalogService.Books + * - http://localhost:4004/ord/v1/documents/CatalogService.Authors + */ + this.on('READ','csn', req => { + let csn = cds.context?.model || cds.model + let { id } = req.data + if (id) csn = csn.definitions[id] || 'not in model!' + return { id, csn } + }) + + /** + * Just an example to serve arbitrary content with a function. + * Try it out with URLs like that: + * + * - http://localhost:4004/ord/v1/api?service=CatalogService + * - http://localhost:4004/ord/v1/api?service=CatalogService&format=edmx + * - http://localhost:4004/ord/v1/api?service=CatalogService&format=edmx-v2 + * - http://localhost:4004/ord/v1/api?service=CatalogService&format=openapi + */ + this.on('api', req => { + let csn = cds.context?.model || cds.model + let { service, format = 'csn' } = req.data + let { res } = req.http + if (format === 'csn') { + if (!service) return res.send(csn) + service = csn.services[service] + return res.send({ definitions: [ service, ...service.entities ] .reduce ((all,e) => { + let d = all[e.name] = {...e} + delete d.projection // not part of the API + delete d.query // not part of the API + return all + },{})}) + } + let api = cds.compile(csn).to[format]({service}) + return res.send(api) + }) + + /** + * Example how to register arbitrary express routes, + * and map them to our service's interface. + * Try it out with URLs like that: + * + * - http://localhost:4004/ord/v1/csn/CatalogService + * - http://localhost:4004/ord/v1/edmx/CatalogService + * - http://localhost:4004/ord/v1/openapi/CatalogService + * - http://localhost:4004/ord/v1/asyncapi/CatalogService + * + * NOTE: we add cds.middlewares.before to the route, which gives us all + * the context and auth handling, which is also available to CAP services. + * + * TODO: Paths should be the following: + * - http://localhost:4004/ord/v1/documents/ord-document + * - http://localhost:4004/ord/v1/:ordId/:fileName + * - http://localhost:4004/.well-known/open-resource-discovery + */ + cds.app.get (`${this.path}/:api?/:service?`, cds.middlewares.before, req => { + const { api, service } = req.params + return this.api (service, api) + }) + + return super.init() + } +} \ No newline at end of file