SampleSampletypeA worked example you read or clone. Evidence: it demonstrates, it never provides.See every one →What this type is →by SAPby SAPoriginPublished by SAP itself. A visible facet, never an input to a reading — a dormant official plugin reads exactly like a dormant independent one.See every one →Starting point

SAP-samples/cloud-cap-hana-swapi

A CAP data model demonstrating bi-directional, many-to-many relationships, built on the SWAPI Star Wars dataset extended with TV shows and streaming series and loadable into SQLite, HANA or PostgreSQL.

Many-to-many relationships across a non-trivial dataset are hard to model well, and this rebuilds the old SWAPI Star Wars dataset as a CAP data model to practise it: people, films, species, starships, vehicles and planets, each linked in both directions. It extends the original with a Show entity for TV and streaming productions, an Episode composition beneath each show, and six read-only UNION ALL views that unify films and shows behind one query surface. The data comes from a two-step pipeline — a rate-limited Wookieepedia scraper with a committed cache, then a load step into SQLite, HANA or PostgreSQL — so the model can be explored without live scraping. It stops at the data layer and a generated Fiori preview UI; there is no bespoke application on top.

Facts

Last pushLicenceApache-2.0

Where it sits

Lives in
Demonstrates
Data modellingCAPData modellingcapabilityDefining the shape of data before anything serves it: entities and their types, how they relate, and the projections and views that services and applications consume.
Flavors

Who is behind it

SAP SamplesSAP SamplesOrganisationMaintains this
In the atlas: maintains 222
@SAP-samples
maintainerAjinkya PatilPersonContributes to this
In the atlas: contributes to 112
@ajinkyapatil8190
Brian BernardPersonContributes to this
In the atlas: contributes to 64
@btbernard
Thomas JungPersonContributes to this
Developer Advocate
In the atlas: contributes to 15, wrote 6
@jung-thomas
Marian ZeisPersonContributes to this
In the atlas: maintains 35, contributes to 86, wrote 25
@marianfoo
Patrice BenderPersonContributes to this
In the atlas: contributes to 11
@patricebender
5 contributors

What it declares

Every artifact

Type
Sample
Origin
By SAP

As a sample

Form
does not say

Connections1

SAP-samples/cloud-cap-hana-swapi connectionsSAP-samples/cloud-cap-hana-swapiPROVIDES→ demonstrates1demonstrates authoredData modelling

ArchitectureBetaRead from the sample's deployment descriptor. Some of the connections it states are not drawn yet.

as cap/mta.yaml states it at 913fbde, read
SAP BTP, Cloud Foundry Runtimecap-hana-swapiSAP clouddocumentedoutbounddocumentedoutboundcap-hana-swapi-srv, nodejscap-hana-swapi-srvnotification-content-deployment, nodejsnotification-content…cap-hana-swapi-db, hdbcap-hana-swapi-dbhana, hana, hdi-sharedhanastarwars-auditlog-service, service instancestarwars-auditlog-se…SAP Application Logging service for SAP BTP, application-logs, standardSAP ApplicationLogging servicefor SAP BTPSAP Destination service, destination, liteSAP DestinationserviceEvent Mesh, enterprise-messaging, defaultEvent MeshSAP Cloud ALM, SAP solutionSAP Cloud ALMSAP solution
SAPnot SAP's, or the project's owndocumented only

Bound, and not drawn

Documented, with no instance in the document

Bound in the descriptor, not joined to an entry

hana

README

quoted from SAP-samples/cloud-cap-hana-swapi under Apache-2.0, read
SAP-samples/cloud-cap-hana-swapi/README.mdOn GitHub

cloud-cap-hana-swapi - bi-directional, many-to-many SAP Cloud Application Programming Model example

REUSE status

Description

SWAPI - the Star Wars API. This sample is based upon the sample at swapi.dev which in turn was based upon swapi.co. The original source can be found at https://github.com/Juriy/swapi.

