OpenAPI import tool

Official Content
This documentation is valid for:
Note: From v17u6 onwards, GeneXus supports both version 2 and version 3 of OpenAPI specification. The OpenAPI importer detects automatically whether the spec refers to version 2 or 3).

The main purpose of the OpenAPI import tool is to inspect the Open Api RESTful API Documentation (fka Swagger RESTful API Documentation Specification) of any RESTful web service (it can be generated by GeneXus or not).

With the information obtained using the OpenAPI Import tool, implementing a consumer is much plain sailing because it consolidates in the KB some objects (Procedures, SDTs, Domains) which are necessary to consume the RESTful service. After that, it's easy to follow the tutorial HowTo: Inserting data using a BC exposed as Rest service.

The advantage of using the OpenAPI import tool is to avoid the effort of Getting information from the Swagger UI docs, such as the operations, the HTTP verb needed to consume the web service, the input and output parameters (the HTTP body structure for invoking the service and the responses).

Note that the OpenAPI documentation of  Rest web services in GeneXus is obtained through the Generate OpenAPI interface property.

The tool is accessible through the Tools > Application Integration > OpenAPI import menu option.

image_20171230143555_1_png

OpenAPI import tool dialog

File Path /Url:  Enter the URL or file path of the RESTful service documentation in Swagger format.

Swagger Format:

The files describing the RESTful API in accordance with the Swagger specification are represented as JSON objects and conform to the JSON standards. YAML, being a superset of JSON, can be used as well to represent a Swagger specification file.

For Rest web services in GeneXus you can obtain the Swagger file if you activate the Generate OpenAPI interface property.

Module / Folder: Where the automatically generated objects will be located.

image_20171230143319_1_png

Note: It's strongly recommended to choose a module where the automatically created objects from the YAML file will be located in order to maintain KB modularization and avoid undesired objects modifications. 
For example, if a structure named "Customers" is included in the YAML file, a "Customers" SDT will be created when this YAML is imported. If an SDT named "Customers" already exists in the KB, it will be modified (replaced by the structure included in the YAML file). If the imported objects are created in a module (e.g. CRM), the SDT will be created as "CRM.Customers" and will not replace the existing one.

Results of using the OpenAPI import tool

The tool consolidates in the KB some objects (procedures, SDTs, domains) which are necessary to consume the RESTful service.

The following is a summary of the objects which are consolidated in the KB:

Object Folder / Module Purpose
ApiResponse SDT OpenAPICommon Defines the HTTP response structure
CallApi procedure OpenAPICommon It's a parameterized procedure that given the service URL and the call parameters, executes the HTTP verb and returns the HTTP result.
VarCharToJsonFormat, 
DateTimeToJsonFormat, 
DateToJsonFormat, 
NumericToJsonFormat
OpenAPICommon Auxiliary procedures
AuthREADME (*) OpenAPICommon Procedure showing information got from imported specificacion about OAuth 2.0 and/or OpenID Connect flows.
ProcessServer (*) OpenAPICommon As server templating is allowed in OpenAPI 3.0, this procedure addresses the replacement of the values given by the user when calling procedure under "Api" folder (through the &ServerUrlTemplatingVar parameter) in the baseURL.
ApiBaseUrl <MyModule>\Client

Returns the BaseURL which will be used for calling the RESTful services. It should be changed in most cases.

When OpenAPI 3.0 specification is imported, this procedure shows all the servers present in the specification, leaving only one uncommented (the first one). 

client procedure of the RESTful service <MyModule>\Api

A procedure to invoke the service. The name of this procedure is selected upon the operationId* in the documentation file (Swagger) of the service.

*operationId: Unique string used to identify the operation. The id is unique among all operations described in the API. 

SDTs needed for defining the input and output parameters of the service. <MyModule>\Model Input and output parameters of the service.

(*) Generated when importing version 3 only.

Example

In this example, we are showing the import of PetStore specification.

Note: This is an OpenAPI 3.0 specification import example. To see an example in version 2, refer to the previous version.

KB Explorer structure example

The following is the KB Explorer structure after importing the YAML file associated with the procedure of the example.

KBExplorerStructureImage

After inspecting the Swagger document of PetStore using the OpenAPI Import tool in the consumer KB, it automatically generates a procedure called CreateUsersWithListInput under the PetStoreModule\Api path. "PetStoreModule" is a module in this example, where we have chosen to import the objects generated by the tool.

Below is the part of the Swagger document which corresponds to the service we are inspecting. Note the operationId value that determines the name of the procedure to consume the RESTful service.

/user/createWithList:
    post:
      tags:
        - user
      summary: Creates list of users with given input array
      description: Creates list of users with given input array
      operationId: createUsersWithListInput
      requestBody:
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: '#/components/schemas/User'
      responses:
        '200':
          description: Successful operation
          content:
            application/xml:
              schema:
                $ref: '#/components/schemas/User'
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        default:
          description: successful operation

The User is an SDTs automatically generated by the tool for both RequestBody and Response (in this case matches the type, but this is not always the case).

The parameter information is also obtained from the Swagger file.

components:
  schemas:
    ...
    User:
      type: object
      properties:
        id:
          type: integer
          format: int64
          example: 10
        username:
          type: string
          example: theUser
        firstName:
          type: string
          example: John
        lastName:
          type: string
          example: James
        email:
          type: string
          example: john@email.com
        password:
          type: string
          example: '12345'
        phone:
          type: string
          example: '12345'
        userStatus:
          type: integer
          description: User Status
          format: int32
          example: 1
      xml:
        name: user

The following parm rule is generated in the CreateUsersWithListInput consumer object which is a stub for calling the service.

parm(in:&ServerUrlTemplatingVar,  in:&body, out:&UserOUT, out:&HttpMessage, out:&IsSuccess);

The &ServerUrlTemplatingVar parameter is present in all consumer procedures. This is a variable of type "Properties", which is responsable for assigning values in the templated variables at the baseURL. As an example, let's suppose we have the following baseURL:

{scheme}://{host}:8082/APIObjectPlayground.NETCoreEnvironment/rest

&ServerUrlTemplatingVar can be setted as follows:

&ServerUrlTemplatingVar.Set("scheme","https")

&ServerUrlTemplatingVar.Set("host","example")

This generates that the baseURL stands as:

https://example:8082/APIObjectPlayground.NETCoreEnvironment/rest

To ease values assignment for this templating, domains may be generated containing enums with possible value ranges to assign. These domains are named like "TemplateServer_{key_name}". For example (and keeping on with the previous case), if a domain would have been generated for the "scheme" key, its name had been "TemplateServer_scheme". This is done if and only if the specification has indicated the enum.

So, in order to call the service, you just need to call the CreateUsersWithListInput consumer object by passing it the corresponding parameters and then processing the results.

Sample consumer code

PetStoreModule.CreateUsersWithListInput(&ServerUrlTemplatingVar,&User,&UserOUT,&HttpMessage,&IsSuccess)
if &IsSuccess
    msg("Success!!")
else
    msg("There was an error! ")    
endif
msg("API return: " + &UserOUT.ToJson())
msg("HTTP Message " + &HttpMessage.Id + " " + &HttpMessage.Description)

This is rather easier than defining the input and output parameters manually and executing the HTTP verbs using HTTP client data type. This task is done by the OpenAPI Import tool, which generates the code for you.