Skip to content

OpenAPIProcessor

Juraj Bielik edited this page Oct 25, 2019 · 4 revisions

Kentico Kontent Docs - OpenAPI Processor

Overview

OpenAPI Processor is a microservice responsible for creating HTML documents that represent API reference pages on the documentation portal, and passing them forward using Azure Blob Storage. It is an Azure function written in Typescript.

Specification

Trigger

The service has a single EventGrid trigger, which responds to the creation of a blob in the Azure Blob Storage.

How it works

OpenAPI Processor receives an event that includes information about the blob stored by Reference Preprocessor. The blob is retrieved from a URL that is a part of the EventGrid event. It contains data related to a single API Reference specification along with an operation that describes the performed action with it (initialize, update, preview, or delete). In the case of delete action, the service does not process the data further and stops its computation.

1. OpenAPI object generation

The OpenAPI Processor first has to transform the preprocessed data into the OpenAPI Specification 3.0.2 format. Having the content types in KK modeled in a way that vaguely satisfies the specification makes the generation algorithm a little easier. It follows the targetted format closely and it should be easy to follow in most cases.

Notable specifics of OpenAPI object generation:

  • OpenAPI's Components object serves as a place for reused items across multiple places (in our case: parameters, request bodies, responses, and schemas). Therefore, any time there is a KK's content item of the aforementioned types encountered, it does get saved within the Components object, and then only a reference to it is being inserted in the OpenAPI object. On the contrary, any KK's component is inserted directly into its place within the OpenAPI object as it cannot be reused.
  • The KK's API Reference content types contain multiple Rich Text elements, which serve 2 different purposes:
    • As a pseudo linked items element that can store components as well as content items. For example - Path Operation's Responses element that only has allowed to contain content items/components of Response type.
    • As a regular Rich Text element. All of these elements are being processed in a specific manner:
      1. Firstly, the content items and components being inserted in these elements have to be specifically handled in order to make further processing easier. Code Samples and Callouts are being marked by HTML comments, for example <!--CodeSample programmingLanguage=java platform=android--> ... <!--CodeSample-end-->. Additionally, Schemas inside Rich Text are being marked as well, by marks that identify them by their codenames.
      2. Then, the Rich Text element is being transformed into Common Mark format using the html2commonmark package. Unfortunately, this package does not handle HTML's headings <h1> and <h2> correctly. Therefore, there are util functions that handle this faulty behavior. The Common Mark text is also sanitized of any extra slashes (\) that could be added to the text by the transformation. Common Mark also does not handle HTML tables well, so any possible <code> tag inside it has to be taken care of manually in a util function.
      3. Finally, the marked items/components are inserted into the Common Mark text. All the marks for schemas are replaced by special HTML tags: <SchemaDefinition schemaRef=${schemaCodename} showReadOnly={true} showWriteOnly={true} />. Code samples are wrapped in markdown's code blocks (```) with appropriate syntax highlighters.
  • In general, OpenAPI object should not contain empty properties. This is solved by using the getGenericProperty factory function that is being reused across multiple types of properties that could be inserted. This function requires 2 functions as its parameters:
    1. ConditionFunction that checks whether the data to be inserted into an OpenAPI property is not empty.
    2. InsertionFunction that specifies how the specific data is supposed to be inserted into the OpenAPI property.

2. OpenAPI validation

After the OpenAPI object has been successfully generated (as a JSON object), it then gets validated by an OpenAPI Schema Validator. In case of any encountered error, a notification can be sent to any MS Teams Channel using Notifier service.

Additionally, the generated JSON is also saved in Azure Blob storage, where the complete API Specification can be accessed and shared with our customers.

3. Transformation to HTML

Finally, the JSON object is traversed and processed one more time. Then, the forked kentico-kontent-docs-redoc package is used to generate the API Reference HTML page from the OpenAPI-compliant JSON object. As a final step, the generated HTML is stored in an Azure Blob Storage.

Configuration for integration tests

If the blob sent by Reference Preprocessor is stored in a folder with -tests suffix, this service runs with an alternative set of environment variables that are used for integration tests. Consecutively, the OpenAPI Processor then also saves the generated HTML into a container with -tests suffix.