Compare commits
6 Commits
build-task
...
openSAP-we
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dff5568618 | ||
|
|
20bb8d8c54 | ||
|
|
045e65487c | ||
|
|
e660e01b77 | ||
|
|
06a9ef0f5b | ||
|
|
8978799491 |
39
.vscode/launch.json
vendored
39
.vscode/launch.json
vendored
@@ -5,18 +5,45 @@
|
|||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": "bookshop", "request": "launch", "type": "node", "runtimeExecutable": "npx", "runtimeArgs": [ "-n" ],
|
"name": "bookshop",
|
||||||
"args": [ "--", "cds", "run", "--in-memory" ],
|
"request": "launch",
|
||||||
|
"type": "node",
|
||||||
|
"runtimeExecutable": "npx",
|
||||||
|
"runtimeArgs": [
|
||||||
|
"-n"
|
||||||
|
],
|
||||||
|
"args": [
|
||||||
|
"--",
|
||||||
|
"cds",
|
||||||
|
"run",
|
||||||
|
"--in-memory"
|
||||||
|
],
|
||||||
"cwd": "${workspaceFolder}/packages/bookshop",
|
"cwd": "${workspaceFolder}/packages/bookshop",
|
||||||
"console": "integratedTerminal",
|
"console": "integratedTerminal",
|
||||||
"skipFiles": ["<node_internals>/**"]
|
"skipFiles": [
|
||||||
|
"<node_internals>/**"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "cds run ...", "request": "launch", "type": "node", "runtimeExecutable": "npx", "runtimeArgs": [ "-n" ],
|
"name": "cds run ...",
|
||||||
"args": [ "--", "cds", "run", "--with-mocks", "--in-memory?" ],
|
"request": "launch",
|
||||||
|
"type": "node",
|
||||||
|
"runtimeExecutable": "npx",
|
||||||
|
"runtimeArgs": [
|
||||||
|
"-n"
|
||||||
|
],
|
||||||
|
"args": [
|
||||||
|
"--",
|
||||||
|
"cds",
|
||||||
|
"run",
|
||||||
|
"--with-mocks",
|
||||||
|
"--in-memory?"
|
||||||
|
],
|
||||||
"cwd": "${workspaceFolder}/packages/${input:service}",
|
"cwd": "${workspaceFolder}/packages/${input:service}",
|
||||||
"console": "integratedTerminal",
|
"console": "integratedTerminal",
|
||||||
"skipFiles": ["<node_internals>/**"]
|
"skipFiles": [
|
||||||
|
"<node_internals>/**"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"inputs": [
|
"inputs": [
|
||||||
|
|||||||
77
README.md
77
README.md
@@ -1,71 +1,42 @@
|
|||||||
# cloud-cap-samples
|
# Welcome to SAP Cloud Application Programming model samples
|
||||||
|
|
||||||
This is a monorepository for sample projects on [SAP Cloud Application Programming Model](https://cap.cloud.sap).
|
Find here the samples for the openSAP course [Building Applications with the SAP Cloud Application Programming Model](https://open.sap.com/courses/cp7).
|
||||||
|
|
||||||
## Description
|
## Get Access to SAP Business Application Studio
|
||||||
|
The recommended environment for the course is SAP Business Application Studio. Watch [unit 2 of week 1](https://open.sap.com/courses/cp7/items/51pzQUzbXHr2kdbOmVs6jI) for how to get access.
|
||||||
|
|
||||||
This repository provides a list of samples and reusable packages created based on SAP Cloud Application Programming Model.
|
## Setup
|
||||||
The SAP Cloud Application Programming Model enables you to quickly create business applications by allowing you to focus on your domain logic. It offers a consistent end-to-end programming model that includes languages, libraries and APIs tailored for full-stack development on SAP Cloud Platform.
|
|
||||||
|
|
||||||
The samples provided can be run in a local setup on SQLite Database.
|
In SAP Business Application Studio, open a terminal.
|
||||||
|
Then clone the repo with this specific branch:
|
||||||
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
* [Node.js](https://nodejs.org/en/) v8 or higher
|
|
||||||
* [Git](https://git-scm.com)
|
|
||||||
* [SQLite DB](https://www.sqlite.org/download.html) (Windows only; pre-installed on Mac/Linux)
|
|
||||||
|
|
||||||
#### Optional (if you want to import the code into an editor)
|
|
||||||
* [VS Code](https://code.visualstudio.com)
|
|
||||||
* [Add CDS extension to VS](https://cap.cloud.sap/docs/get-started/in-vscode#add-cds-editor)
|
|
||||||
|
|
||||||
## Download and Installation
|
|
||||||
|
|
||||||
#### Install `cds` development kit
|
|
||||||
```sh
|
```sh
|
||||||
# `@sap`-scoped packages are set via .npmrc
|
git clone https://github.com/sap-samples/cloud-cap-samples projects/cloud-cap-samples -b openSAP-week3-unit4
|
||||||
npm install -g @sap/cds-dk
|
cd projects/cloud-cap-samples
|
||||||
cds #> test-run it
|
|
||||||
```
|
```
|
||||||
Got issues? Check out the [documentation](https://cap.cloud.sap/docs/get-started/).
|
|
||||||
|
|
||||||
#### Clone and build the application
|
In the `cloud-cap-samples` folder run:
|
||||||
`git clone https://github.com/SAP-samples/cloud-cap-samples samples && cd samples && npm i`
|
```sh
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
#### Run the samples
|
## Run
|
||||||
|
|
||||||
With that you're ready to run the samples, e.g. start the [_bookshop_](./packages/bookshop) sample as follows:
|
Now you're ready to run the samples, for example:
|
||||||
|
```sh
|
||||||
|
cd packages/bookshop
|
||||||
|
cds watch
|
||||||
|
```
|
||||||
|
|
||||||
`npm run bookshop`
|
After that, watch out for the little popup in the lower right corner of SAP Business Application Studio that asks you to open the application in your browser.
|
||||||
|
|
||||||
## Test
|
|
||||||
|
|
||||||
For example, try these links in your browser:
|
|
||||||
- <http://localhost:4004> to test with generic index page.
|
|
||||||
- <http://localhost:4004/fiori.html> to test with Fiori sandbox.
|
|
||||||
|
|
||||||
|
|
||||||
## Debug
|
## Get Support
|
||||||
|
|
||||||
For example, in [VS Code](https://code.visualstudio.com) switch to _Debug_ view and launch one of the prepared _cds run_ launch configurations.
|
Check out the cap docs at https://cap.cloud.sap. <br>
|
||||||
|
In case you find a bug or need support, please [open an issue in here](https://github.com/SAP-samples/cloud-cap-samples/issues/new).
|
||||||
|
|
||||||
|
|
||||||
## Limitations
|
|
||||||
|
|
||||||
None
|
|
||||||
|
|
||||||
## Known Issues
|
|
||||||
|
|
||||||
None
|
|
||||||
|
|
||||||
## How to obtain support
|
|
||||||
|
|
||||||
Check out the documentation on https://cap.cloud.sap. In case you find a bug, or you need additional support, please open an issue [here](https://github.com/SAP-samples/cloud-cap-samples/issues/new) in GitHub.
|
|
||||||
|
|
||||||
## To-Do (upcoming changes)
|
|
||||||
|
|
||||||
None
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under SAP Sample Code License Agreement, except as noted otherwise in the [LICENSE](/LICENSE) file.
|
Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under SAP Sample Code License Agreement, except as noted otherwise in the [LICENSE](/LICENSE) file.
|
||||||
|
|||||||
2064
package-lock.json
generated
Normal file
2064
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
11
package.json
11
package.json
@@ -8,16 +8,11 @@
|
|||||||
"lerna": "npx --no-install lerna -v > /dev/null || npm i lerna --no-save",
|
"lerna": "npx --no-install lerna -v > /dev/null || npm i lerna --no-save",
|
||||||
"install": "(npm -s run lerna) && lerna bootstrap --hoist",
|
"install": "(npm -s run lerna) && lerna bootstrap --hoist",
|
||||||
"cleanup": "lerna clean -y && rm -fr node_modules",
|
"cleanup": "lerna clean -y && rm -fr node_modules",
|
||||||
"bookshop": "cds watch packages/bookshop",
|
"bookshop": "cds watch packages/bookshop"
|
||||||
"bookshop-enhanced": "cds watch packages/bookshop-enhanced",
|
|
||||||
"reviews-service": "cds watch packages/reviews-service",
|
|
||||||
|
|
||||||
"bookstore": "cds watch packages/bookstore",
|
|
||||||
"media-server": "cds watch packages/media-server"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sap/cds": "latest",
|
"@sap/cds": "^3",
|
||||||
"express": "*"
|
"express": "^4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"sqlite3": "*"
|
"sqlite3": "*"
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
using from '@sap/capire-bookshop/app';
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
In this model we demonstrate how to add Genres to Books in
|
|
||||||
as if it was an external extension. For example we use
|
|
||||||
CDS Aspects' to extend the core domain model's Books entity
|
|
||||||
as well as the AdminService.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace sap.capire.bookshop;
|
|
||||||
using { sap.capire.reviews.ReviewsService as external } from '@sap/capire-reviews';
|
|
||||||
using { sap.capire.bookshop.Books } from '@sap/capire-bookshop/db/schema';
|
|
||||||
using { sap.common.CodeList } from '@sap/cds/common';
|
|
||||||
|
|
||||||
// Extending Books by Reviews and Genres
|
|
||||||
extend Books with {
|
|
||||||
reviews : Composition of many external.Reviews on reviews.subject = ID;
|
|
||||||
rating : external.Reviews.rating;
|
|
||||||
genre : Association to Genres;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hierarchical Code List for Genres
|
|
||||||
entity Genres : CodeList {
|
|
||||||
key ID : Integer;
|
|
||||||
children : Composition of many Genres on children.parent = $self;
|
|
||||||
parent : Association to Genres;
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@sap/capire-bookshop-enhanced",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"description": "A sample for extending a base application package, in this case bookshop, e.g. in context of verticalization or customization.",
|
|
||||||
"repository": "https://github.com/SAP-samples/cloud-cap-samples.git",
|
|
||||||
"license": "SAP SAMPLE CODE LICENSE",
|
|
||||||
"dependencies": {
|
|
||||||
"@sap/capire-bookshop": "^1.0.0",
|
|
||||||
"@sap/capire-reviews": "^1.0.0",
|
|
||||||
"@sap/cds": "latest",
|
|
||||||
"express": "*"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"reviews-service": "PORT=5005 cds run ../reviews-service --bind --in-memory?",
|
|
||||||
"start": "cds run --in-memory?",
|
|
||||||
"watch": "cds watch"
|
|
||||||
},
|
|
||||||
"cds": {
|
|
||||||
"requires": {
|
|
||||||
"sap.capire.reviews.ReviewsService": {
|
|
||||||
"kind": "odata",
|
|
||||||
"model": "@sap/capire-reviews"
|
|
||||||
},
|
|
||||||
"messaging": {
|
|
||||||
"kind": "file-based-messaging"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
namespace sap.capire.bookshop;
|
|
||||||
|
|
||||||
using { AdminService } from '@sap/capire-bookshop/srv/admin-service';
|
|
||||||
using { sap.capire.bookshop } from '../db/schema';
|
|
||||||
|
|
||||||
@impl:'srv/services'
|
|
||||||
extend service AdminService with {
|
|
||||||
entity Genres as projection on bookshop.Genres;
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
const cds = require ('@sap/cds')
|
|
||||||
|
|
||||||
module.exports = cds.service.impl (async()=>{
|
|
||||||
|
|
||||||
const ReviewsService = await cds.connect.to ('sap.capire.reviews.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
|
|
||||||
|
|
||||||
CatalogService.impl (srv => {
|
|
||||||
// delegate requests to read reviews to ReviewsService
|
|
||||||
srv.on ('READ', 'Books/reviews', (req) => {
|
|
||||||
const [ subject ] = req.params
|
|
||||||
const tx = ReviewsService.transaction (req)
|
|
||||||
return tx.run (SELECT.from (Reviews) .where ({subject}))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// react on event messages from reviews service
|
|
||||||
ReviewsService.on ('reviewed', (msg) => {
|
|
||||||
console.debug ('> received:', msg.event, msg.data)
|
|
||||||
const { subject, rating } = msg.data
|
|
||||||
const tx = db // TODO: db.transaction (msg)
|
|
||||||
return tx.run (UPDATE (Books, subject) .with ({rating}))
|
|
||||||
// return tx.update (Books, subject) .with ({rating})
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
#################################################
|
|
||||||
#
|
|
||||||
# Genres
|
|
||||||
#
|
|
||||||
|
|
||||||
GET http://localhost:4004/admin/Genres?
|
|
||||||
###
|
|
||||||
|
|
||||||
POST http://localhost:4004/admin/Genres?
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{ "ID":100, "name":"Some Sample Genres...", "children":[
|
|
||||||
{ "ID":101, "name":"Cat", "children":[
|
|
||||||
{ "ID":102, "name":"Kitty", "children":[
|
|
||||||
{ "ID":103, "name":"Kitty Cat", "children":[
|
|
||||||
{ "ID":104, "name":"Aristocat" } ]},
|
|
||||||
{ "ID":105, "name":"Kitty Bat" } ]},
|
|
||||||
{ "ID":106, "name":"Catwoman", "children":[
|
|
||||||
{ "ID":107, "name":"Catalina" } ]} ]},
|
|
||||||
{ "ID":108, "name":"Catweazle" }
|
|
||||||
]}
|
|
||||||
###
|
|
||||||
|
|
||||||
GET http://localhost:4004/admin/Genres(100)?
|
|
||||||
# &$expand=children
|
|
||||||
# &$expand=children($expand=children($expand=children($expand=children)))
|
|
||||||
###
|
|
||||||
|
|
||||||
DELETE http://localhost:4004/admin/Genres(103)
|
|
||||||
###
|
|
||||||
|
|
||||||
DELETE http://localhost:4004/admin/Genres(100)
|
|
||||||
###
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
#################################################
|
|
||||||
#
|
|
||||||
# Reviews Service
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
### 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":"5", "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
|
|
||||||
|
|
||||||
### 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
|
|
||||||
@@ -1,14 +1,25 @@
|
|||||||
{
|
{
|
||||||
"name": "@sap/capire-bookshop",
|
"name": "@sap/capire-bookshop",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "A simple bookshop application, build in a self-contained all-in-one fashion, i.e. w/o reusing other packages.",
|
"description": "A simple bookshop application, build in a self-contained all-in-one fashion, i.e. w/o reusing other packages.",
|
||||||
"license": "SAP SAMPLE CODE LICENSE",
|
"license": "SAP SAMPLE CODE LICENSE",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sap/cds": "latest",
|
"@sap/cds": "^3",
|
||||||
"express": "*"
|
"express": "^4"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "cds run --in-memory?",
|
"start": "cds run --in-memory?",
|
||||||
"watch": "cds watch"
|
"watch": "cds watch"
|
||||||
}
|
},
|
||||||
|
"cds": {
|
||||||
|
"requires": {
|
||||||
|
"db": {
|
||||||
|
"model": [
|
||||||
|
"db",
|
||||||
|
"srv"
|
||||||
|
],
|
||||||
|
"kind": "sqlite"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
ID;firstname;lastname;dateOfBirth;placeOfBirth;dateOfDeath;placeOfDeath
|
|
||||||
101;Emily;Brontë;1818-07-30;Thornton, Yorkshire;1848-12-19;Haworth, Yorkshire
|
|
||||||
107;Charlotte;Brontë;1818-04-21;Thornton, Yorkshire;1855-03-31;Haworth, Yorkshire
|
|
||||||
150;Edgar Allen;Poe;1809-01-19;Boston, Massachusetts;1849-10-07;Baltimore, Maryland
|
|
||||||
170;Richard;Carpenter;1929-08-14;King’s Lynn, Norfolk;2012-02-26;Hertfordshire, England
|
|
||||||
|
500 Internal Server Error
Gitea Version: 1.24.4 |