AsyncAPI offers many ways to reuse certain parts of the document like messages or schemas definitions or references to external files, not to even mention the traits. Purpose of AsyncAPI Optimizer is to enable different ways to optimize AsyncAPI files. It is a library that can be used in UIs and CLIs.
- Clone the project
git https://github.com/asyncapi/optimizer.git
- Install the dependencies
npm i
- for a quick check you can run
npm run example
. You can openexamples/index.js
modify it or add your own AsyncAPI document for optimization.
import { Optimizer } from '@asyncapi/optimizer';
import type { Report } from '@asyncapi/optimizer';
const yaml =`
asyncapi: 2.0.0
info:
title: Streetlights API
version: '1.0.0'
channels:
smartylighting/event/{streetlightId}/lighting/measured:
parameters:
#this parameter is duplicated. it can be moved to components and ref-ed from here.
streetlightId:
schema:
type: string
subscribe:
operationId: receiveLightMeasurement
traits:
- bindings:
kafka:
clientId: my-app-id
message:
name: lightMeasured
title: Light measured
contentType: application/json
traits:
- headers:
type: object
properties:
my-app-header:
type: integer
minimum: 0
maximum: 100
payload:
type: object
properties:
lumens:
type: integer
minimum: 0
#full form is used, we can ref it to: #/components/schemas/sentAt
sentAt:
type: string
format: date-time
smartylighting/action/{streetlightId}/turn/on:
parameters:
streetlightId:
schema:
type: string
publish:
operationId: turnOn
traits:
- bindings:
kafka:
clientId: my-app-id
message:
name: turnOnOff
title: Turn on/off
traits:
- headers:
type: object
properties:
my-app-header:
type: integer
minimum: 0
maximum: 100
payload:
type: object
properties:
sentAt:
$ref: "#/components/schemas/sentAt"
components:
messages:
#libarary should be able to find and delete this message, because it is not used anywhere.
unusedMessage:
name: unusedMessage
title: This message is not used in any channel.
schemas:
#this schema is ref-ed in one channel and used full form in another. library should be able to identify and ref the second channel as well.
sentAt:
type: string
format: date-time`;
const optimizer = new Optimizer(yaml);
const report: Report = await optimizer.getReport();
/*
the report value will be:
{
reuseComponents: [
{
path: 'channels.smartylighting/event/{streetlightId}/lighting/measured.message.payload.properties.sentAt',
action: 'reuse',
target: 'components.schemas.sentAt'
}
],
removeComponents: [
{
path: 'components.messages.unusedMessage',
action: 'remove',
}
],
moveToComponents: [
{
//move will ref the current path to the moved component as well.
path: 'channels.smartylighting/event/{streetlightId}/lighting/measured.parameters.streetlightId',
action: 'move',
target: 'components.parameters.streetlightId'
},
{
path: 'channels.smartylighting/action/{streetlightId}/turn/on.parameters.streetlightId',
action: 'reuse',
target: 'components.parameters.streetlightId'
}
]
}
*/
const optimizedDocument = optimizer.getOptimizedDocument({
rules: {
reuseComponents: true,
removeComponents: true,
moveToComponents: true
}
});
/*
the optimizedDocument value will be:
asyncapi: 2.0.0
info:
title: Streetlights API
version: 1.0.0
channels:
"smartylighting/event/{streetlightId}/lighting/measured":
parameters:
streetlightId:
$ref: "#/components/parameters/parameter-1"
subscribe:
operationId: receiveLightMeasurement
traits:
- bindings:
kafka:
clientId: my-app-id
message:
name: lightMeasured
title: Light measured
contentType: application/json
traits:
- headers:
$ref: "#/components/schemas/schema-1"
payload:
type: object
properties:
lumens:
type: integer
minimum: 0
sentAt:
$ref: "#/components/schemas/sentAt"
"smartylighting/action/{streetlightId}/turn/on":
parameters:
streetlightId:
$ref: "#/components/parameters/parameter-1"
publish:
operationId: turnOn
traits:
- bindings:
kafka:
clientId: my-app-id
message:
name: turnOnOff
title: Turn on/off
traits:
- headers:
$ref: "#/components/schemas/schema-1"
payload:
type: object
properties:
sentAt:
$ref: "#/components/schemas/sentAt"
components:
schemas:
sentAt:
type: string
format: date-time
schema-1:
type: object
properties:
my-app-header:
type: integer
minimum: 0
maximum: 100
parameters:
parameter-1:
schema:
type: string`
*/
For using the optimizer to optimize file you just need to import the Optimizer
class. Use its two methods to get the report (getReport()
) and get the optimized document (getOptimizedDocument()
).
See API documentation for more example and full API reference information.