Introduction

IBM Operational Decision Manager (ODM) V8.8 provides the ability to adapt decision logic of applications at the speed of business. Its dedicated rule authoring and validation environments for business stakeholders gives visibility into, control over, and automation of point-in-time business decisions.
ODM on Cloud provides the same capabilities and benefits, through a Cloud based offering managed by IBM.
This article is valid for both offerings. It is assuming that the reader is familiar with the main concepts in ODM Standard (Decision Server Rules and Decision Center) or ODM on Cloud.
If you want to view the latest ODM capability to API support please also read New OpenAPI support in ODM Standard V8.9 and ODM on Cloud
 

RESTful web service for an executable decision service

ODM can expose a decision service as a web service with REST/JSON endpoints, for a ruleset generated from the decision service and deployed in Rule Execution Server.
That web service is automatically created, thanks to the Hosted Transparent Decision Service (HTDS) feature in Rule Execution Server:
htds
In this article, we will use the HTDS web service exposed as a REST API:
htds2

Describing a REST API

ODM application developers may wish then to describe the RESTful API for such a web service and facilitate its consumption into calling applications. Users can also turn that API into a managed API, for use with Decision Connect or a standalone instance of an API Management platform such as IBM API Connect.
 
That’s where the OpenAPI specification, also known as the Swagger specification, comes to play: the purpose of this widely adopted specification is to allow API consumers to easily understand and consume APIs.
To describe and document a RESTful web service, a developer needs to create a so called Swagger file, based on the specification format. The Swagger 2.0 API specification format is documented at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md.
That Swagger file can then be interpreted by dedicated tools and other developers in charge of integrating the related web service.
This article describes how to create a Swagger file for an ODM executable decision service, exposed as a RESTful web service in Rule Execution Server in ODM V8.8 and ODM on Cloud service in 2016.
 

Structure of a Swagger description file

Before going through a Swagger example applied to ODM, let’s start with an overview of what a Swagger file is expected to contain.
 
A Swagger 2.0 file is made of 15 standardized sections, open to extensions. Only 3 of these sections are required (denoted below with bold face). These 15 sections fall into 5 main categories:

  • A mandatory header section (swagger)
  • Meta data around the API being described (info, tags, externalDocs)
  • Global configuration (host, basePath, schemes)
  • The API description (consumes, produces, paths, definitions, parameters, responses)
  • Security related descriptions (securityDefinitions, security).

 
The metadata section is free to use to attach additional information that may be useful for the developer using the API.
The global configuration are confirmation elements that may change depending on the environment, especially if the same API is found across multiple staged environments (from development to production).
The API description itself represents the main part of the work and is described thoroughly in this article.
The security section depends on the authentication mechanisms applied at the application server configuration level for the ODM HTDS application. A simple example using Basic Authentication is given in this article, more advanced authentication mechanisms can be described with swagger, such as API keys and OAuth.
 
Swagger 2.0 supports 2 file formats, one being JSON and the other YAML. In this article we will provide Swagger file excerpts in the YAML format.
 

Swagger example file for a simple decision service

Let’s now see how to create a new Swagger file for an ODM executable decision service.
For that, we’re considering a decision service for automated loan approval, from a fictitious “ASAP Fund” company. That service is available as a RESTful web service in ODM Rule Execution Server.
The final Swagger example file is available at the end of this article.
 

Header section:

The file starts with:

swagger: '2.0'

Metadata:

We recommend including an info section, to give the API a name and a version number, and some additional descriptive information for the API users. With our example, it looks like this:

info:
  version: 1.0.0
  title: miniloan
  description: The Miniloan API from ASAP Fund Inc
  contact:
    url: www.asapfund.com/apis
    email: info-api@asapfund.com
    license:
      name: Very Open License
      url: www.asapfund.com/api-license.html

 
Adding a reference to additional documentation to support developers using the API can be done the following way:

externalDocs:
  description: Quick Guide to Miniloan APIs
  url: www.asapfund.com/api-quickguide.html

 
As tags can be used by API management and discovery tools to simplify search and quickly categorize APIs, it is a good practice to add such tags, for example:

tags:
  - name: Miniloan
    description: |
      Use this tag to highlight that an API is relevant in the miniloan context
  - name: 'Decision Service'
    description: |
      Use this tag to highlight that an API is implemented by an ODM Decision Service

 

Global configurations:

All decision services running in the same ODM Rule Execution Server share the same host and URL base path. This global configuration section aims at representing these shared values across all the decision services.
For example, let’s assume the Rule Execution Server being used is the production runtime environment of an ODM on Cloud subscription for our fictitious ASAP Fund company. On that server, decision services can only be accessed through https requests, so this section would be:

host: asapfund.bpm.ibmcloud.com
basePath: /odm/dev/DecisionService/rest
schemes:
  - https

 