The original project was a data set and data model based in Python that exposed data from the Star Wars movies sourced originally from the community wiki: Wookiepedia. It encompasses data about the People, Films, Species, Starships, Vehicles and Planets from Star Wars.

The projects described above have fallen out of maintenance but still offered the opportunity for a fun yet challenging learning experience from a non-trivial data model. The many bi-directional, many-to-many relationships with the data provides a good basis for an SAP Cloud Application Programming Model and Fiori Draft UI sample.

This project extends the original data set with TV Shows and streaming series (The Mandalorian, The Clone Wars, Andor, etc.) scraped live from Wookieepedia, and introduces unified Media views that query across both films and shows.

Data Model
Films

film diagram

Shows (TV Series & Streaming)

The Show entity represents all canon Star Wars TV and streaming productions. It shares the same relationship structure as Film — each show can be linked to characters, planets, starships, vehicles, and species.

FieldTypeNotes
titleString@mandatory
show_typeEnumLIVE_ACTION_SERIES, ANIMATED_SERIES, ANIMATED_FILM, ANTHOLOGY
seasonsIntegerNumber of seasons
episode_countIntegerTotal episode count
networkStringBroadcaster / streaming platform
directorStringLead director(s)
producerStringLead producer(s)
release_dateDateFirst air date

Each show owns a composition of Episode records (cascade-delete). The Episode entity captures per-episode metadata: season_number, episode_number, title, air_date, director, writer, runtime (minutes), and timeline (in-universe date, e.g. "19 BBY").

Junction tables: Show2People (physical), Episode2People, Episode2Planets, Episode2Starships, Episode2Vehicles, Episode2Species

Show2Planets, Show2Starships, Show2Vehicles, and Show2Species are CDS define view declarations that aggregate over the corresponding Episode2* tables. They are not physical tables — show-level relationship data is derived from episode-level scraping.

Unified Media Views

Six read-only UNION ALL views join Film and Show data across a single query surface. The relationship views each include a branch for Episode2* data so that episode-level associations are surfaced at the media level:

ViewReturns
MediaAll films and shows with a media_type discriminator ('FILM' / 'SHOW')
MediaCharactersAll film+show+episode → character relationships
MediaPlanetsAll film+show+episode → planet relationships
MediaSpeciesAll film+show+episode → species relationships
MediaStarshipsAll film+show+episode → starship relationships
MediaVehiclesAll film+show+episode → vehicle relationships
People

people diagram

Planets

planet diagram

Species

species diagram

Starships

starships diagram

Vehicles

vehicles diagram

Requirements

Download and Installation

The rest of the operations can be performed within the cap folder and there are scripts in the package.json file for major operations.

You can use npm run build to perform the cds build and should be run before deployment to HANA or whenever you make changes to the data model.

You can run npm run hana to deploy the content to your HANA database. Just be sure from the terminal that you are logged into the cf/xs cli and targeting the Account/Org/Space where you want the content to live. By default this command will create an HDI Container instance named starwars. Note: due to some strange circumstances in the latest versions of CAP it seems the /gen/srv folder is getting cleared after any deployment to HANA. Therefore just execute a cds build or npm run build after any deployment to restore the /gen folder until we find the root cause of this issue.

Data Pipeline

Star Wars data is sourced from Wookieepedia via a rate-limited MediaWiki API scraper. The pipeline is two steps:

Step 1 — Scrape (optional — committed cache makes this instantaneous):

cd cap
npm run scrape              # cache-first run — uses committed cache, completes in seconds
npm run scrape:films        # films-only run (no episodes); reproduces the original SWAPI dataset
npm run scrape:bypass-cache # fetch fresh data from Wookieepedia (prompts for confirmation)

The scraper crawls three levels deep: Show page → Season page → Episode page. It writes nine JSON files to scripts/data/raw/: films.json, shows.json, episodes.json, people.json, planets.json, species.json, starships.json, vehicles.json, relationships.json

Cache files (scripts/data/cache/) are committed to the repository (~6,469 files), so clones can run npm run scrape without any network access. Use --bypass-cache only when you need genuinely fresh Wookieepedia data.

