Skip to content
Snippets Groups Projects
index.js 6.15 KiB
import express from 'express';
import path from 'path';
import bodyParser from 'body-parser';
import { has } from 'lodash';
import {
  getResultCount,
  getPaginatedResults,
  getAllResults,
  getByURI } from './sparql/FacetResults';
import { getFacet } from './sparql/FacetValues';
import { queryJenaIndex } from './sparql/JenaQuery';
const DEFAULT_PORT = 3001;
const app = express();
app.set('port', process.env.PORT || DEFAULT_PORT);
app.use(bodyParser.json());

// NODE_ENV is defined in package.json when running in localhost
const isDevelopment = process.env.NODE_ENV === 'development' ? true : false;

// allow CORS
app.use(function(req, res, next) {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
  next();
});

let publicPath = null;

// Express server is used to serve the React app only in production
if (!isDevelopment) {
  // The root directory from which to serve static assets
  publicPath = path.join(__dirname, './../public/');
  app.use(express.static(publicPath));
}

// React app makes requests to these api urls
const apiPath = '/api';

// https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016
app.get(`${apiPath}/:resultClass/paginated`, async (req, res, next) => {
  try {
    const data = await getPaginatedResults({
      resultClass: req.params.resultClass,
      page: parseInt(req.query.page) || null,
      pagesize: parseInt(req.query.pagesize) || null,
      uriFilters: req.query.uriFilters == null ? null : JSON.parse(req.query.uriFilters),
      spatialFilters: req.query.spatialFilters == null ? null : JSON.parse(req.query.spatialFilters),
      textFilters: req.query.textFilters == null ? null : JSON.parse(req.query.textFilters),
      timespanFilters: req.query.timespanFilters == null ? null : JSON.parse(req.query.timespanFilters),
      sortBy: req.query.sortBy || null,
      sortDirection: req.query.sortDirection || null,
      constraints: req.query.constraints
    });
    res.json(data);
  } catch(error) {
    next(error);
  }
});

app.get(`${apiPath}/:resultClass/all`, async (req, res, next) => {
  try {
    const data = await getAllResults({
      resultClass: req.params.resultClass,
      facetClass: req.query.facetClass || null,
      uriFilters: req.query.uriFilters == null ? null : JSON.parse(req.query.uriFilters),
      spatialFilters: req.query.spatialFilters == null ? null : JSON.parse(req.query.spatialFilters),
      textFilters: req.query.textFilters == null ? null : JSON.parse(req.query.textFilters),
      timespanFilters: req.query.timespanFilters == null ? null : JSON.parse(req.query.timespanFilters),
      variant: req.query.variant || null,
    });
    res.json({
      results: data
    });
  } catch(error) {
    next(error);
  }
});

app.get(`${apiPath}/:resultClass/count`, async (req, res, next) => {
  try {
    const count = await getResultCount({
      resultClass: req.params.resultClass,
      uriFilters: req.query.uriFilters == null ? null : JSON.parse(req.query.uriFilters),
      spatialFilters: req.query.spatialFilters == null ? null : JSON.parse(req.query.spatialFilters),
      textFilters: req.query.textFilters == null ? null : JSON.parse(req.query.textFilters),
      timespanFilters: req.query.timespanFilters == null ? null : JSON.parse(req.query.timespanFilters),
    });
    res.json({ count });
  } catch(error) {
    next(error);
  }
});

app.get(`${apiPath}/:resultClass/instance/:uri`, async (req, res, next) => {
  try {
    const data = await getByURI({
      resultClass: req.params.resultClass,
      facetClass: req.query.facetClass || null,
      uriFilters: req.query.uriFilters == null ? null : JSON.parse(req.query.uriFilters),
      spatialFilters: req.query.spatialFilters == null ? null : JSON.parse(req.query.spatialFilters),
      textFilters: req.query.textFilters == null ? null : JSON.parse(req.query.textFilters),
      timespanFilters: req.query.timespanFilters == null ? null : JSON.parse(req.query.timespanFilters),
      variant: req.query.variant || null,
      uri: req.params.uri
    });
    // there is always one object in the 'data' array
    res.json(data[0]);
  } catch(error) {
    next(error);
  }
});

app.get(`${apiPath}/:facetClass/facet/:id`, async (req, res, next) => {
  try {
    const data = await getFacet({
      facetClass: req.params.facetClass,
      facetID: req.params.id,
      sortBy: req.query.sortBy || null,
      sortDirection: req.query.sortDirection || null,
      uriFilters: req.query.uriFilters == null ? null : JSON.parse(req.query.uriFilters),
      spatialFilters: req.query.spatialFilters == null ? null : JSON.parse(req.query.spatialFilters),
      textFilters: req.query.textFilters == null ? null : JSON.parse(req.query.textFilters),
      timespanFilters: req.query.timespanFilters == null ? null : JSON.parse(req.query.timespanFilters),
    });
    res.json(data);
  } catch(error) {
    next(error);
  }
});

app.get(`${apiPath}/search`, async (req, res, next) => {
  let queryTerm = '';
  let latMin = 0;
  let longMin = 0;
  let latMax = 0;
  let longMax = 0;
  if (has(req.query, 'q')) {
    queryTerm = req.query.q;
  }
  if (has(req.query, 'latMin')) {
    latMin = req.query.latMin;
    longMin = req.query.longMin;
    latMax = req.query.latMax;
    longMax = req.query.longMax;
  }
  try {
    const data = await queryJenaIndex({
      queryTerm: queryTerm,
      latMin: latMin,
      longMin: longMin,
      latMax: latMax,
      longMax: longMax,
    });
    res.json(data);
  } catch(error) {
    next(error);
  }
});

// Express server is used to serve the React app only in production
if (!isDevelopment) {
  /*  Routes are matched to a url in order of their definition
      Redirect all the the rest for react-router to handle */
  app.get('*', function(request, response) {
    response.sendFile(path.join(publicPath, 'index.html'));
  });
}

let servingInfo = isDevelopment ?
  `NODE_ENV=development, so Webpack serves the React app`
  : `Static files (e.g. the React app) will be served from ${publicPath}`;

const port = app.get('port');

app.listen(port, () =>
  console.log(`
  Express server listening on port ${port}
  API path is ${apiPath}
  ${servingInfo}
  `)
);