API Description:

All decision services running in the same Rule Execution Server can leverage JSON payload format for their input and output parameters, the consumes and produces sections can be set globally to the json MIME type, like this:

consumes:
  - application/json
produces:
  - application/json

 
If one prefers, this global setting can be skipped and replaced by similar subsections in each path described, i.e. repeated for each decision service exposed in the API.
 
Each decision service may have different input parameters and responses, so we recommend not to use parameter and response global settings for decision services API descriptions, and to omit these sections from the Swagger file. However, if several decision operations actually share exactly the same parameters or responses, it is possible to share the description of these particular parameters or responses in order not to repeat their definition. See the Swagger specification to leverage this capability.
 
For each API added to the Swagger file, one entry is required in the paths section. In this example, we consider we have only one decision service API to describe. If you have more decision service APIs to describe, you just need to add an additional entry in the paths section for each API, similar to the one described below.
 
Assuming the decision service API we describe is the one corresponding to a ruleset called “Evaluate” in a “MiniloanService” ruleApp, the path will be /MiniloanService/Evaluate. At invocation time, this will select the latest version of the Evaluate ruleset in the latest version of the MiniloanService ruleApp. If the objective is to expose the versioning scheme of ruleApps and rulesets so that the calling application choses a specific ruleapp and/or ruleset version, the path may include these versions. For instance, the path becomes /MiniloanService/1.0/Evaluate (meaning the latest version of the Evaluate ruleset in the MiniloanService ruleApp at version 1.0) or /MiniloanService/1.0/Evaluate/1.4 (meaning the Evaluate ruleset at version 1.4 in the MiniloanService ruleApp at version 1.0).
 
The only http operation supported by decision web services being POST, only one post entry is expected in the decision service path.
The post operation description contains optional metadata entries, such as summary, description and tags, which provide additional information to the users of the API.
So the path description may look like:

paths:
  /MiniloanService/1.0/Evaluate:
    post:
      summary: Evaluates a loan request
      description: The /MiniloanService/Evaluate endpoint computes a loan request status from a loan request.
      tags:
        - Miniloan
        - Decision Service

Note: beware that indentation in YAML files determines the nesting structure. Any starting blank character matters.
 
Let’s now describe the input and output parameters (namely parameters and responses, in Swagger terms) of the decision service.
Decision services expect only input parameters in the http request body. These parameters are generally structured type objects (by opposition to primitive types). Information required to describe the parameters and responses of a decision service is contained in the decision operation artefact, which can be found in the decision service project in Rule Designer or in the Decision Center Business Console (ODM version 8.8 and higher).
operation
All the input and input-output ruleset parameters have to be collated into a single parameter in the post operation of the Swagger path. Let’s call that single parameter ‘Request’.
In our example, two ruleset parameters describing the loan and the borrower are constituting the decision service request. The full definition of the Request type is deferred to the definitions section of the Swagger file, which we will describe later. This gives:

      parameters:
        - name: Request
          description: Loan request payload.
          required: true
          in: body
          schema:
            $ref: '#/definitions/Request'

 
The input-output parameters and output parameters of the decision service operation are collated into a single response object, associated with the http request success code 200. For all other return codes, an error object is returned. Similarly to the Request entry, the object schema is deferred to the definitions section.
 
In our example, the successful response consists of the updated loan, like this:

      responses:
        '200':
          description: A loan evaluation response
          schema:
            $ref: '#/definitions/Response'
        default:
          description: Unexpected error
          schema:
            $ref: '#/definitions/Error'

 
Altogether, the paths section consists in:

paths:
  /MiniloanService/1.0/Evaluate:
    post:
      summary: Evaluates a loan request
      description: The /MiniloanService/Evaluate endpoint computes a loan request status from a loan request.
      tags:
        - Miniloan
        - Decision Service
      parameters:
        - name: Request
          description: Loan request payload.
          required: true
          in: body
          schema:
            $ref: '#/definitions/Request'
      responses:
        '200':
          description: A loan evaluation response
          schema:
            $ref: '#/definitions/Response'
        default:
          description: Unexpected error
          schema:
            $ref: '#/definitions/Error'

In the definitions section, we need to describe the Request type, the Response type and the Error type.
The Request type contains references to the ruleset parameters that contribute to the input of the decision operation (here, a loan and to a borrower), and optionally contains a decision ID (a unique ID to identify a decision instance).
The Response type always contains a decision ID (returned as unique generated ID when not provided in the request, or returned exactly as sent in the request), and references to the ruleset parameters that contribute to the output of the decision operation, here the loan, updated by the decision.
 
This gives:

definitions:
  Request:
    type: object
    properties:
      __DecisionID__:
        type: string
      borrower:
        $ref: '#/definitions/Borrower'
      loan:
        $ref: '#/definitions/Loan'
    additionalProperties: false
    required:
      - borrower
      - loan
  Response:
    type: object
    properties:
      loan:
        $ref: '#/definitions/Loan'
  Error:
    type: object
    properties:
      code:
        type: integer
        format: int32
      message:
        type: string
      fields:
        type: string
      stackTrace:
        type: string

 
At this stage it is necessary to consult the XOM definition of the ruleset parameters in order to describe their model in the Swagger definitions section.
A developer can do so by looking at the BOM classes for the ruleset parameters and from there their associated Java classes, as the BOM model generally does not differ much from the XOM model.
 
For instance, here is the view on the Borrower BOM class in the BOM editor:
bom
Another useful view is the generated JSON example when testing a decision service from the RES console. To reach that test view, select ‘Retrieve HTDS Description File’ in the Ruleset View and click ‘Test’:
htds-test
Here is the Test view with a request in JSON format:
htds-test2
For all these classes, object types must be created in the Swagger file. And all their required attributes must be created as properties with the appropriate type and format.
 
In our example the JSON content for a Request is:

{
  "borrower": {
    "name": "John Doe",
    "creditScore": 500,
    "yearlyIncome": 120000
  },
  "loan": {
    "amount": 1500000,
    "duration": 240,
    "yearlyInterestRate": 0.02
  },
  "__DecisionID__": "abcd456789"
}

 
And the JSON content for the Response to that Request is also visible in the RES Console test tool:

{
  "loan": {
    "amount": 1500000,
    "duration": 240,
    "yearlyInterestRate": 0.02,
    "yearlyRepayment": 0,
    "approved": false,
    "messages": [
      "The loan cannot exceed 1,000,000"
    ]
  },
  "__DecisionID__": "abcd456789"
}

 
From these examples, we can see the required attributes that need to be described in the Swagger file:

  • The Loan object requires the amount, duration and yearlyInterestRate for the object to be constructed,
  • The Borrower object requires name creditScore and yearlyIncome.

 
The corresponding description of these parameters in YAML format is described hereafter, with additional descriptive metadata for the benefit of the developer using the API:

  Loan:
    type: object
    required:
      - amount
      - duration
      - yearlyInterestRate
    properties:
      amount:
        type: integer
        description: The amount of the requested loan
        example: 10000
      duration:
        type: integer
        description: 'The duration of the loan, in months.'
        example: 120
      yearlyInterestRate:
        type: number
        format: double
        description: Yearly interest of the loan.
        example: 0.02
      yearlyRepayment:
        type: integer
        description: Yearly repayment. Computed
      approved:
        type: boolean
        description: Is the loan approved?
      messages:
        type: array
        items:
          type: string
        description: List of loan evaluation related messages.
  Borrower:
    type: object
    required:
      - name
      - creditScore
      - yearlyIncome
    properties:
      name:
        type: string
        description: Name of the borrower.
      creditScore:
        type: integer
        description: Credit Score of the borrower.
        example: 500
      yearlyIncome:
        type: integer
        description: Yearly income of the borrower.
        example: 80000

 
 

Security:

As mentioned above, the security section is more specific to the security configuration of the server hosting the decision service application. For example, with ODM on Cloud, basic authentication (user/password pair) is the only mechanism supported currently. Hence, we just need to add:

securityDefinitions:
  basicAuth:
    type: basic
    description: HTTP Basic Authentication.
security :
  - basicAuth : []

 
For other configurations of ODM installation, one can leverage OAuth 2.0 authentication style or API keys (or no authentication at all).
 

Leveraging the decision service API description in IBM API Connect

The Swagger file for one or several decision services is the base document to create a managed API in a management platform such as IBM API Connect. Most of the Swagger file content can be reused directly (operations and definitions description in particular). API Connect then acts as a gateway to ODM Rule Execution Server and transmits API calls to that ODM server.
 
Another article will describe in details how to transform the RESTful API of a decision service into a managed API, thanks to IBM API Connect and the Swagger file described in this article.
 

File attached to this article:

The final Swagger file for miniloan decision service to be added soon.
 

Author:

Nicolas Sauterey, ODM Architect, sauterey@fr.ibm.com
 
Contributors:
Antony Viaud, ODM Offering Manager, antony.viaud@fr.ibm.com
Andy Ritchie, Smarter Process Offering Manager, andy_ritchie@uk.ibm.com

Learn more:

    2 responses to “How to expose the API of an executable decision service in ODM with a Swagger description”

    1. Note that this procedure is is simpler using the latest ODM on Cloud.
      The Rule execution server tutorial Executing a hosted transparent decision service explains how to proceed in task 3 and task4.

      • Yes. It is much easier in latest versions of ODM on Cloud and recently announced ODM V8.9. We shall have a new article out soon demonstrating how easy this now is.

    Leave a Reply

    Your email address will not be published.