tsed icon indicating copy to clipboard operation
tsed copied to clipboard

Add support for model serialization in Socket service

Open derevnjuk opened this issue 1 year ago • 4 comments

Information

The Socket service supports real-time communication using decorators like @Input, @Emit, and @Args. These decorators are used to define the structure and flow of data during communication with the WebSocket. However, there is a limitation when it comes to handling model serialization, specifically when using the @Emit decorator.

Developers will no longer need to manually handle the serialization of complex data models when using the @Emit decorator. The proposed feature will handle the serialization process based on the provided serialization

Example

We propose adding support for model serialization using the @Emit decorator or by inferring the return type of the method decorated by it.

Using @Emit with explicitly supplied type:

@SocketService("/nsp")
export class MyWS {

  @Input("event")
  @Emit("returnEvent", PersonModel) // The second parameter specifies the class to be used for serialization.
  async myMethod(): Promise<PersonModel> {
    return { firstName: 'Bob', lastName: 'Diamond' };
  }
}

Using @Emit with Automatic Inference of Return Type:

@SocketService("/nsp")
export class MyWS {

  @Input("event")
  @Emit("returnEvent") // The return type of the method will be used to automatically infer the serialization class (PersonModel in this case).
  async myMethod(): Promise<PersonModel> {
    return { firstName: 'Bob', lastName: 'Diamond' };
  }
}

This approach should ensure consistency with the @Args decorator, which already allows developers to specify input data structures.

derevnjuk avatar Jul 26 '23 13:07 derevnjuk

Hello @derevnjuk Inference won't works. When the return type is Promise<Model> typescript will store Object and not Model.

This is why there is @Returns() decorator.

The best solution his to make the @tsed/schema able to describe websocket/socketio methods (and generate the asyncapi doc also).

But it's a big reworks.

A quick win cool be to have an decorator interface like the Returns decorator.

@Emit("messageName", Model)
@Emit("messageName", Array).Of(Model)

You can look the returns.ts file for implementation example ;)

See you

Romakita avatar Jul 26 '23 18:07 Romakita

@derevnjuk the #2453 will cover that :) The @tsed/socketio will be deprecated

Romakita avatar Sep 28 '23 07:09 Romakita

@Romakita why don't implement this in the existing version of the package? I can implement this if you don't mind. wdyt?

derevnjuk avatar Apr 25 '24 14:04 derevnjuk

@derevnjuk I wanted to completely re-use the package code to reuse the @tsed/schema package as much as possible but I didn't have the time. so it's no longer really relevant.

All of stuff described above probably require a huge refactoring of the @tsed/socketio package while is it most simple to create a new package (but maybe I'm wrong now). The problem with this version, is that it doesn't use the @tsed/schema API. It uses its own metadata as you can see. I would have liked to start by migrating the custom metadata to use the JsonEntityStore (@tsed/schema).

If you are motivated to implement these feature, let's Go :)

Romakita avatar Apr 25 '24 16:04 Romakita