Is it possible to alter RPC context data through an interceptor?

Is it possible to adjust the request payload in an RPC-based context, as opposed to HTTP-based contexts like this method? This question arises within the context of modifying a message payload received from Kafka in NestJS microservices setup where messages are encoded using Avro.

// code snippet depicting message decoding
const rpcContext = context.switchToRpc().getContext();
const kafkaMessageBuffer: Buffer = context.switchToRpc().getData();
const decodedMessage = await this.schemaRegistry.decode(kafkaMessageBuffer);

// Attempting to replace the buffer value with the decoded data
rpcContext.args[0]['value'] = decodedMessage;

The above approach encounters obstacles due to the fact that args is protected and cannot be modified.

Are there alternative methods to globally decode all Kafka messages?

Possible alternatives include:

  • Developing a custom pipe to transform data in the controller:
    • @Payload(AvroTransformPipe) message: CustomerMessage
  • Manual decoding of messages in the controller before forwarding them to services

Answer №1

I encountered a similar issue and found a workaround in the global interceptor by dynamically executing the method without utilizing next.handle():

const rpcHost: RpcArgumentsHost = context.switchToRpc();
const dataWrapper = rpcHost.getData();
const user = dataWrapper.user;
const data = dataWrapper.data;

const instance = app.get(context.getClass());

const resultPromise: Promise<any> =
  instance[context.getHandler().name](data);

return from(resultPromise);

Answer №2

After some consideration, I decided to implement a Global Pipe.

transform(value: any, metadata: ArgumentMetadata): any {
  if (metadata.type !== 'body') {
    return value;
  }

  return value instanceof Buffer ? this.schemaRegistry.decode(value) : null;
}

While this approach is functional, it has its limitations. It will impact every decorator due to the metadata.type check, and targeting a specific decorator like @Payload() can be challenging. Additionally, in a Hybrid application with HTTP endpoints, this solution may present some challenges.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Exploring the functionality of generic components in React Native when using TypeScript

As an illustration, consider export class FlatList<ItemT> extends React.Component<FlatListProps<ItemT>> which incorporates the generic type ItemT. How can I utilize it in a .tsx code? When not parametrized, it appears like this: <Flat ...

The specified JSX element type (whether it be from react-konva or not) does not contain any defined constructors or callable signatures

I recently switched over to TypeScript in React and started using Konva library. When I updated my "@types/react" package from version "^17.0.39" to "^18.0.1", I encountered an error message that appears on every Konva component. ...

What is the process for defining functions with distinct data types while allowing variables to have multiple data types?

I am facing a declaration issue - or rather, a challenge in comprehending Typescript. Let me illustrate the scenario: public migrationSource: Skater | Rink; public migrationDestination: Skater | Rink; public migrationMode: MigrationMode; ngOnInit() { ...

Sinon - observing a spy that remains inactive, yet the test proceeds to enter the function

Having some trouble with a test function that uses two stubs. The stubs seem to be working fine, as I can see the spy objects inside when I console.log res.json or next. However, the spy is not being called when I make the assertion. The error message read ...

Safari browser failing to render Angular2 ngFor content

I am facing an issue with my ngFor loop where only the first element's data is loaded upon page refresh. However, when I click on an empty element, the data suddenly appears. This unusual behavior seems to be specific to viewing in Safari browser. How ...

The "ng2-CKEditor" package is experiencing compatibility issues with TypeScript in Angular 2

Currently, I am in the process of setting up CKEditor in my angular2 application. My backend platform is node.js and for this purpose, I am utilizing the ng2-CKEditor npm module. Below, you can find snippets from respective files. index.html:: <html& ...

Creating a function that can have either one or two arguments, with the types of the arguments determined by a specific string literal

I am looking to create a function called emitEvent(event, extra?), which will be restricted by a string literal enum of known strings such as POPUP_OPEN and POPUP_CLOSED. The function will accept a second argument that is a specifically defined dictionary ...

Move forward state using navigateByUrl in Angular

I am looking to send data when changing the view using navigateByUrl like this: this.router.navigateByUrl(url, {state: {hello: "world"}}); Once in the next view, my goal is to simply log the hello attribute like so: constructor(public router: Router) { ...

How can one implement closure in Angular 4?

I am looking to implement a nested function within another function in Angular 4 for closure. However, when attempting the code below, I encounter an error stating "cannot find name innerFn" outerFn(){ let a = "hello"; innerFn(){ console.log(a ...

Optional parameter left unassigned is not automatically determined as undefined

Why is TypeScript not inferring the optional parameter in this function as undefined when it's omitted from the call? function fooFunc<T extends number | undefined>(param?: T){ let x: T extends undefined ? null : T x = param ?? null as any ...

What is the alternative method for converting an API stream into a .csv file without relying on FileSaver or createObjectURL()?

These are the only two methods currently available. An issue with createObjectURL() is that it is deprecated and cannot be called in Chrome anymore. Using FileSaver may feel like adding unnecessary complexity to your project when it should be a simple ta ...

"Users have reported that the file upload preview feature in Angular 6 only works after the

I am currently utilizing Angular 6. In my application, I have a simple input type="file" field that passes data to an image source which displays the image I intend to upload. The issue I am facing is that when I select an image for the first time, nothi ...

Enhancing ES6 capabilities with Angular polyfills

While exploring the Angular documentation and various online resources about Angular, I came across a question. If all code is written in Typescript, why would we need ES6 polyfills? My understanding is that webpack eventually transpiles the code to ES5, s ...

Adding an asterisk to mark a required field in Angular reactive form inputs is a simple task that can be accomplished with just a

Currently, I am in the process of developing an application that utilizes a reactive dynamic angular form. The fields for this form are retrieved from an API request and generated dynamically. I have encountered the need to include a 'required field& ...

State hook variable not being properly updated within a functional component

After updating the name of an ingredient, I am looking to save this data as an ingredient with the new name: from "Milk" to "Cow's milk". I've included simple steps (1,2,3) in comments to outline the process briefly, but for clarification, assum ...

Setting Angular FormControl value to null within a service

My Angular form is reactive and collects mobile numbers along with other details. Here is the code snippet: component.html <form [formGroup]="contactDetailsForm"> <ngx-intl-tel-input [cssClass]="'ngxIntlInputBorder'&quo ...

Incorporating a sidemenu into a DOM using Ionic2 and Angular2 Typescript

I am currently struggling to properly integrate the sidemenu from the app.ts file. app.html: <ion-menu [content]="content"></ion-menu> <ion-nav id="nav" [root]="rootPage" #content ></ion-nav> app.ts import {App, IonicApp,Page, ...

What is the best way to selectively remove and then later reinsert two items from an array in

I am facing a scenario where I have two buttons and an array to work with. The buttons are labeled "OR" and "AND", and the array consists of 7 items in a Dropdown list. When the user clicks on the "OR" button, it should remove 2 items from the array. Co ...

The current version of Firebase functions is not reflecting the most recent modifications when running "firebase serve"

Exploring firebase functions has been a fun journey for me. Everything works smoothly when I deploy to the firebase server using the command firebase deploy --only functions. However, I wanted to test my functions locally before deploying them, and encount ...

Excessive memory usage by Kafka consumer

Recently, I've come to realize that Kafka consumers can be very memory-intensive. During my tests, I set up a single-threaded consumer locally listening to a topic with 4 partitions. The Kafka setup consists of just one broker. I only sent 10 small ...