Step 2 — Load into your target database:

npm run load_sqlite    # SQLite (local development)
npm run load           # SAP HANA Cloud (hybrid profile — requires .cdsrc-private.json)
npm run load_pg        # PostgreSQL

The loading script is convertData.js. It reads the raw JSON files and upserts all entities and junction records using CAP CQL.

Scraped data included:

  • 11 canon films — Episodes I–IX, Rogue One, Solo (with directors, producers, release dates)
  • 15 shows — 8 live-action series + 6 animated series (The Mandalorian, The Clone Wars, Andor, Rebels, etc.)
  • 772 episodes — per-episode metadata and entity relationships (characters, planets, starships, vehicles, species)

The command npm start or cds run will start the service running locally. It will open the standard CAP test page where you can explore the OData Services or the Fiori UI.

From the Cloud Application Programming Model preview (which opens locally when using npm start or cds run), you can access the Swagger UI test tool (with entity diagrams), test the OData services or metadata calls directly in the browser, or access the Fiori preview UI for each of the main entities.

CDS Test Page

Fiori Preview List

Fiori Preveiw Overview Edit

Upgrade Notes

  • Breaking change: legacy value-help helper endpoints were removed in favor of *Values entities.
  • Migration details and endpoint mapping are documented in:

Known Issues

If you receive an error like the following when running the convertData script

[Error: SQLITE_BUSY: database is locked] {
  errno: 5,
  code: 'SQLITE_BUSY',
  query: 'DELETE FROM star_wars_People'
}

This is caused by the parallel nature of the loading of the data in SQLite. The default script with its parallel loading works fine when you use HANA as the target persistence. However if you are using SQLite for your tempoary testing persistence, then you can use the alternative convertDataLite script instead.

Note: due to some strange circumstances in the latest versions of CAP it seems the /gen/srv folder is getting cleared after any deployment to HANA. Therefore just execute a cds build or npm run build after any deployment to restore the /gen folder until we find the root cause of this issue.

How to obtain support

This project is provided "as-is": there is no guarantee that raised issues will be answered or addressed in future releases.

License

Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved. This project is licensed under the Apache Software License, version 2.0 except as noted otherwise in the LICENSE file.

Star Wars and all associated names are copyright Lucasfilm ltd. All data in this sample has been freely collected from open sources such as Wookiepedia under CC-BY-SA .

Apache-2.0, read

History

Latest

v2.1.0

Other 11

Notes

Changed

  • Upgrade to SAP CAP 10: @sap/cds from 9.9.1 to 10.0.3 (@sap/cds-compiler 7.0.1)
  • Update @cap-js/sqlite from 2.x to 3.0.2, @cap-js/hana from 2.x to 3.0.1, @cap-js/postgres from 2.x to 3.0.1 (CAP 10 driver majors)
  • Update @cap-js/telemetry from 1.x to 2.0.1
  • Update @cap-js/change-tracking to 2.0.2, @cap-js-community/odata-v2-adapter to 1.16.0, @cap-js/ord to 1.9.1, @sap/cds-common-content to 3.2.0
  • Update eslint to 10.7.0 and @sap/dev-cap-tools to 1.53.4
  • Remove CAP 10-obsolete feature flags from .cdsrc.json (ieee754compatible, consistent_params, compat_srv_getters, compat_texts_entities, compat_assert_not_null, compat_save_drafts, calc_elements) — now defaults or removed in CAP 10
  • Simplify cds.requires.queue to true (legacyLocking flag obsolete in CAP 10)
  • Scraper: replace axios with Node.js native fetch in mediawiki.js, preserving throttle, 15s AbortController timeout, and 429/503 retry/backoff — removes axios and unused uuid dependency (clears 10 Dependabot alerts, npm audit reports 0 vulnerabilities)

