From 645919daa897a7cf23e1ce17942a303c88152751 Mon Sep 17 00:00:00 2001 From: esikkala <esko.ikkala@aalto.fi> Date: Fri, 28 Jun 2019 09:59:00 +0300 Subject: [PATCH] Streamline API responses --- src/client/actions/index.js | 28 ++++++++++++++++---------- src/client/epics/index.js | 33 +++++++++++++++++++++++-------- src/client/reducers/helpers.js | 13 ++++++------ src/server/index.js | 10 ++++------ src/server/sparql/FacetResults.js | 19 ++++++++++++------ src/server/sparql/FacetValues.js | 14 +++++++++++-- src/server/sparql/Mappers.js | 11 ++--------- src/server/sparql/SparqlApi.js | 10 +++++++--- 8 files changed, 88 insertions(+), 50 deletions(-) diff --git a/src/client/actions/index.js b/src/client/actions/index.js index 83b4477e..d25cdfb4 100644 --- a/src/client/actions/index.js +++ b/src/client/actions/index.js @@ -51,17 +51,17 @@ export const fetchResultsFailed = (resultClass, error, message) => ({ type: FETCH_RESULTS_FAILED, resultClass, error, message }); -export const updateResultCount = ({ resultClass, count }) => ({ +export const updateResultCount = ({ resultClass, data, sparqlQuery }) => ({ type: UPDATE_RESULT_COUNT, - resultClass, count + resultClass, data, sparqlQuery }); -export const updatePaginatedResults = ({ resultClass, data }) => ({ +export const updatePaginatedResults = ({ resultClass, page, pagesize, data, sparqlQuery }) => ({ type: UPDATE_PAGINATED_RESULTS, - resultClass, data + resultClass, page, pagesize, data, sparqlQuery }); -export const updateResults = ({ resultClass, jenaIndex, query, data }) => ({ +export const updateResults = ({ resultClass, data, sparqlQuery }) => ({ type: UPDATE_RESULTS, - resultClass, jenaIndex, query, data + resultClass, data, sparqlQuery }); export const sortResults = (resultClass, sortBy) => ({ type: SORT_RESULTS, @@ -87,9 +87,9 @@ export const fetchByURIFailed = (resultClass, error, message) => ({ type: FETCH_RESULTS_FAILED, resultClass, error, message }); -export const updateInstance = ({ resultClass, instance }) => ({ +export const updateInstance = ({ resultClass, data, sparqlQuery }) => ({ type: UPDATE_INSTANCE, - resultClass, instance + resultClass, data, sparqlQuery }); export const fetchFacet = ({ facetClass, facetID }) => ({ type: FETCH_FACET, @@ -99,9 +99,17 @@ export const fetchFacetFailed = (facetClass, id, error, message) => ({ type: FETCH_FACET_FAILED, facetClass, id, error, message }); -export const updateFacetValues = ({ facetClass, id, distinctValueCount, values, flatValues, min, max }) => ({ +export const updateFacetValues = ({ + facetClass, + id, + data, + flatValues, + min, + max, + sparqlQuery +}) => ({ type: UPDATE_FACET_VALUES, - facetClass, id, distinctValueCount, values, flatValues, min, max + facetClass, id, data, flatValues, min, max, sparqlQuery }); export const updateFacetOption = ({ facetClass, facetID, option, value }) => ({ type: UPDATE_FACET_OPTION, diff --git a/src/client/epics/index.js b/src/client/epics/index.js index f660a123..707220f4 100644 --- a/src/client/epics/index.js +++ b/src/client/epics/index.js @@ -55,7 +55,13 @@ const fetchPaginatedResultsEpic = (action$, state$) => action$.pipe( const requestUrl = `${apiUrl}${resultClass}/paginated?${params}`; // https://rxjs-dev.firebaseapp.com/api/ajax/ajax return ajax.getJSON(requestUrl).pipe( - map(response => updatePaginatedResults({ resultClass: resultClass, data: response })), + map(response => updatePaginatedResults({ + resultClass: response.resultClass, + page: response.page, + pagesize: response.pagesize, + data: response.data, + sparqlQuery: response.sparqlQuery + })), // https://redux-observable.js.org/docs/recipes/ErrorHandling.html catchError(error => of({ type: FETCH_PAGINATED_RESULTS_FAILED, @@ -86,7 +92,11 @@ const fetchResultsEpic = (action$, state$) => action$.pipe( }); const requestUrl = `${apiUrl}${resultClass}/all?${params}`; return ajax.getJSON(requestUrl).pipe( - map(response => updateResults({ resultClass: resultClass, data: response })), + map(response => updateResults({ + resultClass: resultClass, + data: response.data, + sparqlQuery: response.sparqlQuery + })), catchError(error => of({ type: FETCH_RESULTS_FAILED, resultClass: resultClass, @@ -116,7 +126,11 @@ const fetchResultCountEpic = (action$, state$) => action$.pipe( }); const requestUrl = `${apiUrl}${resultClass}/count?${params}`; return ajax.getJSON(requestUrl).pipe( - map(response => updateResultCount({ resultClass: resultClass, count: response.count })), + map(response => updateResultCount({ + resultClass: response.resultClass, + data: response.data, + sparqlQuery: response.sparqlQuery + })), catchError(error => of({ type: FETCH_RESULT_COUNT_FAILED, resultClass: resultClass, @@ -179,7 +193,10 @@ const fetchByURIEpic = (action$, state$) => action$.pipe( }); const requestUrl = `${apiUrl}${resultClass}/instance/${encodeURIComponent(uri)}?${params}`; return ajax.getJSON(requestUrl).pipe( - map(response => updateInstance({ resultClass: resultClass, instance: response })), + map(response => updateInstance({ + resultClass: resultClass, + instance: response + })), catchError(error => of({ type: FETCH_BY_URI_FAILED, resultClass: resultClass, @@ -215,11 +232,11 @@ const fetchFacetEpic = (action$, state$) => action$.pipe( map(res => updateFacetValues({ facetClass: facetClass, id: facetID, - distinctValueCount: res.distinctValueCount || 0, - values: res.values || [], - flatValues: res.flatValues || [], + data: res.data || [], + flatData: res.flatData || [], min: res.min || null, - max: res.max || null + max: res.max || null, + sparqlQuery: res.sparqlQuery })), catchError(error => of({ type: FETCH_FACET_FAILED, diff --git a/src/client/reducers/helpers.js b/src/client/reducers/helpers.js index 30162e51..7b243250 100644 --- a/src/client/reducers/helpers.js +++ b/src/client/reducers/helpers.js @@ -138,7 +138,7 @@ const updateFacetFilter = (state, action) => { export const updateResultCount = (state, action) => { return { ...state, - resultCount: parseInt(action.count), + resultCount: parseInt(action.data), fetchingResultCount: false, }; }; @@ -147,7 +147,7 @@ export const updateResults = (state, action) => { return { ...state, resultsUpdateID: ++state.resultsUpdateID, - results: action.data.results, + results: action.data, fetching: false, }; }; @@ -156,7 +156,7 @@ export const updatePaginatedResults = (state, action) => { return { ...state, resultsUpdateID: ++state.resultsUpdateID, - paginatedResults: action.data.results || [], + paginatedResults: action.data || [], fetching: false }; }; @@ -203,15 +203,16 @@ export const updateFacetValues = (state, action) => { } }; } else { + console.log(action) return { ...state, facets: { ...state.facets, [ action.id ]: { ...state.facets[action.id], - distinctValueCount: action.distinctValueCount || 0, - values: action.values || [], - flatValues: action.flatValues || [], + distinctValueCount: action.data.length || 0, + values: action.data || [], + flatValues: action.flatData || [], isFetching: false } } diff --git a/src/server/index.js b/src/server/index.js index 57baaea9..ea0f3c8b 100644 --- a/src/server/index.js +++ b/src/server/index.js @@ -69,9 +69,7 @@ app.get(`${apiPath}/:resultClass/all`, async (req, res, next) => { variant: req.query.variant || null, resultFormat: req.query.resultFormat == null ? 'json' : req.query.resultFormat }); - res.json({ - results: data - }); + res.json(data); } catch(error) { next(error); } @@ -79,12 +77,12 @@ app.get(`${apiPath}/:resultClass/all`, async (req, res, next) => { app.get(`${apiPath}/:resultClass/count`, async (req, res, next) => { try { - const count = await getResultCount({ + const data = await getResultCount({ resultClass: req.params.resultClass, constraints: req.query.constraints == null ? null : JSON.parse(req.query.constraints), resultFormat: req.query.resultFormat == null ? 'json' : req.query.resultFormat }); - res.json({ count }); + res.json(data); } catch(error) { next(error); } @@ -101,7 +99,7 @@ app.get(`${apiPath}/:resultClass/instance/:uri`, async (req, res, next) => { resultFormat: req.query.resultFormat == null ? 'json' : req.query.resultFormat }); // there is always one object in the 'data' array - res.json(data[0]); + res.json(data); } catch(error) { next(error); } diff --git a/src/server/sparql/FacetResults.js b/src/server/sparql/FacetResults.js index 8021c74e..d0655a05 100644 --- a/src/server/sparql/FacetResults.js +++ b/src/server/sparql/FacetResults.js @@ -30,7 +30,7 @@ export const getPaginatedResults = async ({ sortDirection, resultFormat }) => { - const data = await getPaginatedData({ + const response = await getPaginatedData({ resultClass, page, pagesize, @@ -41,12 +41,14 @@ export const getPaginatedResults = async ({ }); if (resultFormat === 'json') { return { - pagesize: pagesize, + resultClass: resultClass, page: page, - results: data + pagesize: pagesize, + data: response.data, + sparqlQuery: response.sparqlQuery }; } else { - return data; + return response; } }; @@ -100,7 +102,7 @@ export const getAllResults = ({ return runSelectQuery(prefixes + q, endpoint, mapper, resultFormat); }; -export const getResultCount = ({ +export const getResultCount = async ({ resultClass, constraints, resultFormat @@ -118,7 +120,12 @@ export const getResultCount = ({ facetID: null })); } - return runSelectQuery(prefixes + q, endpoint, mapCount, resultFormat); + const response = await runSelectQuery(prefixes + q, endpoint, mapCount, resultFormat); + return({ + resultClass: resultClass, + data: response.data, + sparqlQuery: response.sparqlQuery + }); }; const getPaginatedData = ({ diff --git a/src/server/sparql/FacetValues.js b/src/server/sparql/FacetValues.js index 3a3c2fd9..55f6b50c 100644 --- a/src/server/sparql/FacetValues.js +++ b/src/server/sparql/FacetValues.js @@ -19,7 +19,7 @@ import { mapTimespanFacet } from './Mappers'; -export const getFacet = ({ +export const getFacet = async ({ facetClass, facetID, sortBy, @@ -105,7 +105,17 @@ export const getFacet = ({ // if (facetID == 'productionPlace') { // console.log(prefixes + q) // } - return runSelectQuery(prefixes + q, endpoint, mapper, resultFormat); + const response = await runSelectQuery(prefixes + q, endpoint, mapper, resultFormat); + console.log(response) + return({ + facetClass: facetClass, + id: facetID, + data: response.data, + flatData: response.flatData || null, + min: response.min || null, + max: response.max || null, + sparqlQuery: response.sparqlQuery + }); }; const generateSelectedBlock = ({ diff --git a/src/server/sparql/Mappers.js b/src/server/sparql/Mappers.js index 39f9c8fc..eeb81087 100644 --- a/src/server/sparql/Mappers.js +++ b/src/server/sparql/Mappers.js @@ -27,10 +27,7 @@ export const mapFacet = sparqlBindings => { if (sparqlBindings.length > 0) { results = mapFacetValues(sparqlBindings); } - return { - distinctValueCount: results.length, - values: results - }; + return results; }; export const mapHierarchicalFacet = sparqlBindings => { @@ -44,11 +41,7 @@ export const mapHierarchicalFacet = sparqlBindings => { }); treeData = recursiveSort(treeData); treeData.forEach(node => sumUpAndSelectChildren(node)); - return { - distinctValueCount: results.length, - //flatValues: flatResults, - values: treeData - }; + return treeData; }; export const mapTimespanFacet = sparqlBindings => { diff --git a/src/server/sparql/SparqlApi.js b/src/server/sparql/SparqlApi.js index 8cd4c1a1..e40b945f 100644 --- a/src/server/sparql/SparqlApi.js +++ b/src/server/sparql/SparqlApi.js @@ -13,19 +13,23 @@ export const runSelectQuery = async (query, endpoint, resultMapper, resultFormat 'Content-Type': 'application/x-www-form-urlencoded', 'Accept': MIMEtype }; + const q = querystring.stringify({ query }); try { const response = await axios({ method: 'post', headers: headers, url: endpoint, - data: querystring.stringify({ query }), + data: q, }); if (resultFormat === 'json') { - return resultMapper(response.data.results.bindings); + const mappedResults = resultMapper(response.data.results.bindings); + return { + data: mappedResults, + sparqlQuery: query + }; } else { return response.data; } - } catch(error) { if (error.response) { // The request was made and the server responded with a status code -- GitLab