\section{Endpoints}\label{sec:endpoints}

With ULO triplets imported into the GraphDB triplet store by Collecter
and Importer, we now have all data available necessary for querying.
As discussed before, querying from applications happens through an
Endpoint that exposes some kind of {API}. The interesting question
here is probably not so much the implementation of the endpoint itself,
rather it is the choice of API than can make or break such a project.

There are multiple approaches to querying the GraphDB triplet store,
one based around the standardized SPARQL query language and the other
on the RDF4J Java library implemented by various vendors. Both
approaches have unique advantages.

\begin{description}
    \item[SPARQL] is a standardized query language for RDF triplet
      data~\cite{sparql}. The specification includes not just syntax
      and semantics of the language itself, but also a standardized
      REST interface for querying databases.

      \textbf{Syntax} SPARQL is inspired by SQL and as such the
      \texttt{SELECT} \texttt{WHERE} syntax should be familiar to many
      software developers.  A simple query that returns all triplets
      in the store looks like
      \begin{lstlisting}
      SELECT * WHERE { ?s ?p ?o }
      \end{lstlisting}
      where \texttt{?s}, \texttt{?p} and \texttt{?o} are query
      variables. The result of any query are valid substitutions for
      the query variables. In this particular case, the database would
      return a table of all triplets in the store sorted by
      subject~\texttt{?o}, predicate~\texttt{?p} and
      object~\texttt{?o}.

      \textbf{Advantage} Probably the biggest advantage is that
      SPARQL is ubiquitous. As it is the de facto standard for
      querying triplet stores, lots of literature and documentation is
      available~\cite{sparqlbook, sparqlimpls, gosparql}.

    \item[RDF4J] is a Java API for interacting with triplet stores,
      implemented based on a superset of the {SPARQL} REST interface~\cite{rdf4j}.
      GraphDB supports RDF4J, in fact it is the recommended way of
      interacting with GraphDB repositories~\cite{graphdbapi}.

      \textbf{Syntax} Instead of formulating textual queries, RDF4J
      allows developers to query a repository by calling Java API
      methods. Previous query that requests all triplets in the store
      looks like
      \begin{lstlisting}
      connection.getStatements(null, null, null);
      \end{lstlisting}
      in RDF4J. \texttt{getStatements(s, p, o)} returns all triplets
      that have matching subject~\texttt{s}, predicate~\texttt{p} and
      object~\texttt{o}. Any argument that is \texttt{null} can be
      replace with any value, i.e.\ it is a query variable to be
      filled by the call to \texttt{getStatements}.

      \textbf{Advantage} Using RDF4J does introduce a dependency on
      the JVM and its languages. But in practice, we found RDF4J to be
      quite convenient, especially for simple queries, as it allows us
      to formulate everything in a single programming language rather
      than mixing languages and awkward string literals.

      We also found it quite helpful to generate Java classes from
      OWL ontologies that contain all definitions of the ontology and
      make it readable by any IDE~\cite{rdf4jgen}.
\end{description}

We see that both SPARQL and RDF4J have unique advantages. While SPARQL
is an official W3C standard and implemented by more database systems,
RDF4J can be more convenient when dealing with JVM-based code bases.
For \emph{ulo-storage}, we played around with both interfaces and
chose whatever seemed more convenient at the moment. We recommend any
implementors to do the same.
