Separated reviewed and reviews

This commit is contained in:
Daniel
2020-05-29 16:56:03 +02:00
parent 0a552b4346
commit 6f9737ae38
6 changed files with 25 additions and 30 deletions

16
reviewed/db/schema.cds Normal file
View File

@@ -0,0 +1,16 @@
//
// 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;
}
// Temporary workaround for cap/issues#4112:
annotate Reviews with @cds.autoexpose;

23
reviewed/package.json Normal file
View File

@@ -0,0 +1,23 @@
{
"name": "@capire/bookshop-with-reviews",
"version": "1.0.0",
"dependencies": {
"@capire/bookshop": "../bookshop",
"@capire/reviews": "../reviews",
"@sap/cds": "^3.33.1",
"express": "^4.17.1"
},
"cds": {
"requires": {
"db": {
"kind": "sql"
},
"ReviewsService": {
"kind": "odata", "model": "@capire/reviews"
},
"messaging": {
"kind": "file-based-messaging"
}
}
}
}

55
reviewed/server.js Normal file
View File

@@ -0,0 +1,55 @@
////////////////////////////////////////////////////////////////////////////
//
// This is an example of using a project-local server.js to intercept
// the default bootstrapping process.
//
const cds = require ('@sap/cds')
// Mashup services after all are served...
cds.once('served', async()=>{
// react on event messages from reviews service
const ReviewsService = await cds.connect.to ('ReviewsService')
const db = await cds.connect.to ('db')
// reflect entities required below...
const { Books } = db.entities('sap.capire.bookshop')
const { Reviews } = ReviewsService.entities
ReviewsService.on ('reviewed', (msg) => {
console.debug ('> received:', msg.event, msg.data)
const { subject, rating } = msg.data
const tx = db.tx (msg) // TODO: db.tx(msg) fully implemented?
return tx.update (Books,subject) .with ({rating})
})
// delegate requests to read reviews to ReviewsService
const CatalogService = await cds.connect.to ('CatalogService')
CatalogService.impl (srv => srv.on ('READ', 'Books/reviews', (req) => {
console.debug ('> delegating to ReviewsService')
const [ id ] = req.params
const tx = ReviewsService.tx(req)
return tx.read (Reviews) .where ({ subject: String(id) })
.columns (req.query.SELECT.columns)
}))
})
// Other bootstrapping events you could hook in to...
/* eslint-disable no-unused-vars */
cds.on('bootstrap',(app) => {/* ... */})
cds.on('loaded', (model) => {/* ... */})
cds.on('connect', (srv) => {/* ... */})
cds.on('serving', (srv) => {/* ... */})
cds.once('listening', ({server,url}) => {/* ... */})
// Delegate bootstrapping to built-in server.js
module.exports = cds.server
// Monkey-patching older releases
if (cds.version < '3.33.4') cds.once('listening', ()=> cds.emit('served'))
// Launch server if started directly from command-line
if (!module.parent) cds.server()

View File

@@ -0,0 +1,40 @@
#################################################
#
# To ReviewsService
#
# move the right down:
@reviews-service = http://localhost:4004/reviews
@reviews-service = http://localhost:5005/reviews
### Get all reviews
GET {{reviews-service}}/Reviews
### Add a new review (with random rating)
POST {{reviews-service}}/Reviews
Content-Type: application/json;IEEE754Compatible=true
{"subject":"201", "title":"boo"}
#################################################
#
# Bookshop Requests involving reviews
# (both in-process as well as separate one)
#
@bookshop = http://localhost:4004
### Request to CatalogService > delegated to ReviewsService
GET {{bookshop}}/browse/Books(201)/reviews?
&$select=rating,date,reviewer,title
### Alternative OData URL
GET {{bookshop}}/browse/Books/201/reviews?
&$select=rating,date,reviewer,title
###
GET {{bookshop}}/browse/Books(201)?
&$select=ID,title,rating
&$expand=reviews
# Note: the $expand only works in case of ReviewsService in same process