Architecture¶
The Linked Data Explorer is a monorepo with three workspaces under packages/: a React frontend SPA, a Node.js/Express backend API, and ropa-site, the static public site for the register of processing activities. The frontend renders in the browser; the backend handles SPARQL queries, Operaton calls, and chain orchestration.
System architecture¶
Browser
โโโ Frontend (React + TypeScript, Azure Static Web Apps)
โ HTTPS/REST
โโโ Backend (Node.js + Express, Azure App Service)
โโโ SPARQL โโโโโโโบ TriplyDB (knowledge graph)
โโโ REST API โโโโโบ Operaton (DMN execution engine)
The frontend does not call TriplyDB or Operaton itself. Queries, deployments and chain execution all go through the backend, which handles authentication, CORS, caching, variable orchestration โ and, since v2026.09.5, the outbound guard that checks every host a caller names. That includes the SPARQL Query Editor, which until v2026.09.5 fetched the chosen endpoint straight from the browser and fell back to the third-party api.allorigins.win proxy; both paths are gone. The one thing the browser still loads from TriplyDB directly is organisation logo images, which the frontend's Content-Security-Policy admits in img-src.
Frontend architecture¶
The frontend is a single-page application with no routing library. Navigation state is managed as an enum (ViewMode) in the top-level App.tsx.
App.tsx
โโโ Sidebar navigation (ViewMode selector)
โโโ QueryEditor view
โ โโโ SparqlEditor (query input)
โ โโโ ResultsTable (tabular results)
โ โโโ GraphView (D3.js force-directed graph)
โโโ ChainBuilder view
โ โโโ DmnList (available DMNs, left panel)
โ โโโ ChainComposer (drag-drop zone, centre panel)
โ โ โโโ SemanticAnalysis tab
โ โโโ ChainConfig (inputs + execution, right panel)
โ โ โโโ InputForm
โ โ โโโ ExecutionProgress
โ โ โโโ ChainResults
โ โ โโโ ExportChain (JSON / BPMN 2.0)
โ โโโ ValidationPanel
โโโ BpmnModeler view
โ โโโ ProcessList (left panel)
โ โโโ BpmnCanvas (bpmn-js wrapper, centre)
โ โ โโโ Deploy modal (one-click Operaton deployment)
โ โโโ BpmnProperties (right panel)
โ โโโ DmnTemplateSelector (BusinessRuleTask)
โ โโโ FormTemplateSelector (UserTask / StartEvent) โ new in v1.0.0
โโโ FormEditor view โ new in v1.0.0
โ โโโ FormList (left panel)
โ โโโ FormCanvas (@bpmn-io/form-js editor, centre)
โโโ Changelog / Help view
The FormEditor view and BpmnModeler view share the FormService localStorage layer โ forms authored in FormEditor are immediately available to FormTemplateSelector in the BPMN properties panel with no explicit synchronisation step.
State is managed with React hooks at the component level. There is no global state library. The templateService.ts utility provides the only persistent state โ localStorage CRUD for chain templates and BPMN processes.
Backend architecture¶
The backend is a structured Express application following the Dutch Government API Design Rules (API-20, API-57).
src/
โโโ index.ts entry point: middleware, route mounting, server startup
โโโ routes/ one file per route group, mounted under /v1 by routes/index.ts
โ โโโ registry.ts the route topology, described once (the root page reads it)
โ โโโ health ยท openapi ยท dmn ยท chain ยท template ยท process ยท shacl ยท norms
โ โโโ triplydb ยท vendor ยท dso ยท edocs ยท cache ยท cspReports
โ โโโ assets ยท assets.public ยท ropa ยท ropa.public
โโโ services/ one per external system or domain: sparql, operaton,
โ orchestration, triplydb, dso, edocs, vendor, norms, template,
โ dmn-validation, shacl-validation, assets, ropa, externalTaskWorker
โโโ db/ pg pool, idempotent migrations, row mappers
โโโ openapi/ document.ts serves the built description; testing/ holds the
โ helpers that validate route responses against it
โโโ middleware/
โ โโโ cors.middleware.ts allowlist, plus wildcard for the three public mounts
โ โโโ error.middleware.ts central RFC 9457 problem-details handler
โ โโโ version.middleware.ts API-Version header
โโโ utils/
โโโ outboundUrl.ts route-level checks on caller-supplied endpoints
โโโ outboundHttp.ts the guarded axios client for caller-chosen hosts
โโโ problem.ts builds problem-details responses
โโโ validation.ts body validators for the asset and ROPA upserts
โโโ publicPaths.ts the three mounts served to any origin
โโโ buildInfo.ts reads deploy/build-info.json for /v1/health
โโโ config.ts environment configuration
โโโ logger.ts Winston structured logging
The request and response shapes of every route are in the API Specification, built from packages/backend/openapi/openapi.yaml.
Legacy /api/* routes exist with deprecation headers for backward compatibility. All new work uses /v1/*.
Data flow โ chain execution¶
1. Frontend POST /v1/chains/execute
{ chain: [dmnId1, dmnId2], inputs: {...}, endpoint: "..." }
2. orchestration.service.ts
for each DMN in chain:
a. sparql.service.ts โ fetch DMN metadata from TriplyDB (cached 5 min)
b. Flatten previous step outputs into current step inputs
c. operaton.service.ts โ POST /engine-rest/decision-definition/key/{id}/evaluate
d. Collect and flatten results
3. Return combined results to frontend
Caching¶
The backend caches DMN metadata per endpoint with a 5-minute TTL. The cache key is the endpoint URL. Switching endpoints in the frontend bypasses the cache and triggers a fresh SPARQL query.
Environment variables¶
See Deployment for the full list. Key variables:
| Variable | Description |
|---|---|
TRIPLYDB_ENDPOINT |
Default SPARQL endpoint URL |
OPERATON_BASE_URL |
Operaton engine REST base URL |
CORS_ORIGIN |
Comma-separated list of allowed frontend origins |
NODE_ENV |
development, acceptance, or production |
PORT |
Backend listen port (default 3001 local, 8080 Azure) |