Skip to content

Instantly share code, notes, and snippets.

@symbioquine
Created March 25, 2022 03:52
Show Gist options
  • Save symbioquine/ed505283c4d5b78bba06aa18483e5222 to your computer and use it in GitHub Desktop.
Save symbioquine/ed505283c4d5b78bba06aa18483e5222 to your computer and use it in GitHub Desktop.
Using Drupal Subrequests from Javascript
import makeDrupalSubrequest from '@/makeDrupalSubrequest';
const assetTypes = ['animal', 'land', 'plant'];
async main() {
const filterQueryString = `filter[is_location]=1`;
async function* paginateAssets() {
const requests = assetTypes.map(assetType => ({
id: assetType,
path: `/api/asset/${assetType}?${filterQueryString}`,
verb: 'GET',
}));
const pendingRequestsById = {};
requests.forEach(r => pendingRequestsById[r.id] = r);
while (Object.keys(pendingRequestsById).length > 0) {
const responses = await makeDrupalSubrequest(Object.values(pendingRequestsById));
const assets = responses.flatMap(r => r.data.data);
for (let asset of assets) {
yield asset;
}
responses.forEach(r => {
const nextLink = r.data.links.next?.href;
if (nextLink) {
pendingRequestsById[r.requestId].path = nextLink;
} else {
delete pendingRequestsById[r.requestId];
}
});
}
}
for await (let asset of paginateAssets(requests)) {
console.log(`Asset '${asset.attributes.name}' is a location asset!`);
}
}
main();
import axios from 'axios';
function createDrupalUrl(pathSuffix) {
return new URL(pathSuffix, window.location.origin + '/');
}
// https://git.drupalcode.org/project/subrequests/-/blob/18b0d853f839f46a1bbed7cc7e2a3fd7b9820c46/src/Normalizer/JsonSubrequestDenormalizer.php#L96-117
const ACTION_BY_HTTP_VERB = {
POST: 'create',
PATCH: 'update',
PUT: 'replace',
DELETE: 'delete',
HEAD: 'exists',
OPTIONS: 'discover',
};
export default async function makeDrupalSubrequests(requests) {
const subrequestBlueprint = requests.map(request => ({
requestId: request.id || undefined,
uri: createDrupalUrl(request.path),
action: ACTION_BY_HTTP_VERB[request.verb] || 'view',
headers: request.headers || {},
body: request.body ? JSON.stringify(request.body) : undefined,
}));
const subrequestsResponse = await axios.post(createDrupalUrl('/subrequests?_format=json'), subrequestBlueprint, {
headers: {
'Content-Type': 'application/vnd.api+json',
Accept: 'application/vnd.api+json',
},
});
const responses = Object.keys(subrequestsResponse.data)
.map(requestId => {
const r = subrequestsResponse.data[requestId];
return {
requestId,
data: JSON.parse(r.body),
status: r.headers.status,
headers: r.headers,
};
});
return responses;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment