RPC generator for @wtheff
npm install @wtheff/rpcA TypeScript library for generating type-safe Remote Procedure Calls (RPCs) with built-in schema validation using Suretype or TypeBox.
- Create type-safe query and mutation RPCs
- Built-in schema validation using Suretype/TypeBox
- Runtime validation of arguments
- Generated JSON-Schema for RPCs
``bash`
npm install @wtheff/rpc
`typescript
import { RPCGenerator } from '@wtheff/rpc';
import { v } from 'suretype';
const { RegisterRPC } = RPCGenerator();
// Register a query RPC
const { getUserInfo } = RegisterRPC.query(
'getUserInfo',
{
schema: {
args: v.object({ userId: v.string().required() }),
data: v.object({
name: v.string().required(),
email: v.string()
})
}
},
async (ctx, args) => {
// Handle the RPC call
return {
name: 'John Doe',
email: 'john@example.com'
};
}
);
// Call the RPC
const userInfo = await getUserInfo({ userId: '123' });
`
`typescript
interface CustomContext {
authToken: string;
}
const { RegisterRPC } = RPCGenerator
// RPC handler registration callback
onRegisterRPC: ({ handler, name }) => {
httpRouter.post(/rpc/${name}, async (req) => {
return handler({ authToken: req.headers.authorization }, req.body);
});
}
});
const { CheckIsAuthenticated } = RegisterRPC.query(
'CheckIsAuthenticated',
{
context: async (ctx) => {
if (validateAuthToken(ctx.authToken)) {
const user = await getUserFromToken(ctx.authToken);
return { user }
}
throw new RPCError('Invalid auth token');
},
schema: {
data: v.string(),
}
},
async (ctx, args) => {
// Access context in handler with type-safety
console.log(ctx.user);
return 'User authentication is valid';
}
);
// Call the RPC
CheckIsAuthenticated({authToken:'valid-token'}, {}); // Returns 'User authentication is valid'
CheckIsAuthenticated({authToken:'no-token'}, {}); // Throws 'RPCContextError: Invalid auth token'
`
`typescript
const { RegisterRPC, getRegisteredRPCs } = RPCGenerator();
// Later in your code
const registeredProcedures = getRegisteredRPCs();
const userInfoProcedure = registeredProcedures.get('getUserInfo');
`
`typescript
const { RegisterRPC, getRegisteredRPCs } = RPCGenerator();
const { getUserInfo, getUserInfoSchema } = RegisterRPC.query(
'getUserInfo',
{
schema: {
args: v.object({ userId: v.string().required() }),
data: v.object({
name: v.string().required(),
email: v.string()
})
}
},
async (ctx, args) => {
// Handle the RPC call
return {
name: 'John Doe',
email: ''
};
}
);
console.log(getUserInfoSchema); // { args: JSON-schema; data: JSON-schema }
// or
console.log(getRegisteredRPCs().get('getUserInfo').config.schema); // { args: JSON-schema; data: JSON-schema }
`
Creates a new RPC generator instance.
#### Options
- onRegisterRPC: Callback function called when a new RPC is registeredhandler
- : The RPC handler functionconfig
- : Configuration object containing schema and local RPC context handlername
- : Name of the RPC procedure
Object containing methods to register new RPCs.
#### Methods
- query(name, options, handler): Register a query RPCmutation(name, options, handler)
- : Register a mutation RPC
> Note: query and mutation methods are identical, except for the type of RPC registered.
> These RPC "type"'s are used in client implementation to differentiate between query and mutation RPCs.
> This helps clients support caching calls appropriately if using a cache layer. For example, you can cache
> query RPCs but should not cache mutation RPCs.
#### Options
- schema: args
- : Suretype/TypeBox validation schema for argumentsdata
- : Suretype/TypeBox validation schema for return datacontext
- : Function that returns additional context local to the RPC call
The library includes built-in validation error handling through the RPCValidationError class.
If the RPC config.args schema exists, the args are validated before the RPC handler is called. RPCValidationError
If the validation fails, an is thrown with the validation error message.
- @sinclair/typebox - For providing a great library for generating JSON schema with TypeScript.@suretype/suretype
- - For providing a great library for runtime type validation.@typeschema` - For providing inspiration for the RPC schema resolver between Suretype or TypeBox.
-
MIT
Contributions are welcome! Please feel free to submit a Pull Request.