Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@webrpc/react-query npm package #1

Merged
merged 9 commits into from
Oct 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 0 additions & 56 deletions .eslintrc

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules
dist
1 change: 0 additions & 1 deletion .nvmrc

This file was deleted.

2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2022 golang.cz
Copyright (c) 2022 golang.cz and github.com/webrpc authors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
71 changes: 60 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,79 @@
# webRPC react-query client
@webrpc/react-query -- a react-query adapter for webrpc
=======================================================

Enjoy the RPC code-gen ergonomics + type-safety benefits of webrpc, with the comfort
of react-query from your React apps :)


## Install

From your webapps: `npm install @webrpc/react-query`

As well, make sure you install `@tanstack/react-query` and `react` in your app, which are
peer-dependencies of this library.


## Example

Please see a full example project with both server and client [here](./example).

To run the example:

1. git clone this repo
2. `cd example/webapp`
3. `pnpm install`
4. Start the server -- in one terminal: `make run-server`
5. Start the webapp -- in another terminal: `make run-webapp`
6. Open the webapp at http://localhost:4444 and open your browser console


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

First, you'll need an api contract, ideally in the webRPC format.
Then create an instance of your contract and pass it as an argument to the WebRPCClient constructor.
First, you'll need a webrpc schema definition either in JSON or RIDL.

Then create an instance of your RPC client and pass it as an argument to the WebRpcClient constructor.
It should look something like this:

```ts
const ContractInstance = new Chat('hostname', customFetch)
export const client = new WebRpcClient(ContractInstance)
import { Example } from './client.gen'
import { WebRpcQueryClient } from '@webrpc/react-query'

const rpc = new Example('http://localhost:4242', fetch)
const client = new WebRpcQueryClient(rpc)
```

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


## Differentiating queries and mutations

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

```ts
const ContractInstance = new Chat('hostname', fetch)
const client = new WebRpcClient<typeof ContractInstance, ['get', 'list']>(
ContractInstance,
)
import { Example } from './client.gen'
import { WebRpcQueryClient } from '@webrpc/react-query

const rpc = new Example('http://localhost:4242', fetch)
const client = new WebRpcQueryClient<typeof rpc, ['get', 'list']>(rpc)
```

With this configuration, you can only use `client.useQuery` hook with paths that start with either `'get'` or `'list'`.
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.

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.


## Local dev

You can update `example/webapp/package.json" package to `"@webrpc/react-query": "workspace:../../"`
which will use the build from the local repo.


## Credits

Thank you to @vojoup from the github.com/golang-cz team for the idea and original implementation of this library :)


## LICENSE

Licensed under [MIT License](./LICENSE)
20 changes: 20 additions & 0 deletions example/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
all:
@echo "please read Makefile source or README to see available commands"

generate: generate-server generate-client

generate-server:
webrpc-gen -schema=example.ridl -target=go -pkg=main -server -out=./server/example.gen.go

generate-client:
webrpc-gen -schema=example.ridl -target=ts -client -out=./webapp/src/client.gen.ts

bootstrap:
rm -rf webapp/node_modules
cd webapp && pnpm i

run-server:
@go run ./server

run-client:
@cd webapp && pnpm start
19 changes: 19 additions & 0 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
webrpc react-query example
==========================

* Server: Go
* Client: Web Browser (Typescript)

Simple client+server app with Go api backend (server) and Typescript Webapp (client).

1. `$ make bootstrap` - installs node modules for the webapp (client)
2. `$ make run-server` - to start the Go server at http://localhost:4242/
3. `$ make run-client` - build+start webapp via webpack dev server at http://localhost:4444/
4. Open your browser to https://localhost:4444/ and open your console, and see rpc calls, tada

webrpc comes with its own schema design language called RIDL, which stands for "RPC interface
design language" :) it reads and feels like documentation, but it very flexible. See
[hello-api.ridl](./hello-api.ridl) for the RIDL file for this service.

as well, webrpc supports a json-formatted schema with the identical functionality as the RIDL format.
See here, [hello-api.webrpc.json](./hello-api.webrpc.json).
40 changes: 40 additions & 0 deletions example/example.ridl
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
webrpc = v1

name = example
version = v1.0.0


enum Kind: uint32
- USER = 1
- ADMIN = 2


message User
- ID: uint64
+ json = id
+ go.tag.db = id

- username: string
+ json = USERNAME
+ go.tag.db = username

- role: Kind

- meta: map<string,any>

- internalID: uint64
+ json = -

- createdAt?: timestamp
+ json = created_at,omitempty
+ go.tag.db = created_at


message Page
- num: uint32


service Example
- Ping() => (status: bool)
- GetUser(userID: uint64) => (user: User)
- FindUsers(q: string) => (page: Page, users: []User)
Empty file added example/example.webrpc.json
Empty file.
8 changes: 8 additions & 0 deletions example/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module example

go 1.19

require (
github.com/go-chi/chi/v5 v5.0.7
github.com/go-chi/cors v1.2.1
)
4 changes: 4 additions & 0 deletions example/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8=
github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
Loading