Looking for critique for my ReScript codebase

I have this simple chat app code base written in ReScript. I’m looking forward for any critiques, recommendations, advice.

btw I came from the JS/TS world so my coding style might not fit the OCaml community much.

2 Likes

ReScript is closer to JS community than the OCaml one. So don’t worry about it.

2 Likes

I’ve taken a look at the code. I like it, great job :ok_hand:

1 Like

Thank you. I am still grokking over the serialization and deserialization code. I probably gonna use rescript-struct in the future but for now I am doing it bare bones.

That’s great to hear!

A while ago, I’ve written a web server using fastify. It might give you some inspiration. Here’s the abstraction over fastify, which uses rescript-struct for data validation and transformation. Also, it’s used to generate JSON schema for open api and faster serializing:

let make = (~connectToGameUseCase: InPorts.ConnectToGameUseCase.t) => {
  ApiModule.Route.make(
    ~summary="Connect provided User to the Game",
    ~method=#POST,
    ~url="/v1/games/:gameId/connections",
    ~withAuth=true,
    ~handler=request => {
      let params = request->ApiModule.Request.extractParams
      let body = request->ApiModule.Request.extractBody
      let authDetailsDto = request->ApiModule.Request.extractAuthDetailsDto

      connectToGameUseCase(
        ~authDetailsDto,
        ~gameId=params["gameId"],
        ~deviceId=body["deviceId"],
        ~userId=body["userId"],
      )->Promise.thenResolve(connectToGameResult => {
        switch connectToGameResult {
        | Ok() => ApiModule.Response.NoContent
        | Error(Unauthorized) => ApiModule.Response.Unauthorized
        | Error(UserAlreadyConnected(message))
        | Error(DeviceAlreadyConnected(message))
        | Error(GameNotFound(message)) =>
          ApiModule.Response.BadRequest(message)
        | Error(Forbidden) => ApiModule.Response.Forbidden
        | Error(Failed) => ApiModule.Response.InternalServerError
        }
      })
    },
    ~paramsStruct=S.object(o =>
      {
        "gameId": o->S.field(
          "gameId",
          ApiModule_InputStruct.Game.id->JsonSchema.description(
            "The Id of the Game to connect User",
          ),
        ),
      }
    ),
    ~bodyStruct=S.object(s =>
      {
        "userId": s.field(
          "userId",
          ApiModule_InputStruct.User.id->JsonSchema.description("The provided User Id"),
        ),
        "deviceId": s.field(
          "deviceId",
          ApiModule_InputStruct.Device.id->JsonSchema.description(
            "The Id of Device that provided User using in the Game",
          ),
        ),
      }
    ),
    (),
  )
}
2 Likes

Also, I’ve started developing https://ts-rest.com/ alternative for ReScript. But it’ll most likely come out next year.

2 Likes

Nice monorepo. Have you tried a setup with a single compiler running for all packages, maybe even with rewatch?

Looks neat! Thank you

I haven’t tried it! I will try this.

That’s very cool. I wonder if we can start developing a fullstack boilerplate a.l.a NextJS for ReScript leveraging your project.