Fixed

  • Scraper normalizeDate returned a date one day early in any timezone ahead of UTC — locale date strings (e.g. "May 25, 1977") parsed as local midnight but were formatted via toISOString(); now formatted from the matching parse frame, verified timezone-independent from UTC-12 to UTC+14
  • Scraper extractor test fixtures updated to the {{App}} (films) and {{Credits}} (shows) template formats the extractors actually read, and a stale normalizeInteger ordinal-word assertion corrected — full scraper suite now 87/87 passing

Removed

  • Empty 0-byte cap/db/src/TEST.hdbcalculationview scratch file that caused HANA HDI deployment to fail with an XML parse error
  1. v2.0.2

    Other 19

    Notes

    Changed

    • Update @sap/cds from 9.8.5 to 9.9.1
    • Update @cap-js/cds-test from 0.4.1 to 1.0.1 (stable release)
    • Update eslint from 10.2.1 to 10.3.0
    • Update @cap-js/hana from 2.7.0 to 2.8.0
    • Update @cap-js/sqlite from 2.2.0 to 2.4.0
    • Update @cap-js/postgres from 2.2.0 to 2.3.0
    • Update @sap/cds-common-content from 3.1.0 to 3.2.0
    • Update @sap/dev-cap-tools from 1.53.2 to 1.53.3
    • Update @cap-js/change-tracking from 1.2.1 to 2.0.0-beta.11 (trigger-based architecture with ~2.4-50x performance improvement)
    • Update site dependencies (mermaid 11.13→11.14, vue 3.5.31→3.5.33)
    • Update scraper dependencies (axios 1.14→1.15)
    • Raise minimum Node.js version from 20 to 22 (CDS 10 requirement)
    • Enable CDS 10 forward-compatibility flags: ieee754compatible, consistent_params, compat_srv_getters, compat_texts_entities, compat_assert_not_null, compat_save_drafts, calc_elements
    • Disable legacy queue locking (queue.legacyLocking: false) in preparation for CDS 10
    • Add HANA migration table (sap.changelog.Changes.hdbmigrationtable) for change-tracking v2 schema migration
    • Enable native node:sqlite driver (driver: "node") — uses Node.js built-in SQLite instead of better-sqlite3
    • Enable parallel $batch GET processing (max_batch_parallelization: 3) for concurrent read-only batch atomicity groups

    Added

    • cds-test-v1.test.js — showcase test demonstrating @cap-js/cds-test v1.0 features: Chai assertions, Fetch-based HTTP shortcuts, native sqlite verification
    • @cap-js/ord plugin (v1.6.0) — exposes Open Resource Discovery endpoints (/.well-known/open-resource-discovery, /ord/v1/documents/ord-document) for machine-readable application metadata
  2. v2.0.0

    Other 49

    Notes

    Added

    • Episode entity and Episode2* junction tables (Episode2People, Episode2Planets, Episode2Starships, Episode2Vehicles, Episode2Species) as compositions of Show
    • StarWarsEpisode service exposing Episode and Episode2* projections as read-only
    • Show2Planets, Show2Starships, Show2Vehicles, Show2Species replaced by CDS derived views aggregating over Episode2* tables
    • Wookieepedia scraper pipeline: rate-limited MediaWiki API client, disk cache, entity/episode/season extractors, orchestrator, and CLI
    • Full scrape of 11 films and 15 shows with 772 episodes and episode relationships from Wookieepedia
    • Episode data fields: director, writer, season_number, episode_number, air_date, opening_crawl, show title association
    • Clone Wars chronological episode ordering in StarWarsEpisode service
    • Opening crawl texts for main Star Wars saga films
    • Film.episode_id populated from roman numeral in Wookieepedia page title
    • Sub-series pages (e.g. Tales anthology) registered as shows and their episodes correctly attributed
    • Second-pass entity scrape to resolve entities discovered via episode back-references
    • Virtual edit_url field on Media projection in StarWarsShow service, computed by handler
    • Star Wars Media Browser Fiori webapp (list report + object page)
    • Star Wars Films Fiori webapp (list report + object page)
    • Star Wars Shows Fiori webapp with Episodes sub-navigation tab
    • Fiori launchpad page with People, Films, and Shows tiles
    • i18n labels and value helps for Media entity type selection fields
    • Fiori annotations for Media list report and object page
    • VitePress documentation site with animated Star Wars opening crawl homepage, Imperial Dark and Jedi Archives CSS themes, CDS syntax highlighting, and GitHub Pages CI deployment
    • MIDI audio (Imperial March, Jedi Theme) and hexagon SVG logos for VitePress themes
    • VitePress Apps section with per-app documentation pages (People, Media Browser, Film editor, Show/Episode editor) and API overview page
    • Shows & Episodes section in VitePress API sidebar with architecture deep-dive
    • Generated @cds-models type definitions for all services (DataService, StarWarsEpisode, StarWarsFilm, StarWarsPeople, StarWarsPlanet, StarWarsShow, StarWarsSpecies, StarWarsStarship, StarWarsVehicle)
    • readme.mjs custom widdershins wrapper with circular $ref handling to prevent stack overflow during OpenAPI→Markdown generation
    • Generated OpenAPI 3.0 specifications for all services (OData v4 and REST variants)
    • Viewer app Galaxy/Light CSS themes with responsive layout, sort, filter, column-level search, and pagination
    • Viewer app detail panel with field-by-field display and keyboard navigation (arrow keys, Escape)
    • Viewer app row selection with clipboard copy (Tab-delimited), persisted rowKey cleared on entity switch or panel dismiss
    • jsconfig.json for CAP service layer IDE support
    • CAP Cheat Sheet expanded with detailed CDS modeling patterns, handler registration, and common pitfalls

    Changed

    • convertData.js rewritten to load flat JSON from scripts/data/raw instead of Django fixtures, with parallel chunk loading and SQLite-safe sequencing
    • Episode loading added to data pipeline; Show2* physical table inserts removed (now derived views)
    • Scraper: episode titles extracted from table rows (not all section wikilinks); season links scoped to level-2/3 headings; show attribution uses episode infobox series field filtered by show title
    • Episode.director and Episode.writer use unbounded String (no length limit)
    • normalizeInteger extended to parse ordinal words (One, Two, …) for season_number
    • Migration handling updated and Episode Fiori annotations improved
    • VitePress copy-content pipeline updated to support Fiori app docs, API restructure, and front-matter title extraction
    • VitePress nav/sidebar restructured: added Apps section, split API into per-service pages, added Shows & Episodes
    • CI docs workflow now also triggers on cap/README.md changes
    • Viewer app index.html rewritten with SRI hashes on all CDN resources, Content-Security-Policy meta tag, and viewport meta
    • README updated with current project structure, Fiori app descriptions, and revised pitfalls section

    Fixed

    • Cross-show episode attribution prevented by filtering extractSeasonLinks to the current show title
    • Anthology shows (Tales) without season sub-pages now extract episodes directly from the show page
    • Piped wikilinks in episode infobox now yield the series page title, not the display label
    • Sub-series character relationships accumulated correctly when registering as a show
    • Data quality fixes for sequel trilogy character/planet relationships
    • Obsolete hand-written TypeScript type definitions (cap/types/) replaced by generated @cds-models artifacts
    • Viewer CSP extended with unsafe-eval to allow Vue 3 runtime template compiler
    • Viewer pagination handles backend returning @odata.count=0 without breaking page calculation
  3. v1.8.0dated in the atlas

    Breaking 1, Other 9

    Notes

    Changed

    • Enhance README and improve project documentation
    • Add PostgreSQL profile-specific model exposure updates across CDS models and service projection
    • Add and expand Star Wars CDS model unit tests, including profile-specific exposure coverage
    • Update project dependencies and bump version to 1.8.0
    • Update dev container setup (Dockerfile and devcontainer.json) for Node.js LTS and Cloud Foundry CLI installation
    • Add CAP modeling and handler guidelines plus validation prompt workflows
    • Add compatibility-safe value-help entity migration (*Values helper entities) while retaining legacy helper entities/projections with deprecation comments
    • BREAKING: remove legacy value-help helper entities/projections (climate, terrain, hair_colors, eye_colors, skin_colors, classification, designation, language) in favor of *Values artifacts
    • Migration details: cap/docs/value-help-migration.md
  4. v1.4.0

    Other 3

    Notes

    Changed

    • CAP version 8.0
    • Update for SAPUI5 1.126.0
    • If you have ran this project locally previously, I recommend deleting your node_modules folder and doing a clean install of all dependencies
  5. v1.3.0

    Other 2

    Notes

    Changed

  6. v1.2.7

    Other 3

    Notes

    Changed

  7. v1.2.5

    Other 7

    Notes

    Changed

  8. v1.2.3

    Other 2

    Notes

    Changed

  9. v1.2.1

    Other 2

    Notes

    Changed

    • Add support for new sqlite database service
    • Add support for new postgres database service
  10. v1.2.0

    Other 2

    Notes

    Changed

    • SAP CAP updated to 7.0 June 2023 Rel - Major Annual Update
    • SAPUI5 update to 1.115.0
  11. v1.1.8

    Other 3

    Notes

    Changed

    • SAP CAP updated to 6.6 Feb 2023 Rel
    • Fixes in the convertData to avoid issues with parallelization and DB constrains
    • SAPUI5 update to 1.111.0
  12. v1.1.5

    Other 3

    Notes

    Changed

    • SAP CAP updated to 6.3
    • SAPUI5 update to 1.108.2
    • New Node.js minimal version is 14.18
  13. v1.1.5

    Other 3

    Notes

    Changed

    • SAP CAP updated to 6.3
    • SAPUI5 update to 1.108.2
    • New Node.js minimal version is 14.18
  14. v1.1.4

    Other 6

    Notes

    Changed

    • SAP CAP updated to 6.1
    • SAPUI5 update to 1.105.0
    • Kyma Helm Charts updated for new functionality in CAP 6.1

    Added

    • Update to SAP Cloud Application Programming Model 6.0.x - Yearly Major Release
    • Add Support for Node.js 18.x
    • Added Helm Charts support for deployment on Kyma/K8S
  15. v1.1.0

    Other 6

    Notes

    Changed

    • GraphQL support is now GA by switching to the @sap/cds-graphql dependency. Removal of old GraphQL dependencies.
    • Remove Support Node.js 12.x, minimal version now 14.15 as enforced by @sap/cds itself
    • SAPUI5 update to 1.103.0

    Added

    • Update to SAP Cloud Application Programming Model 6.0.x - Yearly Major Release
    • Add Support for Node.js 18.x
    • Added Helm Charts support for deployment on Kyma/K8S
  16. v1.0.7

    Other 2

    Notes

    Changed

    Added

  17. v1.0.6

    Other 8

    Notes

    Changed

    • Update to CAP March 2022 5.9
    • Update to SAPUI5 1.100
    • Reactivated experimental GraphQL support. Use from test application with /graphql
    • People App now uses OS setting and adjusts to dark theme - new sap_horizon_dark

    Added

Details

Sources3
Added by handdiscovered herechecked
github.com/SAP-samples/cloud-cap-hana-swapitree, pushes, contributors, CIchecked
README.mdquoted, and what the entry declareschecked

Sources are graph entities: the same page may back several entries, and an unreachable source flags every row that rests on it.

Compatibility and provenance
discovered viaAdded by hand
first seen in the atlas
ecosystem and domaincap, data-and-persistence
Flavors1
Node.js
“[Node.js 16, 18, or 20](https://nodejs.org/en/)” — SAP-samples/cloud-cap-hana-swapi — READMEchecked
Contributors5

From the repository’s contributor list, .

History in the atlas1
  1. First seen.
For your agent
Ref
artifact:sap-samples-cloud-cap-hana-swapi
JSON
/artifacts/sap-samples-cloud-cap-hana-swapi.json
MCP
Connecting an agent