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).