Closed jstcki closed 5 years ago
Full streaming support is not on the roadmap, your suggestion makes a lot of sense.
Without a closer look I have no idea how much work replacing fetch-sparql-endpoint
would require but that's something I'll seriously consider later on.
FWIW, I used this code which I adapted from https://github.com/zazuko/d3-sparql
const xmlSchema = "http://www.w3.org/2001/XMLSchema#";
/**
* See https://www.w3.org/TR/2013/REC-sparql11-results-json-20130321/#select-encode-terms
*/
type RDFTerm =
| {
type: "uri";
value: string;
}
| { type: "literal"; value: string }
| { type: "literal"; value: string; "xml:lang": string }
| { type: "literal"; value: string; datatype: string }
| { type: "bnode"; value: string };
export type Result = Record<string, string | number | boolean | Date>;
export async function fetchSparql(endpoint: string, query: string) {
const url = endpoint + "?query=" + encodeURIComponent(query);
const sparql = fetch(url, {
method: "GET",
headers: {
Accept: "application/sparql-results+json"
}
})
.then(r => r.json())
.then(body => {
if (!body.results) {
throw Error(body.message);
}
const results: Result[] = body.results.bindings.map(function(
row: Record<string, RDFTerm>
) {
var rowObject: Result = {};
Object.keys(row).forEach(column => {
rowObject[column] = dataTypeCasting(row[column]);
});
return rowObject;
});
return results;
});
return sparql;
}
function dataTypeCasting(value: RDFTerm) {
const v = value.value;
if ("datatype" in value) {
var dt = value.datatype.replace(xmlSchema, "");
switch (dt) {
case "string":
return v;
case "boolean":
return v === "true" ? true : false;
case "float":
case "integer":
case "long":
case "double":
case "decimal":
case "nonPositiveInteger":
case "nonNegativeInteger":
case "negativeInteger":
case "int":
case "unsignedLong":
case "positiveInteger":
case "short":
case "unsignedInt":
case "byte":
case "unsignedShort":
case "unsignedByte":
return +v;
case "date":
case "time":
case "dateTime":
return new Date(v);
default:
return v;
}
}
return v;
}
I'll tackle this next. I had issues with big queries sent as a URL query, request header too large.
Replacing this lib would allow us to use POST
instead of GET
only, and as you mentioned it should keep the bundle size in check.
Fixed: 00ab2a6
I saw that you're using fetch-sparql-endpoint as a dependency which is a quite large dependency to have in the frontend (https://bundlephobia.com/result?p=fetch-sparql-endpoint@1.4.0), in part because it bundles polyfills that one already may have in their bundle anyway. If I understand correctly, the main benefit is that it supports streaming and other response formats than json – which seems quite unnecessary for our use-case where queries are always using SELECT and requested as
application/sparql-results+json
. Also, the API for this library is promises/async/await (which is good because simple!), so the potential streaming benefit is kind of lost.So I wonder if it's necessary to depend on a library which adds a lot of baggage which could (at the moment at least) be replaced with a simple
fetch()
call. Which is what I've been using so far.But maybe you have plans for full streaming support or there's something else I missed. Would love to hear your thoughts on this.