BFF-WS-EXT
General
This extension provides ability to consume messages from BE via WebSockets. On server connection provided over RabbitMQ in future probably another MQ will be added.
Backend part
Installation
$ npm install @invent/bff-ws-ext
Configuration
On first place you have to describe configuration params.
import { ExtInitConfig } from '@invent/bff-ws-ext';
export const bffWsExt: ExtInitConfig = {
messages: [],
extHost: `${process.env.MY_HOST}:443`,
qOptions: {
qName: 'my-tenant-prefix',
qHost: process.env.RMQ_HOST
}
};
type ExtInitConfig = {
pathOverride?: {
root: string;
schema: string;
channel: string;
};
messages: SchemaMessagesT<unknown>[];
qOptions: QOptionsT;
};
Path override
- this is optional config key
- this key provides ability to override endpoints for this extension
pathOverride?: {
root: string;
schema: string;
channel: string;
};
Default values are:
/ext/ws/schema
/ext/ws/channel
QOptions
- for now implemented support only for
rabbitMq - this is mandatory config key
- if port not setted up default
rabbitmqport will be used
type QOptionsT = {
qName: string;
qPort?: number;
qHost: string;
}
Example:
{
qName: 'wlabel',
qPort: '101107',
qHost: 'amqp://0.0.0.0'
}
Messages
TO BE IMPLEMENTED
Connection mapping
- all connections of user will be binded to user ID provided in
JWT(thesubclaim). - messages from
rabbitMqwill be sent to all user connections in all browser tabs.
Init & expose
import { bffWsExt } from './src/extentions/ws-extention';
import { initBffWsExt } from '@invent/bff-ws-ext';
....
app.use(
validateRequestTokenMiddlewareFabric([
'/images',
'/templates/assets/fonts',
'/theme',
'/theme/my-default-theme',
'/tenent',
'/ext/ws/channel/.websocket'
])
);
overrideRoutes();
let extentions = [];
extensions = await initBffWsExt(app, bffWsExt, extentions);
exposeExtensions(extentions);
endpointConfig.forEach((domain) => hydrate(app, domain));
Exposed extensions in this example
[
{
"author":"Nameless invent developer",
"name":"@invent/bff-ws-ext",
"version":"1.0.12",
"module":"./BffWssCompanion",
"scope":"companion_bff_ws_ext",
"extHost":"https://fe-be.dev.clic.apptrium.cloud:443",
"companion":"https://inventwidgetextensions.z19.web.core.windows.net/271/remoteEntry.js",
"pathList":[
{
"method":"get",
"path":"/ext/ws/schema"
},
{
"method":"ws",
"path":"/ext/ws/channel"
}
]
}
]
- The order of function calls is important
extensionsis list of mounted extenstions. In case you use more then one installed extension, pass this var to anotheriniAnotherExtfunction.- The part
/ext/ws/channel/.websocketexposes connection. Also please keep in mind that.websocketis mandatory. exposeExtnsionsused to expose list of installed extensions. If you want to add customization or override some params, you can do it onextenstionsbefore pass toexposeExtensionsfunction.
Companion
Subscribe
In place where you whan to subscribe on WebSocket.
// In case you are in host application area
import { getExtension, getExtensionsList } from '@/lib/module-federation/use-extensions';
// In case you are accessing websocket extension in widget
const { getExtension, getExtensionsList } = props;
// mySubscriptionId should be placed outside the component
const mySubscriptionId = v4();
useEffect(() => {
const wss = getExtension('@invent/bff-ws-ext');
if (wss && wss.subscribe) {
// (entity: string, id: string, callback: (message: unknown) => void) => void
wss.subscribe('Notification', mySubscriptionId, (message: unknown) => console.log(message));
/*
`entity` refers to `headers.entity` in websocket message.
So you subscribing to specific entity events.
`id` is unique string id.
`callback` is handler function.
*/
}
}, [getExtension('@invent/bff-ws-ext')]);
- you can wrap handler with
React-Queryor another wrapper.
Unsubscribe
import { getExtencion } from '@/lib/module-federation/use-extensions';
import { useUnmount } from 'react-use';
useUnmount(() => {
const wss = getExtencion('@invent/bff-ws-ext');
if (wss) {
// mySubscriptionId same value as in subscribe
wss.unsubscribe('Notification', mySubscriptionId);
}
});
Common websocket messages shape
{
"message": {
"downloadId":"cbe1894e44984b74b9f829f8ddeb9c50",
"userId":"00000",
"type":1,
"name":"contacts-grid_08-21-2021_19-23",
"uri":"https://clicqacudata.blob.core.windows.net/files/downloads/cbe1894e44984b74b9f829f8ddeb9c50?sv=2020-08-04&se=2021-09-21T13%3A23%3A19Z&sr=b&sp=r&rscd=attachment%3B+filename%3Dcontacts-grid_08-21-2021_19-23&sig=2tNFPCOMJR1rkyGgBLuP5MIlV4IetsC6afMjSXUuBb0%3D",
"status":2,
"expiresAt":"2021-09-21T13:23:16.516Z",
"createdAt":"2021-09-21T12:23:19.0470019Z",
"scope":3
},
"headers": {
"x-datadog-trace-id":"7247253089438860160",
"x-datadog-parent-id":"7380314150188049681",
"x-datadog-sampling-priority":"1",
"CausationId":"541750d3-1c93-4656-a40b-237c8c3da2c0",
"CausedBy":"DCore.FinTech.Messages.Downloads.Commands+V1+SetDownloadAvailable",
"CorrelationId":"25df0318-ab3a-5087-b345-681753ee5ed5",
"TenantId":"CIR",
"entity":"Download",
"recipientId":"00000",
"deliveryMethod":"Direct"
}
}