Skip to content

Commit 51bdd49

Browse files
authored
@webrpc/react-query npm package (#1)
1 parent a734db1 commit 51bdd49

32 files changed

+6340
-1040
lines changed

.eslintrc

-56
This file was deleted.

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
node_modules
2+
dist

.nvmrc

-1
This file was deleted.

LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2022 golang.cz
3+
Copyright (c) 2022 golang.cz and github.com/webrpc authors
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

+60-11
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,79 @@
1-
# webRPC react-query client
1+
@webrpc/react-query -- a react-query adapter for webrpc
2+
=======================================================
3+
4+
Enjoy the RPC code-gen ergonomics + type-safety benefits of webrpc, with the comfort
5+
of react-query from your React apps :)
6+
7+
8+
## Install
9+
10+
From your webapps: `npm install @webrpc/react-query`
11+
12+
As well, make sure you install `@tanstack/react-query` and `react` in your app, which are
13+
peer-dependencies of this library.
14+
15+
16+
## Example
17+
18+
Please see a full example project with both server and client [here](./example).
19+
20+
To run the example:
21+
22+
1. git clone this repo
23+
2. `cd example/webapp`
24+
3. `pnpm install`
25+
4. Start the server -- in one terminal: `make run-server`
26+
5. Start the webapp -- in another terminal: `make run-webapp`
27+
6. Open the webapp at http://localhost:4444 and open your browser console
28+
229

3-
Server synchronization made easy & type-safe!
430
## How to use
531

6-
First, you'll need an api contract, ideally in the webRPC format.
7-
Then create an instance of your contract and pass it as an argument to the WebRPCClient constructor.
32+
First, you'll need a webrpc schema definition either in JSON or RIDL.
33+
34+
Then create an instance of your RPC client and pass it as an argument to the WebRpcClient constructor.
835
It should look something like this:
936

1037
```ts
11-
const ContractInstance = new Chat('hostname', customFetch)
12-
export const client = new WebRpcClient(ContractInstance)
38+
import { Example } from './client.gen'
39+
import { WebRpcQueryClient } from '@webrpc/react-query'
40+
41+
const rpc = new Example('http://localhost:4242', fetch)
42+
const client = new WebRpcQueryClient(rpc)
1343
```
1444

1545
Import `client` where you need to make your API calls and let type inference guide your way!
1646

47+
1748
## Differentiating queries and mutations
1849

1950
If you want to make the distinction between a query and a mutation even clearer, you can define custom _query prefixes_.
2051
You do so by adding a generic type to your `WebRpcClient` instance.
2152

2253
```ts
23-
const ContractInstance = new Chat('hostname', fetch)
24-
const client = new WebRpcClient<typeof ContractInstance, ['get', 'list']>(
25-
ContractInstance,
26-
)
54+
import { Example } from './client.gen'
55+
import { WebRpcQueryClient } from '@webrpc/react-query
56+
57+
const rpc = new Example('http://localhost:4242', fetch)
58+
const client = new WebRpcQueryClient<typeof rpc, ['get', 'list']>(rpc)
2759
```
2860

2961
With this configuration, you can only use `client.useQuery` hook with paths that start with either `'get'` or `'list'`.
30-
Any other method from your contract will be considered a _mutation_. If you choose not to provide _query prefixes_, you will be able to call both `client.useQuery` and `client.useMutation` with any path from your contract.
62+
63+
Any other method from your contract will be considered a _mutation_. If you choose not to provide _query prefixes_, you will be able to call both `client.useQuery` and `client.useMutation` with any path from your contract.
64+
65+
66+
## Local dev
67+
68+
You can update `example/webapp/package.json" package to `"@webrpc/react-query": "workspace:../../"`
69+
which will use the build from the local repo.
70+
71+
72+
## Credits
73+
74+
Thank you to @vojoup from the github.com/golang-cz team for the idea and original implementation of this library :)
75+
76+
77+
## LICENSE
78+
79+
Licensed under [MIT License](./LICENSE)

example/Makefile

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
all:
2+
@echo "please read Makefile source or README to see available commands"
3+
4+
generate: generate-server generate-client
5+
6+
generate-server:
7+
webrpc-gen -schema=example.ridl -target=go -pkg=main -server -out=./server/example.gen.go
8+
9+
generate-client:
10+
webrpc-gen -schema=example.ridl -target=ts -client -out=./webapp/src/client.gen.ts
11+
12+
bootstrap:
13+
rm -rf webapp/node_modules
14+
cd webapp && pnpm i
15+
16+
run-server:
17+
@go run ./server
18+
19+
run-client:
20+
@cd webapp && pnpm start

example/README.md

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
webrpc react-query example
2+
==========================
3+
4+
* Server: Go
5+
* Client: Web Browser (Typescript)
6+
7+
Simple client+server app with Go api backend (server) and Typescript Webapp (client).
8+
9+
1. `$ make bootstrap` - installs node modules for the webapp (client)
10+
2. `$ make run-server` - to start the Go server at http://localhost:4242/
11+
3. `$ make run-client` - build+start webapp via webpack dev server at http://localhost:4444/
12+
4. Open your browser to https://localhost:4444/ and open your console, and see rpc calls, tada
13+
14+
webrpc comes with its own schema design language called RIDL, which stands for "RPC interface
15+
design language" :) it reads and feels like documentation, but it very flexible. See
16+
[hello-api.ridl](./hello-api.ridl) for the RIDL file for this service.
17+
18+
as well, webrpc supports a json-formatted schema with the identical functionality as the RIDL format.
19+
See here, [hello-api.webrpc.json](./hello-api.webrpc.json).

example/example.ridl

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
webrpc = v1
2+
3+
name = example
4+
version = v1.0.0
5+
6+
7+
enum Kind: uint32
8+
- USER = 1
9+
- ADMIN = 2
10+
11+
12+
message User
13+
- ID: uint64
14+
+ json = id
15+
+ go.tag.db = id
16+
17+
- username: string
18+
+ json = USERNAME
19+
+ go.tag.db = username
20+
21+
- role: Kind
22+
23+
- meta: map<string,any>
24+
25+
- internalID: uint64
26+
+ json = -
27+
28+
- createdAt?: timestamp
29+
+ json = created_at,omitempty
30+
+ go.tag.db = created_at
31+
32+
33+
message Page
34+
- num: uint32
35+
36+
37+
service Example
38+
- Ping() => (status: bool)
39+
- GetUser(userID: uint64) => (user: User)
40+
- FindUsers(q: string) => (page: Page, users: []User)

example/example.webrpc.json

Whitespace-only changes.

example/go.mod

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module example
2+
3+
go 1.19
4+
5+
require (
6+
github.com/go-chi/chi/v5 v5.0.7
7+
github.com/go-chi/cors v1.2.1
8+
)

example/go.sum

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8=
2+
github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
3+
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
4+
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=

0 commit comments

Comments
 (0)