Updated reviews samples for messaging GA
This commit is contained in:
@@ -34,7 +34,7 @@
|
|||||||
<td>{{ book.author }}</td>
|
<td>{{ book.author }}</td>
|
||||||
<td>{{ book.genre.name }}</td>
|
<td>{{ book.genre.name }}</td>
|
||||||
<td class="rating-stars">
|
<td class="rating-stars">
|
||||||
{{ ('★'.repeat(Math.round(book.rating))+'☆☆☆☆☆').slice(0,5) }}
|
{{ ('★'.repeat(Math.round(book.rating))+'☆☆☆☆☆').slice(0,5) }} ({{ book.numberOfReviews }})
|
||||||
</td>
|
</td>
|
||||||
<td>{{ book.currency && book.currency.symbol }} {{ book.price }}</td>
|
<td>{{ book.currency && book.currency.symbol }} {{ book.price }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
exports.CatalogService = require('./srv/cat-service')
|
const { CatalogService } = require('./srv/cat-service')
|
||||||
|
module.exports = { CatalogService }
|
||||||
|
|||||||
@@ -38,6 +38,11 @@
|
|||||||
"[production]": {
|
"[production]": {
|
||||||
"model": "db/hana"
|
"model": "db/hana"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"messaging": {
|
||||||
|
"[development]": { "kind": "file-based-messaging" },
|
||||||
|
"[hybrid]": { "kind": "enterprise-messaging-shared" },
|
||||||
|
"kind": "enterprise-messaging"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ using { sap.capire.bookshop.Books } from '@capire/bookshop';
|
|||||||
using { ReviewsService.Reviews } from '@capire/reviews';
|
using { ReviewsService.Reviews } from '@capire/reviews';
|
||||||
extend Books with {
|
extend Books with {
|
||||||
reviews : Composition of many Reviews on reviews.subject = $self.ID;
|
reviews : Composition of many Reviews on reviews.subject = $self.ID;
|
||||||
|
numberOfReviews : Integer;
|
||||||
rating : Decimal;
|
rating : Decimal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ module.exports = async()=>{ // called by server.js
|
|||||||
//
|
//
|
||||||
ReviewsService.on ('reviewed', (msg) => {
|
ReviewsService.on ('reviewed', (msg) => {
|
||||||
console.debug ('> received:', msg.event, msg.data)
|
console.debug ('> received:', msg.event, msg.data)
|
||||||
const { subject, rating } = msg.data
|
const { subject, count, rating } = msg.data
|
||||||
return UPDATE(Books,subject).with({rating})
|
return UPDATE(Books,subject).with({ numberOfReviews:count, rating })
|
||||||
// ^ Note: the framework will execute this and take care for db.tx
|
// ^ Note: the framework will execute this and take care for db.tx
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,11 @@ service ReviewsService {
|
|||||||
action unlike (review: type of Reviews:ID);
|
action unlike (review: type of Reviews:ID);
|
||||||
|
|
||||||
// Async API
|
// Async API
|
||||||
event reviewed : {
|
event reviewed : {
|
||||||
subject: type of Reviews:subject;
|
subject : type of Reviews:subject;
|
||||||
rating: Decimal(2,1)
|
count : Integer;
|
||||||
}
|
rating : Decimal;
|
||||||
|
}
|
||||||
|
|
||||||
// Input validation
|
// Input validation
|
||||||
annotate Reviews with {
|
annotate Reviews with {
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ module.exports = cds.service.impl (function(){
|
|||||||
// Emit an event to inform subscribers about new avg ratings for reviewed subjects
|
// Emit an event to inform subscribers about new avg ratings for reviewed subjects
|
||||||
this.after (['CREATE','UPDATE','DELETE'], 'Reviews', async function(_,req) {
|
this.after (['CREATE','UPDATE','DELETE'], 'Reviews', async function(_,req) {
|
||||||
const {subject} = req.data
|
const {subject} = req.data
|
||||||
const {rating} = await cds.tx(req) .run (
|
const { count, rating } = await cds.tx(req) .run (
|
||||||
SELECT.one (['round(avg(rating),2) as rating']) .from (Reviews) .where ({subject})
|
SELECT.one `round(avg(rating),2) as rating, count(*) as count` .from (Reviews) .where ({subject})
|
||||||
)
|
)
|
||||||
global.it || console.log ('< emitting:', 'reviewed', { subject, rating })
|
global.it || console.log ('< emitting:', 'reviewed', { subject, count, rating })
|
||||||
await this.emit ('reviewed', { subject, rating })
|
await this.emit ('reviewed', { subject, count, rating })
|
||||||
})
|
})
|
||||||
|
|
||||||
// Increment counter for reviews considered helpful
|
// Increment counter for reviews considered helpful
|
||||||
|
|||||||
3
reviews/test/app/bookshop.html
Normal file
3
reviews/test/app/bookshop.html
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<head>
|
||||||
|
<meta http-equiv="refresh" content="0;url=app/bookshop/index.html">
|
||||||
|
</head>
|
||||||
3
reviews/test/app/reviews.html
Normal file
3
reviews/test/app/reviews.html
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<head>
|
||||||
|
<meta http-equiv="refresh" content="0;url=app/reviews/index.html">
|
||||||
|
</head>
|
||||||
17
reviews/test/package.json
Normal file
17
reviews/test/package.json
Normal file
@@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
13
reviews/test/srv/bookshop.cds
Normal file
13
reviews/test/srv/bookshop.cds
Normal file
@@ -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;
|
||||||
|
}
|
||||||
27
reviews/test/srv/bookshop.js
Normal file
27
reviews/test/srv/bookshop.js
Normal file
@@ -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')))
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user