Skip to content

Direct JSON RPC support #621

@FunFunFine

Description

@FunFunFine

Hello!
In my organization we are using tapir and it feels like a very good tool.

Nevertheless we are also heavily using JSON RPC protocol and tapir doesn't help us at all.

Here is the example:

  • JRPC always uses HTTP POST requests with same top level json body, e.g.
{"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"}
  • method field contains information about API method that request is calling.
  • params field contains actual data needed for the method of API, it can have any structure: list, object, raw value etc.
    As for now we are using Http4s for it and we have to do dynamic dispatch on field method and then decode params as desired object:
case class JRPCRequest[A](id: String,
                      jsonrpc: String,
                      method: String,
                      params: A)

 def handleReq(req: Request[F]): F[Response[F]] = getMethodFromRequest(req) match {
case "foo" => req.as[JRPCRequest[Foo]] >>= (...) some foo handler
case "bar" => req.as[JRPCRequest[Bar]] >>= (...) some bar handler
case _ => ... //bad request here
}

where getMethodFromRequest gets method field from JSON.
All this boilerplate code doesn't look very good and is a pain to support, and I'm not even talking about documentation like swagger etc.

I've tried using tapir somehow by creating two endpoints:

  val jrpcList = endpoint.post.in(jsonBody[JRPCRequest[List[Int]]]).out(stringBody)

  val jrpcInt = endpoint.post.in(jsonBody[JRPCRequest[Int]]).out(stringBody)
def routes[F[_]: Sync: ContextShift]: HttpRoutes[F] = jrpcInt.toRoutes(_ =>
      "Int".asRight[Unit].pure[F]) <+> jrpcList.toRoutes(_ => "List".asRight[Unit].pure[F])

But this didn't work, only Int endpoint have been working while the other's response was "Error: Bad Request"

So is there any possibility to add JSON RPC support directly into tapir?
I would like to implement it but I need some advices on where to start or what are the best options.

Anyway thank you guys for the great library!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions