Integration Modelling
Overview
K5 SDK enables Integration modelling for NestJS-based services, to easily manage integrations to external services within the Solution Designer UI, and provides easy access to integration methods.
When Integration Modelling is enabled, the K5 SDK provides dedicated integration modules per API dependency that can be imported into the project.
Integration is controlled via the project configuration file k5-project.yml
See also: Integration Modelling
Usage
Assuming a Petstore
integration namespaces, containing an API dependency is modelled through the Solution Designer UI, the PetstoreIntegrationModule
module can be imported into the project as follows:
import { PetstoreIntegrationModule } from 'k5-sdk';
@Module({
imports: [PetstoreIntegrationModule],
controllers: [MyAPIController],
providers: [],
})
export class MyAPIModule {}
Then, controllers and services within your project can use the Petstore
integration service as follows:
import { Request, Response } from 'express';
import { PetstoreIntegrationService, K5LoggerService } from 'k5-sdk';
@Controller('/my-api')
export class MyAPIController {
constructor(
private readonly logger: K5LoggerService,
private petStoreService: PetstoreIntegrationService,
) { }
@Post('/')
async postSomething( req: Request, res: Response): Promise<any> {
this.logger.info(`Starting "postSomething" operation`);
const findPetsResponse = await this.petStoreService.findPetsByStatus({ status: ['pending'] });
return findPetsResponse.data;
}
}
Accessing the Integration Models
K5 SDK exports Integration models, e.g. PetstoreIntegrationModels
, which define types for integration API requests and responses, including schemas, query parameters, and headers. These models facilitate type-safe integration by ensuring consistency in request and response structures.
import { Request, Response } from 'express';
import { K5LoggerService, PetstoreIntegrationService, PetstoreIntegrationModels } from 'k5-sdk';
@Controller('/my-api')
export class MyAPIController {
constructor(
private readonly logger: K5LoggerService,
private petStoreService: PetstoreIntegrationService,
) { }
@Post('/')
async postSomething( req: Request, res: Response): Promise<Array<PetstoreIntegrationModels.Pet>> {
this.logger.info(`Starting "postSomething" operation`);
/**
* Status values that need to be considered for filter
* status: Array<'available' | 'pending' | 'sold'>;
*/
const queryParams: PetstoreIntegrationModels.PetstoreServiceFindPetsByStatusQueryParam = { status: ['available'] };
/**
* AxiosResponse<Array<Pet>>
*/
const findPetsResponse: PetstoreIntegrationModels.FindPetsByStatusResponse = await this.petStoreService.findPetsByStatus(queryParams);
return findPetsResponse.data;
}
}
API Binding
The k5 SDK also exports the K5APIBindingService
which provides methods to acquire the API bindings of the integration services.
API bindings are externalized specifications created per API dependency. They can be used to store API-related configuration information, that may be stage-dependent.
API bindings are typically used to store, e.g.
- url
- username
- password
- API-Key
- ... for the 3rd party service you want to access.
Example binding:
{
"url": "http://example.com/dev"
}
DEV-Bindings
Dev-Bindings provide an easy way to specify some default values, which are easily accessible on all non-production stages. They are meant to be used for rapid development to avoid long and extensive configuration outside of the project.
DEV-Binding can be created and speciified inside the Solution Designer. To do so, you go to the Integration Namespace you want to use for interacting with this API (or create a new namespace) and create an API dependency. There you will find an input field where you can place your information as JSON formatted key/value pairs.
Please be aware, that all information entered into DEV bindings will go into the Git repository! To prevent this, you can instead create an API binding for the same purpose, since they get stored as OpenShift secrets inside the cluster.
Programmatically Access the Binding
API bindings can be accessed through the K5APIBindingService
as follows:
import { Request, Response } from 'express';
import { K5LoggerService, K5APIBindingService } from 'k5-sdk';
@Controller('/my-api')
export class MyAPIController {
constructor(
private readonly logger: K5LoggerService,
private bindingService: K5APIBindingService,
) { }
@Post('/')
async postSomething( req: Request, res: Response): Promise<any> {
this.logger.info(`Starting "postSomething" operation`);
const myBinding = await this.bindingService.getPetstoreAPIBinding();
return {};
}
}
Local Development
To set API bindings during local development, create a local configuration file (YAML or JSON format) and place it in your project's root directory. Make sure it's added to the .gitignore
file, so it will not get uploaded to your git repository.
This configuration file should then be loaded into the project using the loadConfigFile
method provided by k5 SDK.
import { K5SDKModule, loadConfigFile } from 'k5-sdk';
@Module({
imports: [
ConfigModule.forRoot({ load: [loadConfigFile('local-config.yaml')] }),
K5SDKModule.forRoot({}),
],
controllers: [],
providers: [],
})
export class AppModule {}
To setup API bindings in the local config file, simply provide the k5ApiBindings
property, containing the API bindings for each integration namespace's API dependency.
k5ApiBindings:
mypet-pet:
url: https://petstore.swagger.io/v2
k5_propagate_security_token: false
customProperty: customValue
The key of the API bindings is the combination of the integration namespace name and the API dependency name, separated by a hyphen -
.
Customization
Customizing the Integration Modules
The Integration modules module can be customized to use custom axios configurations, this is done through the axiosConfig
optional property [type: CreateAxiosDefaults
] of the forRoot
method of the integration module.
import { PetstoreIntegrationModule } from 'k5-sdk';
@Module({
imports: [
PetstoreIntegrationModule.forRoot({
axiosConfig: { baseURL: 'https://petstore.swagger.io/v2/' }, // optional CreateAxiosDefaults
}),
],
controllers: [MyAPIController],
providers: [],
})
export class MyAPIModule {}
Customizing an Integration Method Call
Additionaly, every call to an integration service method can also use a custom config
property [type: AxiosRequestConfig
] as an optional last argument of the method, this enables customization of the request made to the integration service without overriding the default configuration used by the whole integration module.
import { Request, Response } from 'express';
import { PetstoreIntegrationService, K5LoggerService } from 'k5-sdk';
@Controller('/my-api')
export class MyAPIController {
constructor(
private readonly logger: K5LoggerService,
private petStoreService: PetstoreIntegrationService,
) { }
@Post('/')
async postSomething( req: Request, res: Response): Promise<any> {
this.logger.info(`Starting "postSomething" operation`);
const findPetsResponse = await this.petStoreService.findPetsByStatus(
{ status: ['pending'] },
{ decompress: true }, // optional AxiosRequestConfig
);
return findPetsResponse.data;
}
}