diff --git a/bookshop/app/vue/index.html b/bookshop/app/vue/index.html
index 6dae24bc..641914ae 100644
--- a/bookshop/app/vue/index.html
+++ b/bookshop/app/vue/index.html
@@ -34,7 +34,7 @@
{{ book.author }} |
{{ book.genre.name }} |
- {{ ('★'.repeat(Math.round(book.rating))+'☆☆☆☆☆').slice(0,5) }}
+ {{ ('★'.repeat(Math.round(book.rating))+'☆☆☆☆☆').slice(0,5) }} ({{ book.numberOfReviews }})
|
{{ book.currency && book.currency.symbol }} {{ book.price }} |
diff --git a/bookshop/index.js b/bookshop/index.js
index 0f7a3ffa..7bffbe36 100644
--- a/bookshop/index.js
+++ b/bookshop/index.js
@@ -1 +1,2 @@
-exports.CatalogService = require('./srv/cat-service')
+const { CatalogService } = require('./srv/cat-service')
+module.exports = { CatalogService }
diff --git a/fiori/package.json b/fiori/package.json
index 2e4e62cf..0449fb13 100644
--- a/fiori/package.json
+++ b/fiori/package.json
@@ -38,6 +38,11 @@
"[production]": {
"model": "db/hana"
}
+ },
+ "messaging": {
+ "[development]": { "kind": "file-based-messaging" },
+ "[hybrid]": { "kind": "enterprise-messaging-shared" },
+ "kind": "enterprise-messaging"
}
}
}
diff --git a/fiori/srv/mashup.cds b/fiori/srv/mashup.cds
index 97f21771..7bc0ff47 100644
--- a/fiori/srv/mashup.cds
+++ b/fiori/srv/mashup.cds
@@ -12,6 +12,7 @@ using { sap.capire.bookshop.Books } from '@capire/bookshop';
using { ReviewsService.Reviews } from '@capire/reviews';
extend Books with {
reviews : Composition of many Reviews on reviews.subject = $self.ID;
+ numberOfReviews : Integer;
rating : Decimal;
}
diff --git a/fiori/srv/mashup.js b/fiori/srv/mashup.js
index b76252fe..6d8aa412 100644
--- a/fiori/srv/mashup.js
+++ b/fiori/srv/mashup.js
@@ -41,8 +41,8 @@ module.exports = async()=>{ // called by server.js
//
ReviewsService.on ('reviewed', (msg) => {
console.debug ('> received:', msg.event, msg.data)
- const { subject, rating } = msg.data
- return UPDATE(Books,subject).with({rating})
+ const { subject, count, rating } = msg.data
+ return UPDATE(Books,subject).with({ numberOfReviews:count, rating })
// ^ Note: the framework will execute this and take care for db.tx
})
diff --git a/reviews/srv/reviews-service.cds b/reviews/srv/reviews-service.cds
index 6e026b99..ee92bc83 100644
--- a/reviews/srv/reviews-service.cds
+++ b/reviews/srv/reviews-service.cds
@@ -8,10 +8,11 @@ service ReviewsService {
action unlike (review: type of Reviews:ID);
// Async API
- event reviewed : {
- subject: type of Reviews:subject;
- rating: Decimal(2,1)
- }
+ event reviewed : {
+ subject : type of Reviews:subject;
+ count : Integer;
+ rating : Decimal;
+ }
// Input validation
annotate Reviews with {
diff --git a/reviews/srv/reviews-service.js b/reviews/srv/reviews-service.js
index 21441df6..b9b5c6c9 100644
--- a/reviews/srv/reviews-service.js
+++ b/reviews/srv/reviews-service.js
@@ -12,11 +12,11 @@ module.exports = cds.service.impl (function(){
// Emit an event to inform subscribers about new avg ratings for reviewed subjects
this.after (['CREATE','UPDATE','DELETE'], 'Reviews', async function(_,req) {
const {subject} = req.data
- const {rating} = await cds.tx(req) .run (
- SELECT.one (['round(avg(rating),2) as rating']) .from (Reviews) .where ({subject})
+ const { count, rating } = await cds.tx(req) .run (
+ SELECT.one `round(avg(rating),2) as rating, count(*) as count` .from (Reviews) .where ({subject})
)
- global.it || console.log ('< emitting:', 'reviewed', { subject, rating })
- await this.emit ('reviewed', { subject, rating })
+ global.it || console.log ('< emitting:', 'reviewed', { subject, count, rating })
+ await this.emit ('reviewed', { subject, count, rating })
})
// Increment counter for reviews considered helpful
diff --git a/reviews/test/app/bookshop.html b/reviews/test/app/bookshop.html
new file mode 100644
index 00000000..8d1a4314
--- /dev/null
+++ b/reviews/test/app/bookshop.html
@@ -0,0 +1,3 @@
+
+
+
diff --git a/reviews/test/app/reviews.html b/reviews/test/app/reviews.html
new file mode 100644
index 00000000..00fba527
--- /dev/null
+++ b/reviews/test/app/reviews.html
@@ -0,0 +1,3 @@
+
+
+
diff --git a/reviews/test/package.json b/reviews/test/package.json
new file mode 100644
index 00000000..e93244fb
--- /dev/null
+++ b/reviews/test/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "@capire/bookshop-with-reviews",
+ "version": "1.0.0",
+ "dependencies": {
+ "@capire/bookshop": "*",
+ "@capire/reviews": "*",
+ "@sap/cds": "^5",
+ "express": "^4.17.1"
+ },
+ "cds": {
+ "requires": {
+ "db": {
+ "kind": "sql"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/reviews/test/srv/bookshop.cds b/reviews/test/srv/bookshop.cds
new file mode 100644
index 00000000..cf217bcc
--- /dev/null
+++ b/reviews/test/srv/bookshop.cds
@@ -0,0 +1,13 @@
+// Use enhanced implementation for CatalogService
+using { CatalogService } from '@capire/bookshop';
+annotate CatalogService with @impl:'srv/bookshop.js';
+
+
+// Extend Books with access to Reviews and average ratings
+using { sap.capire.bookshop.Books } from '@capire/bookshop';
+using { ReviewsService.Reviews } from '@capire/reviews';
+extend Books with {
+ reviews : Composition of many Reviews on reviews.subject = $self.ID;
+ rating : Decimal;
+ numberOfReviews : Integer;
+}
diff --git a/reviews/test/srv/bookshop.js b/reviews/test/srv/bookshop.js
new file mode 100644
index 00000000..5738b44b
--- /dev/null
+++ b/reviews/test/srv/bookshop.js
@@ -0,0 +1,27 @@
+const { CatalogService } = require('@capire/bookshop')
+const cds = require ('@sap/cds')
+
+module.exports = class extends CatalogService {async init(){
+
+ const { Books } = cds.entities('sap.capire.bookshop')
+
+ // Connect to ReviewsService to receive `reviewed` events from it
+ const ReviewsService = await cds.connect.to ('ReviewsService')
+ ReviewsService.on ('reviewed', (msg) => {
+ console.debug ('> received:', msg.event, msg.data)
+ const { subject, count, rating } = msg.data
+ return UPDATE(Books,subject).with({ numberOfReviews:count, rating })
+ })
+
+ return super.init()
+}}
+
+
+// -----------------------------------------------------------------------
+// Helper for serving static content from npm-installed packages
+const {dirname,resolve} = require('path')
+const {static} = require('express')
+cds.once('listening',()=>{
+ cds.app.use ('/app/bookshop', static (dirname (require.resolve('@capire/bookshop'))+'/app/vue'))
+ cds.app.use ('/app/reviews', static (resolve (__dirname, '../../app/vue')))
+})