RedwoodJS: Intro & Web Side
Tags: javascript, webdev, beginners, react
Published: 2020-04-14 15:32:11

---
title: RedwoodJS: Intro & Web Side
published: true
description: 
tags: javascript, webdev, beginners, react
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/q29p6dsvi27itrfmb8sh.png
---

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/gf2iwck4ptogchftwgqg.png)

[Redwoodjs](https://redwoodjs.com) is an **opinionated serverless web framework** for Javascript, that allows you to create applications using the [JAMstack](https://jamstack.org).

Since it make you follow some code conventions (that will explore in this post) while coding, the developer experience is really lovely and I'm pretty sure after reading this post you will like to try it out!

## First Impressions

Topics like: **ReactJS**, **Apollo (GraphQL)**, **Prisma**, **Storybook**, **Babel**, **Webpack**, are really popular among web developers, and there's a good reason for that:
They all make the developer experience great!
> Don't forget to mention that each tool resolves many other issues on it's own environment

So now, imagine someone describe to you, their React frontend app, statically delivered by CDN, that talks via **GraphQL** to their backend running on **AWS Lambdas** around the world, all deployable with just a `git push` command?

Really cool uh?, Well this last paragraph it's exactly how [RedwoodJS is officially defined](https://redwoodjs.com/docs), so no more presentations needed, let's start digging into it!.

## JAMstack
> If you already understand what's the **JAMstack** you can skip this section and just jump ahead to the **Going through the web side** section.

*JAM* stands for **JavaScript, API & Markup**, and like you can imagine, it means that your app (if it applies) should be just about Markup (HTML) and Javascript (Using the API of the browers) and nothing else.
It's just a way to think about the workflow of an app development, by removing a backend server.

Nowadays the web need apps that are high-performant, have less security risk, and of course, there's a less cost when trying to scale them.

**How do you achieve this?** By making it small and simple from the begging, which happens to be one features of the JAMstack.

One of the many ways to define the JAMstack that I like more is the one from *Mathias Biilmann*, CEO & Co-founder of Netlify:

*"A modern web development architecture based on client-side JavaScript, reusable APIs, and prebuilt Markup"*

It's [very likely that you already have interact with one of these apps](https://github.com/automata/awesome-jamstack), or even work in one if you have use any of the [static site generators](https://www.staticgen.com) that are out there.

For obvious reasons, the JAMstack doesn't fit for all the apps, so how we can know if our app applies to this stack? Easy, if your app **doesn't relies on a tight coupling between client and server**, then you are on the right path.

Also, if you are using a server-side CMS (Drupal, Wordpress, etc..) or building a monolithic app with Node, Ruby, etc... the JAMstack is not what you are looking for.

So now you have a basic idea of what the JAMstack is, now let's check RedwoodJS.

## Going through the web side

RedwoodJS uses `node` and `yarn`, so you will need those to be installed on your computer. [Check Prerequisites Here](https://redwoodjs.com/tutorial/prerequisites)

To create an app just run:

```bash
yarn create redwood-app ./my-app
```

Let's start talking about how RedwoodJS organize the code.

### Code Organization

By default, a RedwoodJS app has 2 **sides**: `web` and `api`

```
my-app
|__api/
   |__prisma/
   |__migrations/
   |__src/
      |__functions/
      |__graphql/
      |__services/
   |__dev.db
|__web/
   |__public/
   |__src/
      |__components/
      |__layouts/
      |__pages/
   |__index.css
   |__index.html
   |__index.js
   |__Routes.js
```

Inside the `api` folder, we have 3 more directories:
 * `prisma/`:  Contains the database schema and the seeds to pre-populate your database.
 * `migrations/`: This folder will be created after running your first migration, and it contains snapshots of your database.
 * `src/`: This directory contains another 3 directories inside: 
   - `functions/`: This is where all the labmda functions live, you will find some other files to configure your Graphql API.
   - `graphql/`: Contains Schema Definition Language (SDL) files of your grapql schema
   - `services/`: Here you'll find all the business logic of your app, but in an abstract way, so it can be consume across all your app (**web** & **api**) in a consist way.

Now for the `web` folder, we have a more simple structure:
 * `public/`: This folder is for static resources
 * `src/`: This is where all the code for our React app will live:
   - `components/`: Besides your regular React components, RedwoodJS stores the `Cells` components in this directory too (we'll explore them later)
   - `layouts/`: Not much to say here, just use it for all the layouts that your app could have
   - `pages/`: This pages components, usually are wrapped by a layout component, and it's what the user see when they land on a url.

RedwoodJS call these top-level folders (**web** & **api**) **sides**, but underneath they are [**Yarn workspaces**](https://classic.yarnpkg.com/en/docs/workspaces/), and of course there are a couple of features around using them.

### The CLI

RedwoodJS comes with a [handy CLI app](https://redwoodjs.com/docs/the-redwood-command-line-interface) that let you run some task, like create an scaffold, create a database, running a migration, and so on.

Here is the list of some of the commands I use more:

* `yarn redwood dev` or `yarn rw dev`: Starts a development server
* `yarn rw test`: Run test suite using Jest
* `yarn rw db save`: Create a new migration
* `yarn rw db up`: Run any new migration and update the schema
* `yarn rw db seed`: Seed the database
* `yarn rw generate <resource>`: A generator for the given resource:
    - `cell`
    - `component`
    - `layout`
    - `page`
    - `scaffold`
    - `sdl`
    - `service`

We'll look more into the resources later.

### Alias Path

Like I've mention, following some code conventions allows us to increase the developer experience and we can see an example with how RedwoodJS handle the routes.

Let's create a new page using the cli:

```bash
yarn rw generate page hello /
```
As you can see, the page generators accepts 2 parameters, one is the name of the page, and the other one is the url of that page.

After running this command, you'll see a new directory inside `web/src/pages/` called `HelloPage`, as you can see RedwoodJS automatically takes the name you specified, capitalize it and append `Page` to create the folder name.

Let's see how our page component looks like:

```react
const HelloPage = () => {
  return (
    <div>
      <h1>HelloPage</h1>
      <p>Find me in ./web/src/pages/HelloPage/HelloPage.js</p>
    </div>
  )
}

export default HelloPage
```

As you can see, we no longer need to import React at the top of each component so we have more cleaner components.
You'll also notice that all the react component are **functional component**, and this is because they use **React Hooks** a lot, you still can use class though, but they don't recommend it.

Now let's take a look to the `Routes.js` file:

```react
import { Router, Route } from '@redwoodjs/router'

const Routes = () => {
  return (
    <Router>
      <Route path="/" page={HelloPage} name="hello" />
      <Route notfound page={NotFoundPage} />
    </Router>
  )
}

export default Routes
```

As you can see, there's a new `Route` component that points the `/` url to the `HelloPage` component. We can also notice a few other things happening on this file:

 * `<Router>` & `<Route>` component are coming from redwoodjs.
 * `HelloPage` & `NotFoundPage` components are not imported anywhere in this file.

So how does it know where to find this component? Well, since pages are what the user see when they land on a url, its gonna be obvious that all the pages component would need to be imported here, so RedwoodJS automatically import it for you at build time, so you don't need to have a huge `Routes.js` filled with `import ...` statments.

This feature also works with nested folders, but there's a rule: **the have to be uppercase**

```js
'src/pages/HomePage/HomePage.js'         -> HomePage
'src/pages/Admin/BooksPage/BooksPage.js' -> AdminBooksPage
```

### Named routes

Run this to create another page:

```bash
yarn rw generate page about
```

This time we just specify the resource name without the route, when we do this, Redwood automatically uses that same name, to define the route:

```react
const Routes = () => {
  return (
    <Router>
      <Route path="/about" page={AboutPage} name="about" />
      <Route path="/" page={HelloPage} name="hello" />
      <Route notfound page={NotFoundPage} />
    </Router>
  )
}
```

RedwoodJS uses the `<Link>` component to handle the navigations between pages, let's take a look on how to use it:

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

const HelloPage = () => {
  return (
    <div>
      <h1>HelloPage</h1>
      <Link to={routes.about()}>See about</Link>
    </div>
  )
}
```

The `<Link>` components accept a prop called `to`, and as you can see we passed it a function from the `routes` object. This is a **named route function** calling this function will generate the correct url, and maybe you already figure it out, but the name of the property inside the `routes` object is coming from the `name` prop that we set on the `<Route>` component:

```react
<Route path="/about" page={AboutPage} name="about" />
```

Additionally, the `to` prop also accepts a string, but a great thing about having this name route, is that we can change the url any time and all the links will be updated without having to do anything else.

### Cells

Another good thing about Redwoodjs are `Cells` components.

When you work with React, is very common to step into the next scenario:

You have to implement a simple listing page, that fetch data from your server, and then renders a list of items, easy!, but then you start asking yourself, what should I show when there's no items, or when there's been an error while fetching the data, or event what you show to the user while fetching this data!?

All the sudden you have to implement a single listing component that handle up to 4 different states.

The bad part is when you have this listing page for each resource of your app.

Well RedwoodJS found this use case to be very repetitive and that's why they create a `Cell` component.

***Cells*** *provide a simpler and more declarative approach to data fetching*.

That's how RedwoodJS define a `Cell` component. Okay, let's see them in action.

The next example would probably looks weird since we have not talk about the **api side**, but for now, you can just think that there's a grahpql model called `post` and all the backend works outta of magic.
*We'll talk about the api side on the next post*

```react
export const QUERY = gql`
  query {
    posts {
      id
      title
      body
      createdAt
    }
  }
`

export const Loading = () => <div>Loading...</div>

export const Empty = () => <div>No posts yet!</div>

export const Failure = ({ error }) => (
  <div>Error loading posts: {error.message}</div>
)

export const Success = ({ posts }) => {
  return posts.map((post) => (
    <article>
      <h2>{post.title}</h2>
      <div>{post.body}</div>
    </article>
  ))
}
```

Ok, I know there's a lot going on here, so lets just untangle all:

* There's a variable called `QUERY` been exported from this file and it holds a [gql](https://github.com/graphql/graphql-js) query
* There are 4 components been exported also: `Loading`, `Empty`, `Failure` and `Success`, each of one render a different UI representing the state of the component.

So what happens here, once React has made the render, RedwoodJS will execute the grahpql query from the `QUERY` variable while it renders the `Loading` component, once the call is done, it will render either `Empty`, `Failure` or `Success` component based on the query response.

Additionally you could use the `beforeQuery` and `afterQuery` lifecyles to do modify the props before they go to the `Success` component.

You can omit the `Empty` and `Failure` components, and after an empty data response, the `Success` component will be rendered or if there's any error will be outputted to the console.


## Wrapping up: Web Side

Even though there a lot of libraries and frameworks out there, TBH RedwoodJS looks really unique to me when it comes to a fast development, great developer experience and huge performance for develop web apps using the JAMstack.

The sad part? RedwoodJS is still in **alpha** version, so it's not production-ready yet, but they have an [interesting roadmap](https://redwoodjs.com/tutorial/wrapping-up), so feel free to try it out or even better [contribute to the framework](https://github.com/redwoodjs/redwood/issues)

On the next post we'll look into the API side of the framework and check what RedwoodJS offer us!

Thanks for reading! 👋🏻👋🏻