-
Notifications
You must be signed in to change notification settings - Fork 459
Description
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"}
methodfield contains information about API method that request is calling.paramsfield 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 fieldmethodand then decodeparamsas 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!