Build apps

Using LinkedDataHub as a low-code platform for Knowledge Graph applications

Every component in LinkedDataHub is data-driven and was designed with extensibility in mind. You can override behavior (e.g. Java method or XSLT template) without having to modify LinkedDataHub's codebase, and more importantly, without having to write the same logic from scratch.

The following sections are split by component/layer and explain how to extend them when building bespoke apps.


You can go a long way just by mounting files (e.g. config files, ontologies, stylesheets) into LinkedDataHub's default Docker setup. But you may also want to build a dedicated Docker image for your app using LinkedDataHub as the base. Usually this is done to COPY files inside the the image or RUN additional commands.

Here's an sample Dockerfile that copies custom stylesheets into the app's Docker image:

FROM atomgraph/linkeddatahub:4.0.0

USER root

RUN curl -fsSL | bash - && \
    apt-get update --allow-releaseinfo-change && \
    apt-get install -y nodejs && \
    rm -rf /var/lib/apt/lists/* && \
    mkdir /home/ldh && chown ldh:ldh /home/ldh

USER ldh

RUN npm install saxon-js && \
    npm install xslt3


COPY --chown=ldh:ldh files/layout.xsl net/example/xsl/layout.xsl
COPY --chown=ldh:ldh files/client.xsl net/example/xsl/client.xsl

# pre-processing stylesheets in order to inline XML entities which SaxonJS does not support
RUN curl${SAXON_VERSION}/Saxon-HE-${SAXON_VERSION}.jar -O && \
    cat com/atomgraph/linkeddatahub/xsl/client.xsl | grep 'xsl:import' | cut -d '"' -f 2 | xargs -I{} java -cp Saxon-HE-${SAXON_VERSION}.jar net.sf.saxon.Query -qs:"." -s:com/atomgraph/linkeddatahub/xsl/{} -o:com/atomgraph/linkeddatahub/xsl/{} && \
    cat com/atomgraph/linkeddatahub/xsl/client.xsl | grep 'xsl:include' | cut -d '"' -f 2 | xargs -I{} java -cp Saxon-HE-${SAXON_VERSION}.jar net.sf.saxon.Query -qs:"." -s:com/atomgraph/linkeddatahub/xsl/{} -o:com/atomgraph/linkeddatahub/xsl/{} && \
    java -cp Saxon-HE-${SAXON_VERSION}.jar net.sf.saxon.Query -qs:"." -s:com/atomgraph/linkeddatahub/xsl/client.xsl -o:com/atomgraph/linkeddatahub/xsl/client.xsl && \
    java -cp Saxon-HE-${SAXON_VERSION}.jar net.sf.saxon.Query -qs:"." -s:net/example/xsl/client.xsl -o:net/example/xsl/client.xsl && \
    npx xslt3 -t -xsl:net/example/xsl/client.xsl -export:net/example/xsl/client.xsl.sef.json -nogo -ns:##html5 -relocate:on && \
    rm Saxon-HE-${SAXON_VERSION}.jar && \
    setfacl -Rm user:ldh:rwx net/example/xsl



The Java layer of LinkedDataHub is a Maven project with a webapp layout. The codebase uses JAX-RS, specifically Jersey 3, as the HTTP/REST framework and uses Apache Jena for RDF I/O.

If you want to extend the Java codebase, for example to add a custom REST endpoint, you need to create a new Maven project with LinkedDataHub as dependency:


After adding the new endpoint, you'll also need to extend the LinkedDataHub's JAX-RS application (com.atomgraph.linkeddatahub.Application) and register your class there.

By convention, static files (e.g. stylesheets, images) are placed in the src/main/webapp/static/ folder in the codebase, which then becomes /usr/local/tomcat/webapps/ROOT/static/ within the webapp deployed in the Docker container, and is available as ${base}static/ over HTTP.

This means that if you want to deploy static files as part of your LinkedDataHub app, you will have to either mount them into the /usr/local/tomcat/webapps/ROOT/static/ folder in the container, or copy them into a custom Docker image to the same effect.

You can allow Java debugger access using configuration properties.


LinkedDataHub uses XSLT 3.0 for UI rendering both on the server- and on the client-side.

You can specify a custom server-side XSLT 3.0 stylesheet in the dataspace configuration. Then you can reuse LinkedDataHub's stylesheet by importing it as explained in the change layout user guide.


You can modify or extend the default RDF datasets used by LinkedDataHub. However, a better practice is to use the CLI scripts to create documents and import data.

See the LinkedDataHub app repository for more examples.