Processes Service basics

The OGC API Processes Service is accessed via the Processes version 1.0 link on the home page.

../../_images/ogcapi-processes.png

The landing page (at http://localhost:8083/geoserver/ogc/processes/v1) provides clients with a starting point for using the API, through a collection of resources, with links for navigation between content. The following screenshot shows the HTML representation of the landing page.

../../_images/ogcapi-processes-landing.png

The service title and description are provided by the existing Web Processing Service (WPS) settings.

The API definition provides an OpenAPI description of the available resources and the operation that can be perfomed on them. The following is the HTML representation:

../../_images/api-definition-swagger1.png

Processes and process description

Unlike most of the other OGC API services, Processes does not provide a list of collections. Instead, it provides a list of available processes.

../../_images/processes.png

Each process is described by a process definition, which provides the process title, description, inputs and outputs, and other metadata. For example, let’s focus on JTS:buffer process, which creates a buffer around a geometry:

../../_images/buffer-description.png

The JSON representation of the process definition is available at http://localhost:8083/geoserver/ogc/processes/v1/processes/JTS:buffer?f=json. Here is the output:

{
   "id": "JTS:buffer",
   "version": "1.0.0",
   "title": "Buffer",
   "description": "Returns a polygonal geometry representing the input geometry enlarged by a given distance around its exterior.",
   "jobControlOptions": [
      "sync-execute",
      "async-execute"
   ],
   "inputs": {
      "geom": {
         "title": "geom",
         "description": "Input geometry",
         "schema": {
         "title": "Geometry",
         "oneOf": [
            {
               "type": "string",
               "contentMediaType": "application/wkt"
            },
            {
               "type": "string",
               "contentMediaType": "application/ewkt"
            },
            {
               "type": "string",
               "contentMediaType": "application/gml-3.1.1"
            },
            {
               "type": "string",
               "contentMediaType": "application/gml-2.1.2"
            },
            {
               "type": "string",
               "contentMediaType": "application/json"
            }
         ]
         },
         "minOccurs": 1,
         "maxOccurs": 1
      },
      "distance": {
         "title": "distance",
         "description": "Distance to buffer the input geometry, in the units of the geometry",
         "schema": {
         "title": "number",
         "type": "number"
         },
         "minOccurs": 1,
         "maxOccurs": 1
      },
      "quadrantSegments": {
         "title": "quadrantSegments",
         "description": "Number determining the style and smoothness of buffer corners. Positive numbers create round corners with that number of segments per quarter-circle, 0 creates flat corners.",
         "schema": {
         "title": "integer",
         "type": "integer"
         },
         "minOccurs": 0,
         "maxOccurs": 1
      },
      "capStyle": {
         "title": "capStyle",
         "description": "Style for the buffer end caps. Values are: Round - rounded ends (default), Flat - flat ends; Square - square ends.",
         "schema": {
         "title": "string",
         "type": "string",
         "enum": [
            "Round",
            "Flat",
            "Square"
         ]
         },
         "minOccurs": 0,
         "maxOccurs": 1
      }
   },
   "outputs": {
      "result": {
         "title": "result",
         "description": "Buffered geometry",
         "schema": {
         "title": "Geometry",
         "oneOf": [
            {
               "type": "string",
               "contentMediaType": "application/wkt"
            },
            {
               "type": "string",
               "contentMediaType": "application/ewkt"
            },
            {
               "type": "string",
               "contentMediaType": "application/gml-3.1.1"
            },
            {
               "type": "string",
               "contentMediaType": "application/gml-2.1.2"
            },
            {
               "type": "string",
               "contentMediaType": "application/json"
            }
         ]
         }
      }
   }
}

From this description we can surmise a few things:

  • The process can be invoked synchronously or asynchronously, as indicated by the jobControlOptions field.
  • The geom input and distance are mandatory, while quadrantSegments and capStyle are optional.
  • The geom input is a geometry, which can be returned in various formats, including WKT, EWKT, GML, and GeoJSON.
  • The capStyle input can take one of three values: Round, Flat, or Square.

Synchronous Process execution

In OGC API Processes execution is performed by POST-ing a JSON document to the “execution” endpoint of the process. The document contains the inputs for the process, as well as the desired outputs (should there be more than one), their format, and the execution mode.

Here is an example of a request to execute the JTS:buffer process:

{
   "inputs": {
      "geom": {
         "value": "POINT(0 0)",
         "mediaType": "application/wkt"
      },
      "distance": 10,
      "capStyle": "Square"
   },
   "outputs": {
      "result": {
         "format": {
         "mediaType": "application/json"
         }
      }
   }
}

To run it, we can save the above JSON in a file called buffer.json and POST it to the process execution endpoint:

curl  -XPOST -H "Content-Type: application/json" -d @buffer.json \
      "http://localhost:8083/geoserver/ogc/processes/v1/processes/JTS:buffer/execution"

And the output will be the buffered polygon, as a JSON geometry:

{
   "type":"Polygon",
   "coordinates":[[[10,10],[10,-10],[-10,-10],[-10,10],[10,10]]]
}

Asynchronous process execution

A process execution can also be performed asynchronously, by adding the async-execute job control option in the request. In this case, the response will contain a link to the job status, which can be polled to check if the process has completed. The job status can be polled by sending a GET request to the job status URL, which will return the current status of the process execution, including any errors that may have occurred.

For example, we could perform a more complex buffering, with a large number of segments for the corners, and executing it asynchronously:

{
   "inputs": {
      "geom": {
         "value": "LINESTRING(0 0, 10 0, 10 10, 0 10)",
         "mediaType": "application/wkt"
      },
      "distance": 10,
      "quadrantSegments": 800
   },
   "outputs": {
      "result": {
         "format": {
            "mediaType": "application/json"
         }
      }
   }
}

The asynchronos execution is requested by adding the Prefer HTTP header <https://www.rfc-editor.org/rfc/rfc7240.txt> to the request:

curl -XPOST -H "Content-Type: application/json" \
     -H "Prefer: respond-async" \
     -d @buffer.json \
     -D - \
     "http://localhost:8083/geoserver/ogc/processes/v1/processes/JTS:buffer/execution"

The -D - option will print the response headers to the console, which will include a Location header with the URL to poll for the job status:

HTTP/1.1 201 Created
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: base-uri 'self'; form-action 'self'; default-src 'none'; child-src 'self'; connect-src 'self'; font-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self';, frame-ancestors 'self';
Location: http://localhost:8083/geoserver/ogc/processes/v1/jobs/b83b9e26-f7d4-4ee1-9c04-0e15392cde62
API-Version: 1.0.0
Content-Length: 0
Server: Jetty(9.4.57.v20241219)

Following the Location header, we can poll the job status by sending a GET request to the job status URL. Since the process executes quickly, it will likely already contain a reference to download the output:

{
   "processID": "JTS:buffer",
   "type": "process",
   "status": "successful",
   "created": 1751637779583,
   "finished": 1751637779605,
   "progress": 100,
   "links": [
      {
         "href": "http://localhost:8083/geoserver/ogc/processes/v1/jobs/b83b9e26-f7d4-4ee1-9c04-0e15392cde62/results",
         "rel": "http://www.opengis.net/def/rel/ogc/1.0/results",
         "type": "application/json"
      }
   ]
}

If the process would have taken long enough, sending a DELETE request to the status URL would have cancelled the process execution.

The links array contains a link to the output of the process, which can be downloaded by sending a GET request to the URL provided in the href field. The output will be the buffered polygon, as a JSON geometry (not displayed here for brevity).

Stealing a page from the future: execution via simple GET

The draft of the next version of OGC API Processes introduces a new way to execute processes called “KVP-encoded Execute”, which simply sends a GET request to the process execution endpoint, with the inputs and outputs specified as query parameters.

GeoServer implements a preview of this feature, which can come in handy for simple processes that do not require complex inputs.

Going back to our JTS:buffer process, we can execute it by sending a GET request with the inputs and outputs specified as query parameters, with the media types indicated in square brackets for the inputs and outputs:

This results in a GeoJSON response that will be displayed directly in the browser.