An OSLC 3.0 server reference implementation built with Node.js and Express. It uses the oslc-service Express middleware for OSLC operations, backed by Apache Jena Fuseki for RDF persistence.
oslc-server only provides OSLC and LDP REST services. It does not provide any additional application capabilities or UI. The REST services are intended to be used programmatically, possibly to support an OSLC3 test server and reference implementation, or by the oslc-browser sample application.
Many thanks to Steve Speicher and Sam Padgett for their valuable contribution to LDP and the LDP middleware upon which this service is built.
oslc-server is built from several modules in the oslc4js workspace:
- oslc-server -- Express application entry point and static assets
- oslc-service -- Express middleware providing OSLC 3.0 services, built on ldp-service
- ldp-service -- Express middleware implementing the W3C LDP protocol (GET, HEAD, PUT, POST, DELETE for RDF resources and containers)
- ldp-service-jena -- Storage backend that persists RDF graphs in Apache Jena Fuseki
- storage-service -- Abstract storage interface shared by all backends
The Express app (src/app.ts) serves static files, then mounts oslc-service which delegates to ldp-service for all LDP operations. Configuration is read from config.json with environment variable overrides.
- Node.js v22 or later
- Apache Jena Fuseki running with a dataset configured
Install dependencies from the workspace root:
$ npm install
Build the TypeScript source:
$ cd oslc-server
$ npm run build
Edit config.json to match your environment:
{
"scheme": "http",
"host": "localhost",
"port": 3001,
"context": "/",
"jenaURL": "http://localhost:3030/univ/"
}- port -- The port to listen on (3001 by default, to avoid conflict with ldp-app on 3000)
- context -- The URL path prefix for OSLC/LDP resources
- jenaURL -- The Fuseki dataset endpoint URL
Start Fuseki with your dataset, then:
$ npm start
The server starts on the configured port. Use a REST client or the ldp-app visualization to interact with resources.
oslc-server exposes OSLC 3.0 discovery services and W3C LDP resource management. All RDF endpoints accept and produce text/turtle, application/ld+json, and application/rdf+xml.
The ServiceProviderCatalog is an LDP BasicContainer at {context}/oslc (e.g. http://localhost:3000/oslc), initialized at startup from config/catalog-template.ttl.
- GET /oslc -- Returns the catalog with
ldp:containslinks to ServiceProviders - POST /oslc -- Creates a new ServiceProvider. Body is Turtle with at least
dcterms:title. UseSlugheader to suggest a URI segment. Returns201withLocation - GET /oslc/{sp} -- Returns a ServiceProvider with its services, creation factories, and dialogs
- DELETE /oslc/{sp} -- Deletes a ServiceProvider and removes it from the catalog
Example -- create a ServiceProvider:
POST /oslc HTTP/1.1
Content-Type: text/turtle
Slug: myproject
@prefix dcterms: <http://purl.org/dc/terms/> .
<> dcterms:title "My Project" .
- GET /dialog/create?shape={shapeURI}&creation={creationURI} -- Returns an HTML creation form generated from the ResourceShape. On submit, POSTs Turtle to the creation URI and responds via the OSLC delegated UI protocol (
postMessageorwindowName) - GET /compact?uri={resourceURI} -- Resource preview.
Accept: text/htmlreturns a small preview HTML fragment;Accept: text/turtlereturns anoslc:CompactRDF description with asmallPreviewlink
All resources are managed under the configured context path. LDP supports RDF Source resources and containers (BasicContainer, DirectContainer).
- GET /{path} -- Returns the resource or container. Supports
If-None-Match/ETagconditional requests. Containers supportPreferheader to control containment and membership triples - HEAD /{path} -- Same as GET without the body. Returns
ETag,Content-Type,Link, andAllowheaders - POST /{container} -- Creates a new resource in the container. Use
Slugheader to suggest a URI. Returns201withLocation. For DirectContainers, automatically adds membership triples - PUT /{resource} -- Updates an existing RDF Source (not containers). Requires
If-Matchwith the currentETag. Can also create a resource at a specific URI - DELETE /{path} -- Deletes the resource and cleans up container membership (
ldp:containsfor BasicContainers,hasMemberRelationfor DirectContainers) - OPTIONS /{path} -- Returns
AllowandLinkheaders describing supported methods and interaction model
public/-- Favicon, stylesheets, usage documentationdialog/-- OSLC delegated UI dialogs (creation and selection)example/-- Sample Turtle data files
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.