This snippet implements an RPC server and client using effect
:
effect
: Core library@effect/rpc
: RPC library@effect/platform
: HTTP client requests (web handler)
The implementation starts from api.ts
. Inside it, we define all the requests supported by the RPC server. Each request is defined from a RpcGroup
using Rpc.make
:
error
success
payload
RpcGroup
represents the requests definition, shared between server and client.
export class RpcAuth extends RpcGroup.make(
Rpc.make("SignUpRequest", {
error: RequestError,
success: Schema.Boolean,
payload: {
email: Schema.NonEmptyString,
password: Schema.String,
},
})
) {}
Server
server.ts
defines the implementation of each request using toLayer
:
const RpcAuthLayer = RpcAuth.toLayer({
SignUpRequest: (params) =>
Effect.gen(function* () {
yield* Effect.log(params.email, params.password);
return true;
}),
});
We then convert RpcAuth
to a web handler that accepts the standard web Request
/Response
model:
export const RpcWebHandler = RpcServer.toHttpApp(RpcAuth).pipe(
Effect.map(HttpApp.toWebHandler),
);
route.ts
shows an example of using the web handler for anext
API route (passingRequest
and returning aResponse
).
Client
On the client you use RpcClient.make
to derive a type-safe HTTP client that sends requests to the server API.
The client is fully type-safe since it's derived from the shared
RpcAuth
, with both success, error and payload types extracted fromRpc.make
.
The configuration for the HTTP request is defined as RpcClient.Protocol
(url
, HttpClient
, RpcSerialization
), which is provided as a Layer
to RpcAuthClient
.