From 84a815e7e6d5d4bdc7bbd669bdf5f956601ef97a Mon Sep 17 00:00:00 2001 From: Daniel Date: Sun, 8 Mar 2020 12:42:26 +0100 Subject: [PATCH] Added reviews/test/bookshop --- reviewed/services.cds | 13 ------ reviewed/tests.http | 40 ------------------- reviews/srv/reviews-service.cds | 1 - reviews/srv/reviews-service.js | 8 ++-- .../test/bookshop}/package.json | 9 ++--- reviews/test/bookshop/schema.cds | 13 ++++++ .../test/bookshop/server.js | 29 ++++++++------ reviews/test/messaging.test.js | 2 +- reviews/test/requests.http | 40 +++++++++++-------- samples.md | 10 +---- 10 files changed, 64 insertions(+), 101 deletions(-) delete mode 100644 reviewed/services.cds delete mode 100644 reviewed/tests.http rename {reviewed => reviews/test/bookshop}/package.json (72%) create mode 100644 reviews/test/bookshop/schema.cds rename reviewed/services.js => reviews/test/bookshop/server.js (83%) diff --git a/reviewed/services.cds b/reviewed/services.cds deleted file mode 100644 index 6cf3bd70..00000000 --- a/reviewed/services.cds +++ /dev/null @@ -1,13 +0,0 @@ -namespace sap.capire.bookshop; -using { sap.capire.reviews.ReviewsService as external } from '@capire/reviews'; -using { sap.capire.bookshop.Books } from '@capire/bookshop/db/schema'; - -// Extending Books by Reviews -extend Books with { - reviews : Composition of many external.Reviews on reviews.subject = ID; - rating : external.Reviews.rating; -} - -using from '@capire/bookshop/srv/admin-service'; -using from '@capire/bookshop/srv/cat-service'; -annotate AdminService with @impl:'services.js'; diff --git a/reviewed/tests.http b/reviewed/tests.http deleted file mode 100644 index d1c89504..00000000 --- a/reviewed/tests.http +++ /dev/null @@ -1,40 +0,0 @@ -################################################# -# -# Reviews Service -# - - -### Request to CatalogService > delegated to ReviewsService -GET http://localhost:4004/browse/Books(201)/reviews - -### Alternative OData URL -GET http://localhost:4004/browse/Books/201/reviews - -### -GET http://localhost:4004/browse/Books(201)? -&$select=ID,title,rating -&$expand=reviews -# Note: the latter only works in case of ReviewsService in same process - - - -### ReviewsService mocked in same process -GET http://localhost:4004/reviews/Reviews? - -### -POST http://localhost:4004/reviews/Reviews -Content-Type: application/json;IEEE754Compatible=true - -{"subject":"201", "title":"boo"} - - - - -### ReviewsService running as separate process -GET http://localhost:5005/reviews/Reviews? - -### -POST http://localhost:5005/reviews/Reviews -Content-Type: application/json;IEEE754Compatible=true - -{"subject":"201", "title":"boo"} diff --git a/reviews/srv/reviews-service.cds b/reviews/srv/reviews-service.cds index 9634c183..dafcb0d1 100644 --- a/reviews/srv/reviews-service.cds +++ b/reviews/srv/reviews-service.cds @@ -1,5 +1,4 @@ using { sap.capire.reviews as my } from '../db/schema'; -namespace sap.capire.reviews; service ReviewsService { // Sync API diff --git a/reviews/srv/reviews-service.js b/reviews/srv/reviews-service.js index 2e347a93..33f383d9 100644 --- a/reviews/srv/reviews-service.js +++ b/reviews/srv/reviews-service.js @@ -5,9 +5,9 @@ module.exports = cds.service.impl (function(){ // ( Note: we explicitly specify the namespace to support embedded reuse ) const { Reviews, Likes } = this.entities ('sap.capire.reviews') - // this.before (['CREATE','UPDATE'], 'Reviews', req => { - // if (!req.data.rating) req.data.rating = Math.round(Math.random()*4)+1 - // }) + this.before (['CREATE','UPDATE'], 'Reviews', req => { + if (!req.data.rating) req.data.rating = Math.round(Math.random()*4)+1 + }) // Emit an event to inform subscribers about new avg ratings for reviewed subjects // ( Note: req.on.succeeded ensures we only do that if there's no error ) @@ -17,7 +17,7 @@ module.exports = cds.service.impl (function(){ SELECT.one (['round(avg(rating),2) as rating']) .from (Reviews) .where ({subject}) ) req.on ('succeeded', ()=>{ - console.log ('< emitting:', 'reviewed', { subject, rating }) + global.it || console.log ('< emitting:', 'reviewed', { subject, rating }) this.emit ('reviewed', { subject, rating }) }) }) diff --git a/reviewed/package.json b/reviews/test/bookshop/package.json similarity index 72% rename from reviewed/package.json rename to reviews/test/bookshop/package.json index 55c4f202..f24f3233 100644 --- a/reviewed/package.json +++ b/reviews/test/bookshop/package.json @@ -3,17 +3,16 @@ "version": "1.0.0", "dependencies": { "@capire/bookshop": "*", - "@capire/reviews": "*" - }, - "scripts": { - "watch": "cds watch" + "@capire/reviews": "*", + "@sap/cds": "^3.31.1", + "express": "^4.17.1" }, "cds": { "requires": { "db": { "kind": "sql" }, - "sap.capire.reviews.ReviewsService": { + "ReviewsService": { "kind": "odata" }, "messaging": { diff --git a/reviews/test/bookshop/schema.cds b/reviews/test/bookshop/schema.cds new file mode 100644 index 00000000..39fdfb35 --- /dev/null +++ b/reviews/test/bookshop/schema.cds @@ -0,0 +1,13 @@ +// +// Extending Books with Reviews +// + +using { sap.capire.bookshop.Books } from '@capire/bookshop'; +using { ReviewsService.Reviews } from '@capire/reviews'; + +extend Books with { + /** Access to detailed collection of Reviews */ + reviews : Composition of many Reviews on reviews.subject = $self.ID; + /** Average rating */ + rating : Reviews.rating; +} diff --git a/reviewed/services.js b/reviews/test/bookshop/server.js similarity index 83% rename from reviewed/services.js rename to reviews/test/bookshop/server.js index 261c3e9f..540c6d65 100644 --- a/reviewed/services.js +++ b/reviews/test/bookshop/server.js @@ -1,24 +1,15 @@ const cds = require ('@sap/cds') -module.exports = cds.service.impl (async()=>{ +cds.on('listening', async()=>{ - // connect to requires services - const ReviewsService = await cds.connect.to ('sap.capire.reviews.ReviewsService') + // connect to requires services + const ReviewsService = await cds.connect.to ('ReviewsService') const CatalogService = await cds.connect.to ('CatalogService') const db = await cds.connect.to ('db') // import model definitions from connected services to work with subsequently - const { Books } = db.entities const { Reviews } = ReviewsService.entities - - // delegate requests to read reviews to ReviewsService - CatalogService.impl (srv => { - srv.on ('READ', 'Books/reviews', (req) => { - const [ subject ] = req.params - const tx = ReviewsService.transaction (req) - return tx.run (SELECT.from (Reviews) .where ({subject})) - }) - }) + const { Books } = db.entities // react on event messages from reviews service ReviewsService.on ('reviewed', (msg) => { @@ -29,4 +20,16 @@ module.exports = cds.service.impl (async()=>{ // return tx.update (Books, subject) .with ({rating}) }) + console.log (Reviews.name) + // delegate requests to read reviews to ReviewsService + CatalogService.impl (srv => { + srv.on ('READ', 'Books/reviews', (req) => { + const [ subject ] = req.params + const tx = ReviewsService.transaction (req) + return tx.run (SELECT.from (Reviews) .where ({subject})) + }) + }) + }) + +module.exports = cds.server diff --git a/reviews/test/messaging.test.js b/reviews/test/messaging.test.js index 55e758ac..d1ace70a 100644 --- a/reviews/test/messaging.test.js +++ b/reviews/test/messaging.test.js @@ -1,6 +1,6 @@ const _model = __dirname+'/..' const cds = require ('@sap/cds') -const {expect} = require('chai').use(require('chai-subset')) +const {expect} = cds.require.chai describe('messaging tests', ()=>{ diff --git a/reviews/test/requests.http b/reviews/test/requests.http index 564c8789..d1c89504 100644 --- a/reviews/test/requests.http +++ b/reviews/test/requests.http @@ -4,21 +4,6 @@ # -### Use this one for ReviewsService running as a separate process -# Note: use 5005 instead of 4004 in case of separate service -POST http://localhost:5005/reviews/Reviews -# POST http://localhost:4004/reviews/Reviews -Content-Type: application/json;IEEE754Compatible=true - -{"subject":"201", "rating":"4", "title":"boo"} - -### Direct Request to ReviewsService -# Note: use 5005 instead of 4004 in case of separate service -GET http://localhost:5005/reviews/Reviews? -# GET http://localhost:4004/reviews/Reviews? -# &$filter=subject eq '201' - - ### Request to CatalogService > delegated to ReviewsService GET http://localhost:4004/browse/Books(201)/reviews @@ -28,5 +13,28 @@ GET http://localhost:4004/browse/Books/201/reviews ### GET http://localhost:4004/browse/Books(201)? &$select=ID,title,rating -# &$expand=reviews +&$expand=reviews # Note: the latter only works in case of ReviewsService in same process + + + +### ReviewsService mocked in same process +GET http://localhost:4004/reviews/Reviews? + +### +POST http://localhost:4004/reviews/Reviews +Content-Type: application/json;IEEE754Compatible=true + +{"subject":"201", "title":"boo"} + + + + +### ReviewsService running as separate process +GET http://localhost:5005/reviews/Reviews? + +### +POST http://localhost:5005/reviews/Reviews +Content-Type: application/json;IEEE754Compatible=true + +{"subject":"201", "title":"boo"} diff --git a/samples.md b/samples.md index 7bd1ee81..efa74a61 100644 --- a/samples.md +++ b/samples.md @@ -40,20 +40,14 @@ Each sub directory essentially is a individual npm package arranged in an [all-i ## [reviews](reviews) - Shows how to implement a modular service to manage product reviews, including... +- Consuming other services synchronously and asynchronously - Serving requests synchronously - Emitting events asynchronously -- As well as managed data, input validations and authorization - - -## [reviewed](reviewed) - -- Enhances [bookshop](#bookshop) with [reviews](#reviews), thereby showcasing... -- Consuming other services synchronously -- As well as asynchronously, subscribing to events - Grow as you go, with... - Mocking app services - Running service meshes - Late-cut Micro Services +- As well as managed data, input validations and authorization ## [fiori](fiori)