RESTful Services Orchestration with Kogito and OpenAPI

The invocation of remote services plays a big role in workflow orchestration. In this blog post, we will take a look at RESTful service orchestration using Kogito and the OpenAPI specification.

CNCF Serverless Workflow Implementation

Kogito is a modern business automation runtime. In addition to flowchart and form-based workflow DSLs, it also supports CNCF Serverless Workflow, a declarative workflow DSL that targets the serverless technology domain. At the time of this writing, Kogito supports a subset of features of the 0.5 of the specification version.

Since version 1.3.0, Kogito has the ability to define workflows that can orchestrate RESTful services described via OpenAPI. This fits well with the Serverless Workflow specification, where OpenAPI is the default standard for describing RESTful services. In other words, you don’t need to worry about writing boilerplate client code to orchestrate RESTful services. All you need to do is to declare the service calls!

Understanding function declarations with OpenAPI

Our business requirement is to write a simple serverless temperature converter. To do this, we want to write a workflow that can orchestrate two existing RESTful services, namely Multiplication and Subtraction services.

These two services are described via OpenAPI, meaning they are described in a programming language-agnostic way. This means that you do not need to know how to write the code that invokes these services.

Kogito reads this function definition during build time. It contains the needed information to generate REST client code based on these OpenAPI specification files during build time. The code generated is based on the OpenAPI Generator tool, now embedded in our platform.

In our workflow definition, we have to know the location of the services’ OpenAPI definition and the specific operation we want to invoke on the defined service.

Serverless Workflow allows us to define reusable function definitions. These definitions represent an invocation of an operation on a remote service. Function definitions have a domain-specific name and can be referenced by that name throughout workflow control-flow logic when they need to actually be invoked. Below is our workflow function definition we will use throughout the blog post:

"functions": [
      {
        "name": "multiplication",
        "operation": "specs/multiplication.yaml#doOperation"
      },
      {
        "name": "subtraction",
        "operation": "specs/subtraction.yaml#doOperation"
      }
   ]

Calling your RESTful Services

With this in place, invoking these services in the workflow becomes trivial. All we have to do is define when in the workflow control-flow logic they need to be invoked. Workflow control-flow logic in Serverless Workflow is defined within the "states" block. This is where you define all your workflow states (steps) and the transitions between them:

"states": [
    {
      "name": "Computation",
      "actionMode": "sequential",
      "type": "operation",
      "actions": [
        {
          "name": "subtract",
          "functionRef": {
            "refName": "subtraction",
            "parameters": {
              "subtractionOperation": { 
                 "leftElement": "$.fahrenheit", 
                 "rightElement": "$.subtractValue"
              }
            }
          }
        },
        {
          "name": "multiply",
          "functionRef": {
            "refName": "multiplication",
            "parameters": {
              "multiplicationOperation": {
                "leftElement": "$.subtraction.difference", 
                "rightElement": "$.multiplyValue" 
              }
            }
          }
        }
      ]
    }
  ]

Going back to our business requirements, for temperature conversion, our workflow needs to call the two services in a certain order. First, we want to execute the Multiplication service and then the Subtraction service. The Operation state is perfect for what we need.

The parameters are taken from the workflow data input and processed with JSONPath expressions. And how do we know how to define these parameters? It’s just a matter of extracting from the OpenAPI Specification file:

# ...
operationId: doOperation
requestBody:
  content:
    application/json:
      schema:
        $ref: '#/components/schemas/MultiplicationOperation'
# ...
components:
  schemas:
    MultiplicationOperation:
      type: object
      properties:
        leftElement:
          format: float
          type: number
        product:
          format: float
          type: number
        rightElement:
          format: float
          type: number

The workflow declares two functions that represent the service operations that should be invoked during workflow execution. The first one, multiplication, will execute the operation doOperation from the OpenAPI specification file in our project’s classpath (Kogito also supports file and http schemas). Same thing for the subtraction function.

Since this operation only needs one parameter, we can name it as we like (in this case, multiplicationOperation). For operations that require multiple parameters (like query strings), you should use the same names as defined by the OpenAPI specification.

Configuring the Endpoints

The last piece of this puzzle is to define the URL for each of the services we want to invoke. To do so, declare the URLs in your application properties file. You should set a configuration like: org.kogito.openapi.client.<spec file name>.base_path=http://myservice.com.

This is a runtime property that can be defined using any method the target runtime (Quarkus or SpringBoot) supports. But if the OpenAPI Specification file declares the endpoint URL, you don’t even need to bother. Take a look at the PetStore, for example:

host: petstore.swagger.io
basePath: v2
schemas:
  - http
  - https

Now you’re ready to call your newly generated Kogito Workflow and start orchestrating services! You can find the full Temperature Conversion workflow example here.

TIP: If you’re curious about the CNCF Serverless Workflow Kogito implementation, please take a look at these references:

If you have any questions about this new feature, please drop a question on the Kogito development community list. We would love to hear from you!

* Featured photo by Wan San Yip on Unsplash

0 0 vote
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments