tsedio / tsed

:triangular_ruler: Ts.ED is a Node.js and TypeScript framework on top of Express to write your application with TypeScript (or ES6). It provides a lot of decorators and guideline to make your code more readable and less error-prone. ⭐️ Star to support our work!
https://tsed.io/
MIT License
2.85k stars 285 forks source link

Add support for model serialization in Socket service #2396

Open derevnjuk opened 1 year ago

derevnjuk commented 1 year ago

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.

Romakita commented 1 year ago

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 commented 1 year ago

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

derevnjuk commented 6 months ago

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

Romakita commented 6 months ago

@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 :)