RedwoodJS with Hasura = ❤️
Tags: javascript, redwoodjs, graphql, hasura
Published: 2020-11-11 04:07:26

---
title: RedwoodJS with Hasura = ❤️
published: true
date: 2020-11-10 15:21:02 UTC
tags: JavaScript,RedwoodJS, graphql, hasura
canonical_url: https://hasura.io/blog/redwoodjs-with-graphql-hasura/
---

 ![RedwoodJS with Hasura = ❤️](https://hasura.io/blog/content/images/2020/11/redwoodjs_hasura-1.png)

RedwoodJS is the new sensation in full-stack application development. It is highly opinionated with a choice of technologies. This blog is a step by step tutorial on how to use Hasura with Redwood JS and make it double awesome.

Before we move forward, let’s have a small introduction about our two participants Redwood and Hasura.

**Redwood JS:**

- _ **Redwood is an opinionated, full-stack, serverless web application framework that will allow you to build and deploy JAMstack applications with ease.** _

Redwood JS uses a lot of the latest bleeding technology and abstracts all the complexity away from the developers. It uses React with Apollo for the frontend and has a lot of code generators like pages, cells, etc which makes development very easy. It also takes care of configuring tests, storybooks, etc out of the box. It uses Prisma for its GraphQL backend and enables you to create quick backends with DashBoard/GUI support. Sounds fascinating? Not just that, it supports out of the box deployment with Netlify, AWS, etc.

In one line, the developer has to write only the styles and business logic. Everything else has been taken care of.

**Hasura:**

- _ **Instant GraphQL with built-in authorization for your data** _

Hasura is a futuristic tool that lets you built GraphQL backends instantly from your existing database. It makes creating GraphQL backends as simple as a walk in the park.

**The Problem**

My equal love for both the tools created a desire for using them together. But Redwood JS was highly opinionated and didn't have any provisions to do it out of the box. This made me explore their codebase and figure out simple steps to start building applications with RedwoodJS + Hasura.

**Why Hasura?**

If we just focus on frontend parts of Redwood, it gives you literally everything you need, out of the box. It lets you create pages and control the routes manually as well (in case of customization), it lets you create cells along with stories and tests pre-configured. They will support React Native and Electron in the future. So, it's kind of an ideal frontend with all complexity abstracted (similar to Next.js, but more GraphQL focused).

Any frontend engineer who uses redwood would start loving it. But the constraint is, it's highly opinionated and you are obliged to use default integrations and this can be a lot of work. Hasura, on the other hand, is truly a one-stop GraphQL solution with redwood. It can be directly consumed by the Web side (what redwood calls its frontend) and also it supports auth/webhooks etc. Especially when the DB is Postgres, Hasura is pure black magic. Also with Prisma it's again the developer's responsibility to look after scaling/performance etc while Hasura does it out of the box.

## Step 1: Build a Hasura GraphQL backend

Refer to this detailed tutorial by Hasura to build a GraphQL backend [here](https://hasura.io/learn/graphql/hasura/introduction/). I am using one of their demo apps for this tutorial - [https://learn-graphql.demo.hasura.app/console](https://learn-graphql.demo.hasura.app/console).

This backend gives me a set of queries on Super Heros data. We will use the following query to fetch the required data:

```
    query getSuperHeros {
      superhero_aggregate {
        nodes {
          name
          team {
            name
          }
        }
      }
    }

```

## Step 2: Bootstrap a Redwood JS app

To bootstrap a Redwood JS app, run the following command.

```
yarn create redwood-app my-redwood-app

```

This will create a full-stack boilerplate with two subfolders `web` and `api`. Since we are going to use Hasura for the backend, we will not require this `api` folder. Hence, this folder can be deleted.

## Step 3: Create a Page

A Page is a screen/route of the app. Each Page gets loaded in a particular route. To create a Page, run the below command:

```
yarn redwood generate page SuperHero /

```

This will create a new Page called SuperHero inside the `pages` folder and will load the page in the route `/` ie: root route. You can replace `/` with `/custom-route` to load it in the desired path.

The page looks like this:

```
import { Link, routes } from '@redwoodjs/router'

const SuperHeroPage = () => {
  return (
    <>
      <h1>SuperHeroPage</h1>
      <p>
        Find me in 
        <code>./web/src/pages/SuperHeroPage/SuperHeroPage.js</code>
      </p>
      <p>
        My default route is named <code>superHero</code>, link to me with `
        <Link to={routes.superHero()}>SuperHero</Link>`
      </p>
    </>
  )
}

export default SuperHeroPage

```

## Step 4: Setup Hasura in RedWoodJS

In the generated Redwood JS files, the `src/index.js` file has the following code:

```
ReactDOM.render(
  <FatalErrorBoundary page={FatalErrorPage}>
    <RedwoodProvider>
      <Routes />
    </RedwoodProvider>
  </FatalErrorBoundary>,
  document.getElementById('redwood-app')
)

```

Here, the entire App is wrapped inside `RedWoodProvider` which is from the `redwoodjs` library. Reading through the source code, this provider uses `ApolloProvider` underneath. From the [source code](https://github.com/redwoodjs/redwood/blob/main/packages/web/src/graphql/index.tsx) :

```
/**
 * Create a GraphQL Client (Apollo) that points to the `apiProxyPath` that's
 * specified in `redwood.toml`.
 */
export const createGraphQLClient = (config: GraphQLClientConfig) => {
  return new ApolloClient({
    uri: `${window. __REDWOOD__ API_PROXY_PATH}/graphql`,
    cache: new InMemoryCache(),
    ...config,
  })
}

/**
 * A GraphQL provider that instantiates a client automatically.
 */
export const GraphQLProvider: React.FC<GraphQLProviderProps> = ({
  config = {},
  ...rest
}) => {
  return <ApolloProvider client={createGraphQLClient(config)} {...rest} />
}

```

and the provider gets the config as props in `RedWoodProvider` as below:

```
/* Modified a bit to shorten the code */
const RedwoodProvider: React.FC<RedwoodProviderProps> = ({
  useAuth = window. __REDWOOD__ USE_AUTH,
  graphQLClientConfig,
  children,
  ...rest
}) => {
    return (
      <GraphQLProvider config={graphQLClientConfig} {...rest}>
        <FlashProvider>{children}</FlashProvider>
      </GraphQLProvider>
    )
}

```

Considering the above piece of source code, we can override the existing set up by passing the config in props of RedWoodProvider. The `src/index.js` is modified accordingly:

```
ReactDOM.render(
  <FatalErrorBoundary page={FatalErrorPage}>
    <RedwoodProvider graphQLClientConfig={{
      // URL of your Hasura backend
      uri: 'https://learn-graphql.demo.hasura.app/v1/graphql' 
    }}>
      <Routes />
    </RedwoodProvider>
  </FatalErrorBoundary>,
  document.getElementById('redwood-app')
)

```

**Note: You can pass any config supported by Apollo Client through the** `graphQLClientConfig` **props.**

## Step 5: Generate a Cell

> Cells are a declarative approach to data fetching and one of Redwood's signature modes of abstraction.

Cells are auto-generated files, that have scaffolding to fire a GraphQL query and display loading/error states or data based on the response of the query. It reduces the efforts of retyping the boilerplate code. You can create a cell using the following command:

```
yarn rw g cell SuperHeros

```

This command will generate a Cell inside the src/components folder along with scaffolded tests and storybooks. The file looks like this:

```
export const QUERY = gql`
  query SuperHerosQuery {
    superHeros {
      id
    }
  }
`
export const Loading = () => <div>Loading...</div>
export const Empty = () => <div>Empty</div>
export const Failure = ({ error }) => <div>Error: {error.message}</div>
export const Success = ({ superHeros }) => {
  return JSON.stringify(superHeros)
}

```

Here we will also have to change the query and the components based on our UI/UX requirements. Let’s modify the above file to consume our query:

```
export const QUERY = gql`
  query getSuperHeros {
    superhero_aggregate {
      nodes {
        name
        team {
          name
        }
      }
    }
  }
`
export const Loading = () => <div>Loading...</div>
export const Empty = () => <div>Empty</div>
export const Failure = ({ error }) => <div>Error: {error.message}</div>
export const Success = ({ superhero_aggregate }) => {
  return (
    <div>
      {superhero_aggregate.nodes.map((hero) => (
        <li>{hero.name} - {hero.team.name}</li>
      ))}
    </div>
  )
}

```

Now lets import and use it in our `pages/SuperHeroPage/SuperHeroPage.js` file as below:

```
import SuperHerosCell from 'src/components/SuperHerosCell';
const SuperHeroPage = () => {
  return (
    <>
      <h1>SuperHeroPage</h1>
      <SuperHerosCell />
    </>
  )
}
export default SuperHeroPage

```

Execute the command `yarn rw dev` to run the application. The app opens in `http://localhost:8910/` by default. The output looks like this:

![RedwoodJS with Hasura = ❤️](https://paper-attachments.dropbox.com/s_450DCC3FE95D72F7F89A87A987F198EF14DB90FE334689CB9DC6DD4687450D7C_1604178710551_Screenshot+2020-10-31+at+22.11.46.png)

Tadaa! We have successfully created an app with RedwoodJS and Hasura.

## Bonus:

RedWood JS is actively building a lot of tools and to take advantage of all the tools and support, we will also have to modify `graphql.config.js` file.

Replace the contents of the file with the below code and you are ready to enjoy all the benefits RedwoodJS offers along with Hasura's superpowers!

```
module.exports = {
  // URL of your Hasura backend
  schema: `https://learn-graphql.demo.hasura.app/v1/graphql`, 
}

```

A sample implementation of Hasura + Redwood can be found [here](https://github.com/vilvaathibanpb/redwoodjs_hasura). Happy coding

* * *

**About the author**  
This blog post was written by Vilva Athiban P B, a JavaScript developer working for Omio as part of the [Hasura Technical Writer Program](https://hasura.io/blog/the-hasura-technical-writer-program/).

<!--kg-card-end: markdown-->