Skip to main content

Async Requests

For larger or longer-running jobs, Geoflip provides an option to process requests asynchronously by adding the ?async=true URL parameter to any API request. This allows the request to be queued and processed in the background, while Geoflip immediately returns a task ID instead of processing the request synchronously.

How to Use Async Requests

Initiating an Async Request

To start an asynchronous request, simply add ?async=true to the end of any transformation route. This will trigger Geoflip to create a task for the job and return a response with a task_id:

Example Request URL: https://api.geoflip.io/v1/transform/geojson?async=true

Example Initial Response
{
"message": "Geoflip GPKG task has been created",
"state": "TASK CREATED",
"task_id": "cec5b73c-b70a-4c23-88f6-7c50e212ad5d"
}

Checking the Status of an Async Task

With the task_id from the initial response, you can periodically check the status of your geoprocessing task using the following endpoint:

https://api.geoflip.io/v1/transform/result/{{task_id}}

Geoflip will respond with the current state of the task:

  • TASK CREATED: The task is created and queued for processing.
  • PROCESSING: The task is currently being processed.
  • SUCCESS: The task has completed successfully.
  • FAILED: The task encountered an error and did not complete.
example status response
{
"message": "Task is processing",
"state": "PROCESSING"
}

Retrieving the Completed Result

Once the task has reached the "SUCCESS" state, Geoflip will provide an output_url where you can download the processed data:

Example: Async Result Success
{
"message": "Task completed successfully",
"output_url": "https://api.geoflip.io/v1/transform/output/o_cec5b73c-b70a-4c23-88f6-7c50e212ad5d",
"state": "SUCCESS"
}

Important notes

  • One-Time Use URL: The output_url is valid for a single download only. Once accessed and the data is retrieved, the source data will be deleted, and the URL will no longer be accessible.
  • Polling Frequency: To minimize server load, avoid excessive polling. A reasonable interval for checking task status could be every 15-30 seconds, depending on the complexity of the task.
  • Error Handling: If the task fails, the response will include an error message. You can inspect this message to understand the cause and decide whether to retry the request.

Using asynchronous requests in Geoflip enables you to handle large and complex geoprocessing tasks without waiting for immediate processing, allowing your application to remain responsive and efficient.

Full Async Request Example

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GeoFlip Async GeoJSON to SHP Conversion</title>
</head>
<body>
<h1>Async GeoJSON to SHP Conversion</h1>

<input type="file" id="fileInput" accept=".geojson" />
<button id="convertButton">Convert to SHP</button>

<p id="statusMessage">Status: Waiting for input...</p>
<a id="downloadLink" style="display:none;">Download SHP File</a>

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
const convertButton = document.getElementById('convertButton');
const fileInput = document.getElementById('fileInput');
const statusMessage = document.getElementById('statusMessage');
const downloadLink = document.getElementById('downloadLink');

convertButton.addEventListener('click', async () => {
const selectedFile = fileInput.files[0];
if (!selectedFile) {
statusMessage.textContent = "Please select a GeoJSON file.";
return;
}

// Prepare the form data
const formData = new FormData();
formData.append('file', selectedFile);

// Payload configuration
const config = {
output_format: "shp", // Desired output format
output_crs: "EPSG:4326" // Output CRS (WGS84)
};
formData.append('config', JSON.stringify(config));

try {
// Initiate async request
const response = await axios.post(
'https://api.geoflip.io/v1/transform/geojson?async=true',
formData,
{
headers: {
'Content-Type': 'multipart/form-data',
'apiKey': 'YOUR_API_KEY' // Replace with your Geoflip API key
}
}
);

if (response.status === 200 && response.data.task_id) {
const taskId = response.data.task_id;
statusMessage.textContent = "Task created. Checking status...";

// Polling for task completion
const checkTaskStatus = setInterval(async () => {
try {
const taskResponse = await axios.get(`https://api.geoflip.io/v1/transform/result/${taskId}`, {
headers: { 'apiKey': 'YOUR_API_KEY' }
});

if (taskResponse.data.state === "SUCCESS" && taskResponse.data.output_url) {
clearInterval(checkTaskStatus);

// Provide the download link
downloadLink.href = taskResponse.data.output_url;
downloadLink.textContent = "Download SHP File";
downloadLink.style.display = "block";
statusMessage.textContent = "Conversion complete! Click the link to download.";
} else if (taskResponse.data.state === "FAILED") {
clearInterval(checkTaskStatus);
statusMessage.textContent = "Conversion failed. Please try again.";
} else {
statusMessage.textContent = `Status: ${taskResponse.data.state}...`;
}
} catch (error) {
clearInterval(checkTaskStatus);
statusMessage.textContent = "Error checking task status.";
}
}, 5000); // Check every 5 seconds
}
} catch (error) {
statusMessage.textContent = "Error initiating async conversion.";
console.error('Error initiating async conversion:', error);
}
});
</script>
</body>
</html>