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

3.4 KiB

Metaforecast website is implemented on top of GraphQL API.

Tech stack:

  • Pothos on the backend for implementing our graphql server
  • urql on the frontend
  • GraphQL Code Generator for schema generation, queries generation and schema introspection

Rationale for this stack can be found on #32 and #21 in comments.

Code layout

List of all files used for 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 and 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 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 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 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).