HaNdTriX / next-rpc-experiment

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Next RPC Experiment

This repository tries to explore new patterns and ways to solve the Server Client typing.

The goals of this project is to create a tiny RPC lib that focuses on

  • zero configuration (no codegen, no buildsystem patches)
  • serverless support (build time code splitting)
  • edge runtime support
  • type inference server-client
  • runtime type checking where it makes sence
  • cacheability (queries only)

Strategy

Define your queries & mutations inside multiple serverless edge functions.

Server

File: api/posts.ts

import { z } from "zod";
import createRPCHandler from "../../lib/create-rpc-handler";

export const config = {
  runtime: "experimental-edge",
};

const rpcHandler = createRPCHandler()
  .query("myMethodName", {
    input: z.object({
      id: z.string(),
    }),
    resolve({ id }) {
      return { id, title: "Building a next rpc client" };
    },
  })
  .mutation("delete", {
    input: z.object({
      id: z.string(),
    }),
    resolve({ id }) {
      return {
        id,
        removed: true,
      };
    },
  })

export default rpcHandler.handle()

// Future:
// Infer the type of the RPCClient from the RPC handler.
// Please note that this api is a WIP and not yet fully specified
declare global {
  export type RPCClient = rpcHandler.infer<'posts'>
}

Client

This experiment also exposes a tiny dump RPCClient that soly depends on the inferred typescript type from the serverless edge functions. It is based on a recursive proxy pattern and has no runtime information of the different api functions.

This api client configures itself by usage:

Syntax:

api.<pathSegment*n>.<rpcMethodName>.$query(Input, ReqInit): Promise<ReturnType>
api.<pathSegment*n>.<rpcMethodName>.$mutate(Input, ReqInit): Promise<ReturnType>

Usage:

const { id, title } = await api.posts.myMethodName.$query({
  id: "42",
});

When using this client, typescript will inform the developer what is possible and what not. This information should be inferred from the RPCHandler.

Install

$ yarn

Development

yarn run dev

Production

yarn run build && yarn run start

Todo

  • create rpc-handler internal inferred runtime checks
  • create rpc-client
  • infer RPCClient from createRPCHandler
  • expose react-query hooks
  • create req context configurator (webmiddleware pattern)
  • create benchmarks

About


Languages

Language:TypeScript 98.4%Language:JavaScript 1.6%