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

feat: Migrate the backend from GraphQL to tRPC #282

Merged
merged 10 commits into from
Oct 31, 2022
Merged
Show file tree
Hide file tree
Changes from 8 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
7 changes: 1 addition & 6 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,4 @@ tmp
lerna-debug.log
.env

packages/create-bison-app/dist/

# symlinked files in the template directory for development
packages/create-bison-app/template/types
packages/create-bison-app/template/api.graphql
packages/create-bison-app/template/types.ts
packages/create-bison-app/dist/
78 changes: 24 additions & 54 deletions docs/devWorkflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,28 @@

You're not required to follow this exact workflow, but we've found it gives a good developer experience.

We start from the API and then create the frontend. The reason for this is that Bison will generate types for your GraphQL operations which you will leverage in your components on the frontend.
We start from the API and then create the frontend. The reason for this is that Bison will infer types for your API procedures which you will leverage in your components on the frontend.

## API

### Generate a new GraphQL module
### Generate a new tRPC router

To generate a new GraphQL module we can run the command `yarn g:graphql MODULE_NAME`, replacing MODULE_NAME with the name of your module. In our example, we'll be using the concept of an `Organization`.
To generate a new tRPC router we can run the command `yarn g:trpc ROUTER_NAME`, replacing ROUTER_NAME with the name of your router. In our example, we'll be using the concept of an `Organization`.

```shell
yarn g:graphql organization
yarn g:trpc organization
```

This should output something like:

```shell
yarn run v1.22.10
$ hygen graphql new --name organization
$ hygen trpc new --name organization

Loaded templates: _templates
added: graphql/organization.ts
inject: graphql/schema.ts
added: server/routers/organization.ts
inject: server/routers/_app.ts
inject: server/routers/_app.ts
✨ Done in 0.34s.
```

Expand Down Expand Up @@ -62,25 +63,21 @@ model User {

Note that we have defined `organizations` as `Organization[]`.

### Run your migrations

This is currently a two step process, 1) generate the migration and 2) execute the migration

**Generate the migration**
### Generate and execute the migration

```shell
yarn g:migration
yarn db:migrate
```

**Execute the migration**
If you want to create the migration without executing it, run

```shell
yarn db:migrate
yarn db:migrate --create-only
```

## Write a type, query, input, or mutation using [Nexus](https://nexusjs.org/guides/schema)
## Write a query or mutation using [tRPC](https://trpc.io)

[See Nexus Examples](./nexus-examples.md)
[See tRPC Examples](./trpc-examples.md)

## Create a new request test

Expand All @@ -90,58 +87,31 @@ yarn g:test:request

## Run `yarn test` to start the test watcher

1. Add tests cases and update schema code accordingly. The GraphQL playground (localhost:3000/api/graphql) can be helpful to form the proper queries to use in tests.

1. `types.ts` and `api.graphql` should update automatically as you change files. Sometimes it's helpful to open these as a sanity check before moving on to the frontend code.
Add tests cases and update tRPC code accordingly.

## Frontend

1. Generate a new page using `yarn g:page`
1. Generate a new component using `yarn g:component`
1. If you need to fetch data in your component, use a cell. Generate one using `yarn g:cell`
1. To generate a typed GraphQL query, simply add it to the component or page:

```ts
export const SIGNUP_MUTATION = gql`
mutation signup($data: SignupInput!) {
signup(data: $data) {
token
user {
id
}
}
}
`;
```

5. Use the newly generated hooks from Codegen instead of the typical `useQuery` or `useMutation` hook. For the example above, that would be `useSignupMutation`. You'll now have a fully typed response to work with!
1. Use the hooks from tRPC, such as `trpc.user.signup.useMutation()`. You'll now have a fully typed response to work with!

```tsx
import { User, useMeQuery } from './types';

// adding this will auto-generate a custom hook in ./types.
export const ME_QUERY = gql`
query me {
me {
id
email
}
}
`;

// an example of taking a user as an argument with optional attributes
function noIdea(user: Partial<User>) {
import { trpc, inferQueryOutput } from '@/lib/trpc';

// an example of inferring the output of a query
function noIdea(user: Partial<inferQueryOutput<"user","me">>) {
console.log(user.email);
}

function fakeCell() {
// use the generated hook
const { data, loading, error } = useMeQuery();
const { data, isLoading, isError } = trpc.user.me.useQuery();

if (loading) return <Loading />;
if (isLoading) return <Loading />;

// data.user will be fully typed
return <Success user={data.user}>
// data will be fully typed
return <Success user={data}>
}
```

Expand Down
12 changes: 0 additions & 12 deletions docs/faq.md

This file was deleted.

Loading