metaforecast/docs/graphql.md
2022-04-26 00:46:42 +04:00

54 lines
3.4 KiB
Markdown

Metaforecast website is implemented on top of GraphQL API.
Tech stack:
- [Pothos](https://pothos-graphql.dev/) on the backend for implementing our graphql server
- [urql](https://formidable.com/open-source/urql/) on the frontend
- [GraphQL Code Generator](https://www.graphql-code-generator.com/) for schema generation, queries generation and schema introspection
Rationale for this stack can be found on [#32](https://github.com/quantified-uncertainty/metaforecast/issues/32) and [#21](https://github.com/quantified-uncertainty/metaforecast/issues/32) in comments.
# Code layout
List of all files used for graphql:
- [schema.graphql](../schema.graphql), GraphQL schema generated by graphql-code-generator.
- [codegen.yml](../codegen.yml), graphql-code-generator [config](https://www.graphql-code-generator.com/docs/config-reference/codegen-config)
- [graphql.config.yaml](../graphql.config.yaml), [GraphQL Config](https://www.graphql-config.com/) for better VS Code integration ([VS Code GraphQL extension](https://marketplace.visualstudio.com/items?itemName=GraphQL.vscode-graphql) type-checks graphql files thanks to it)
- [src/pages/api/graphql.ts](../src/pages/api/graphql.ts) implements the GraphQL HTTP endpoint and GraphQL playground
- [src/web/urql.ts](../src/web/urql.ts) contains some helper functions.
[src/graphql/](../src/graphql) dir contains GraphQL server code.
`*.graphql` files in `src/web/**` contain GraphQL fragments, queries and mutations which are used on the frontend.
`graphql-code-generator` converts those into `*.generated.ts` files which can be imported from the React components.
# Notes on caching
`urql` has both [document caching](https://formidable.com/open-source/urql/docs/basics/document-caching/) and [normalized caching](https://formidable.com/open-source/urql/docs/graphcache/normalized-caching/) (which we don't use yet).
Unfortunately, it's useful only on a page level: since we like server-side rendering, we still have to hit `getServerSideProps` on navigation, even if we have data in cache.
There are some possible workaround for this to make client-side navigation faster, but none of them are trivial to implement; relevant Next.js discussion to follow: https://github.com/vercel/next.js/discussions/19611
# Recipes
**I want to check out what Metaforecast's GraphQL API is capable of**
Go to [/api/graphql](https://metaforecast.org/api/graphql) and do some queries by hand. Note the "Docs" link in the top right corner.
**I want to add a new query/mutation to our schema**
Read the [Pothos](https://pothos-graphql.dev/) docs to learn how to implement new objects and fields. Add the new code somewhere in `src/graphql/schema/`.
**I want to display a new piece of data on the metaforecast website**
- add a query in a nearest `queries.graphql` file (if there isn't one, create it)
- run `gql-gen` (or keep it running with `gql-gen -w`) to get a `graphql.generated.ts` file
- use [useQuery](https://formidable.com/open-source/urql/docs/basics/react-preact/#queries) with your new `MyQueryDocument` which you can import from the `graphql.generated.ts` file
If you need SSR, you'll also need to do **the same** query with **the same variables** from your page's `getServerSideProps` function. Check out any existing page which calls `ssrUrql`.
(You might not need to use `useQuery` in your components if you're doing SSR and the page content is not dynamic, just pass the data from `getServerSideProps` in `props` and avoid GraphQL on the client side).