You can use this API to find which compositions have a specific pattern, so when it is published you can find which URLs to purge from CDN. Please find the example Uniform webhook handler code below:
This is a sample code and should be optimized. It doesn’t include the composition cache purge, only the pattern logic
const findAffectedPaths = async (patternId: string) => {
const response = await fetch(
"https://uniform.app/api/v1/relationships?ids=" +
patternId +
"&withInstances=true&type=componentPattern&limit=10&offset=0&projectId=411d562d-3340-4b3b-8258-2950a48aab4f",
{
method: "GET",
headers: {
"x-api-key": process.env.UNIFORM_API_KEY,
},
}
);
const data = await response.json();
const allCompositionIds = data.flatMap((item) =>
item.instances.map((wrapper) => wrapper.instance._id)
);
const pjmapClient = new ProjectMapClient({
projectId: process.env.UNIFORM_PROJECT_ID,
apiHost: process.env.UNIFORM_CLI_BASE_URL,
apiKey: process.env.UNIFORM_API_KEY,
});
// getting all the affected project map nodes
const allProjectMapNodes = await Promise.all(
allCompositionIds.map(async (compositionId) => {
const { nodes } = await pjmapClient.getNodes({
compositionId: compositionId,
});
return nodes;
})
);
// getting only the path from the project map nodes
const pathsToRevalidate: string[] | undefined = allProjectMapNodes
?.flat()
.map((n) => {
// here we replace any encounter for a dynamic path like :article-title with *, so all the dynamic pages will be purged under this path like /blog/*
return n?.path?.replace(/\\:.*/g, "*");
});
return pathsToRevalidate;
};
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const payload = (await buffer(req)).toString();
const client = new ProjectMapClient({
projectId: process.env.UNIFORM_PROJECT_ID,
apiHost: process.env.UNIFORM_CLI_BASE_URL,
apiKey: process.env.UNIFORM_API_KEY,
});
const canvasClient = new CanvasClient({
apiKey: process.env.UNIFORM_API_KEY,
projectId: process.env.UNIFORM_PROJECT_ID,
apiHost: process.env.UNIFORM_API_HOST ?? process.env.UNIFORM_CLI_BASE_URL,
});
const payloadObject = JSON.parse(payload);
// we need to get the composition to know if this is pattern or not
const pujblishedCompositionData = await canvasClient.getCompositionById({
compositionId: payloadObject.id,
state: 64,
});
if (pujblishedCompositionData?.pattern) {
const affectedPaths = await findAffectedPaths(payloadObject.id);
if (affectedPaths) {
// code for the CDN purge logic
}
}
}