diff --git a/README.md b/README.md index e86acb0..41aca9e 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,19 @@ yarn start ### Configuration -The application can be configured by editing the `config/config.ts` file. The following parameters are available: +The application can be configured by using environment variables. The following variables are supported: -- `port`: The port where the application will be listening. -- `endpoint.sparql`: The URL of the SPARQL endpoint to be used. -- `prefixes`: A list of prefixes to be used in the application. Each prefix is defined as a pair of `prefix` and `uri`. +- `PORT`: The port where the application will be listening. +- `LOGLEVEL`: The log level. The possible values are `DEBUG`, `INFO`, `WARN`, and `ERROR`. +- `SPARQL_QUERY_URL`: The URL of the SPARQL endpoint to be used. + +You can use an `.env` file to set environment variables. For example, this command creates an `.env` file for our PROVENANCE endpoint: + +```bash +$ echo 'SPARQL_QUERY_URL="https://endpoint.mint.isi.edu/provenance" +PORT=8000 +LOGLEVEL=INFO' > .env +``` ### Usage @@ -32,7 +40,7 @@ RDF Explorer will show the information of the resource, including its attributes #### Content negotiation -RDF Explorer supports content negotiation. You can get the information of a resource in different formats by using the `Accept` header. For example, to get the information of `http://dbpedia.org/resource/Spain` in Turtle format, you can use the following command: +RDF Explorer supports content negotiation. You can get the information of a resource in different formats by using the `Accept` header. For example, to get the information of `https://opmw.org/exportTest/resource/WorkflowExecutionAccount/Caesar_Cypher-2b-3c5e9dd8-6c44-4666-a6a2-cf572aca76db` in Turtle format, you can use the following command: ```bash curl -H "Accept: text/turtle" http://localhost:8000/opmw.org/exportTest/resource/WorkflowExecutionAccount/Caesar_Cypher-2b-3c5e9dd8-6c44-4666-a6a2-cf572aca76db diff --git a/config/config.ts b/config/config.ts deleted file mode 100644 index 2231734..0000000 --- a/config/config.ts +++ /dev/null @@ -1,14 +0,0 @@ -const config = { - endpoint: { - sparqlUrl: "https://endpoint.mint.isi.edu/provenance", - }, - logLevel: "info", - prefixes: [ - { prefix: "owl:", uri: "http://www.w3.org/2002/07/owl#" }, - { prefix: "dc:", uri: "http://purl.org/dc/terms/" }, - { prefix: "rdf:", uri: "http://www.w3.org/1999/02/22-rdf-syntax-ns#" }, - { prefix: "rdfs:", uri: "http://www.w3.org/2000/01/rdf-schema#" }, - ], -}; - -export default config; diff --git a/index.ts b/index.ts index e130bc2..64d5211 100644 --- a/index.ts +++ b/index.ts @@ -1,46 +1,24 @@ import express, { Request, Response, Application } from "express"; -import { - performIncomingQueryHtml, - performQuery, - performQueryHtml, -} from "./src/query"; -import { toPrefix } from "./src/utils"; import pino from "pino-http"; -import config from "./config/config"; +import { performQuery } from "./src/query"; +import { config } from "./src/config"; +import { handleQueryHtml } from "./src/renderHtml"; +//set express const app: Application = express(); -const port = process.env.PORT || 8000; +const port = config.port; const publicDirectory = __dirname + "/public/"; const logger = pino({ level: config.logLevel, autoLogging: false, }); + app.set("view engine", "pug"); app.use(express.static(publicDirectory)); app.use(logger); -const handleQueryHtml = async (uri: string) => { - const outcomingQuads = await performQueryHtml(uri as string); - const incomingQuads = await performIncomingQueryHtml(uri as string); - if (outcomingQuads.length === 0 && incomingQuads.length === 0) { - throw new Error("Not Found"); - } - const title = getTitle(); - return { - incomingQuads: incomingQuads, - outcomingQuads: outcomingQuads, - title: title, - toPrefix: toPrefix, - }; - function getTitle() { - return outcomingQuads.length > 0 - ? outcomingQuads[0].subject.value - : incomingQuads[0].object.value; - } -}; - const handleQuery = async (uri: string, format: string) => { - return await performQuery(uri, format); + return await performQuery(uri, format, config.sparqlQueryUrl); }; app.get("/*", (req: Request, res: Response) => { @@ -50,7 +28,7 @@ app.get("/*", (req: Request, res: Response) => { res.format({ "text/html": async () => { try { - const data = await handleQueryHtml(uri); + const data = await handleQueryHtml(uri, config.sparqlQueryUrl); return res.render("results", data); } catch (error) { return res.status(404).send("Not Found"); @@ -98,4 +76,5 @@ app.get("/*", (req: Request, res: Response) => { app.listen(port, () => { console.log(`Server is Fire at http://localhost:${port}`); + console.log(`Sparql endpoint is ${config.sparqlQueryUrl}`); }); diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 0000000..9e60bd0 --- /dev/null +++ b/src/config.ts @@ -0,0 +1,19 @@ +import dotenv from "dotenv"; +import { Config } from "./types"; +import { PREFIXES } from "./prefixes"; + +dotenv.config(); + +const config: Config = { + sparqlQueryUrl: process.env.SPARQL_QUERY_URL as string, + port: parseInt(process.env.PORT as string) || 8000, + logLevel: (process.env.LOG_LEVEL as string) || "info", + prefixes: PREFIXES, +}; + +if (!config.sparqlQueryUrl) { + console.error("SPARQL_QUERY_URL is not set"); + process.exit(1); +} + +export { config }; diff --git a/src/prefixes.ts b/src/prefixes.ts new file mode 100644 index 0000000..980b6ee --- /dev/null +++ b/src/prefixes.ts @@ -0,0 +1,10 @@ +import { Prefix } from "./types"; + +const PREFIXES = [ + { prefix: "owl:", uri: "http://www.w3.org/2002/07/owl#" }, + { prefix: "dc:", uri: "http://purl.org/dc/terms/" }, + { prefix: "rdf:", uri: "http://www.w3.org/1999/02/22-rdf-syntax-ns#" }, + { prefix: "rdfs:", uri: "http://www.w3.org/2000/01/rdf-schema#" }, +] as Prefix[]; + +export { PREFIXES }; diff --git a/src/query.ts b/src/query.ts index 5c0331a..c5deb15 100644 --- a/src/query.ts +++ b/src/query.ts @@ -1,40 +1,39 @@ import { Parser, Generator } from "sparqljs"; import { QueryEngine } from "@comunica/query-sparql"; -import config from "../config/config"; const myEngine = new QueryEngine(); const generator = new Generator(); -const performQueryHtml = async (uri: string) => { +const performQueryHtml = async (uri: string, endpoint: string) => { const query = createQuery(uri); - const stream = await sendQueryQuads(query); + const stream = await sendQueryQuads(query, endpoint); const quads = await stream.toArray(); return quads; }; -const performIncomingQueryHtml = async (uri: string) => { +const performIncomingQueryHtml = async (uri: string, endpoint: string) => { const query = createQueryIncoming(uri); - const stream = await sendQueryQuads(query); + const stream = await sendQueryQuads(query, endpoint); const quads = await stream.toArray(); return quads; }; -const performQuery = async (uri: string, format: string) => { +const performQuery = async (uri: string, format: string, endpoint: string) => { const query = createQuery(uri); - const result = await sendQuery(query); + const result = await sendQuery(query, endpoint); const triples = serializeResults(result, format); return triples; }; -const sendQuery = async (query: string) => { +const sendQuery = async (query: string, endpoint: string) => { return await myEngine.query(query, { - sources: [config.endpoint.sparqlUrl], + sources: [endpoint], }); }; -const sendQueryQuads = async (query: string) => { +const sendQueryQuads = async (query: string, endpoint: string) => { return await myEngine.queryQuads(query, { - sources: [config.endpoint.sparqlUrl], + sources: [endpoint], }); }; diff --git a/src/renderHtml.ts b/src/renderHtml.ts new file mode 100644 index 0000000..f0523a8 --- /dev/null +++ b/src/renderHtml.ts @@ -0,0 +1,24 @@ +import { performIncomingQueryHtml, performQueryHtml } from "./query"; +import { toPrefix } from "./utils"; + +const handleQueryHtml = async (uri: string, endpoint: string) => { + const outcomingQuads = await performQueryHtml(uri, endpoint); + const incomingQuads = await performIncomingQueryHtml(uri, endpoint); + if (outcomingQuads.length === 0 && incomingQuads.length === 0) { + throw new Error("Not Found"); + } + const title = getTitle(); + return { + incomingQuads: incomingQuads, + outcomingQuads: outcomingQuads, + title: title, + toPrefix: toPrefix, + }; + function getTitle() { + return outcomingQuads.length > 0 + ? outcomingQuads[0].subject.value + : incomingQuads[0].object.value; + } +}; + +export { handleQueryHtml }; diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..9a64e09 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,13 @@ +interface Config { + sparqlQueryUrl: string; + port: number; + logLevel: string; + prefixes: Prefix[]; +} + +interface Prefix { + prefix: string; + uri: string; +} + +export { Config, Prefix }; diff --git a/src/utils.ts b/src/utils.ts index d1d6cb3..e0fae35 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,9 +1,8 @@ -import config from "../config/config"; +import { PREFIXES } from "./prefixes"; +import { Prefix } from "./types"; -const prefixes = config.prefixes; -const toPrefix = (uri: string) => { - //transform this uri to prefix notation. - for (const i in prefixes) { +const toPrefix = (uri: string, prefixes: Prefix[]) => { + for (const i in PREFIXES) { if (uri.includes(prefixes[i].uri)) { return uri.replace(prefixes[i].uri, prefixes[i].prefix); }