How to get postgrest, postgis, and maplibre to cooperate and use geojson
Postgrest has a really snazzy feature where you can set the 'Accept: application/geo+json'
header to get your results as geojson instead of simple rows.
And Maplibre has a handy function where you can pass in a request transformer to alter all your requests to a source, like this:
function customRequestTransformer(url: string): RequestParameters {
const params = {
url: url,
headers: {
Authorization: `Bearer ${user.access_token}`,
Accept: 'application/geo+json',
},
}
return params;
}
<Map
....
transformRequest={customRequestTransformer}
>
But if you do that, you'll see that your Authorization header is added, BUT your Accept one is not. Arrgg!
Annnnd I wrote the below while I was trying to find a fix, but instead I just wrote the fix and pushed it upstream at https://github.com/maplibre/maplibre-gl-js/pull/4210 . Enjoy! The next release of Maplibre-gl-js will work properly with Postgrest now.
Open source is great.
(Below, if anyone is curious)
The culprit is here: https://github.com/maplibre/maplibre-gl-js/blob/68569cf22655c53bc474504bf07893709723f7d6/src/util/ajax.ts#L154
if (requestParameters.type === 'json') {
request.headers.set('Accept', 'application/json');
}
and then, here
export const getJSON = <T>(requestParameters: RequestParameters, abortController: AbortController): Promise<{data: T} & ExpiryData> => {
return makeRequest(extend(requestParameters, {type: 'json'}), abortController);
};
and finally, here: https://github.com/maplibre/maplibre-gl-js/blob/68569cf22655c53bc474504bf07893709723f7d6/src/source/geojson_worker_source.ts#L220
async loadGeoJSON(params: LoadGeoJSONParameters, abortController: AbortController): Promise<GeoJSON.GeoJSON> {
const {promoteId} = params;
if (params.request) {
const response = await getJSON<GeoJSON.GeoJSON>(params.request, abortController);
So loadGeoJSON calls getJSON, which always sets type: 'json
', which means our final request nukes whatever request headers we had set.