Lang
Blog

Redwood.JS — Merging JAMstack with Full-Stack

A JavaScript Framework connecting React, GraphQL, and Prisma!

ByPayal Mittal
April 23rd . 5 min read
Redwood.JS — Merging JAMstack with Full-Stack

Building a JavaScript project is not that easy, as you have to take everything under the radar at the same time, the configuration, additional packages and technologies, plugins, database, all of it. And you also want to connect it with GraphQL which is the real pain because new graphql clients keep coming every week.

Redwood has been created to solve these problems. It connects multiple highly popular technologies together in database-backed single-page applications.

In this blog, we’ll get to know a few things about Redwood that may fascinate you-

What is RedwoodJS?

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

Redwood comes with a built-in command line generator that makes the development process easier. It is focused upon enhancing the user experience by offering improvements across various verticals such as removing most of the boilerplate, separating concerns for backend and frontend, adopting JAMstack for full-stack applications, bringing database-backed development workflow, etc.

It is built by using (and inspired by) many popular technologies, such as React, Storybook, Babel, JAMstack, Webpack, GraphQL (Apollo), Prisma, and Jest.

If you’re familiar with React, you can easily catch up with Redwood.

The most hyped features and functionalities of Redwood are given below-

  • Opinionated defaults for formatting, file organization, webpack, Babel, and more.
  • Simple but powerful routing and named route functions
  • Boilerplate-less GraphQL API construction.
  • Declarative data-fetching through Cells
  • Automatic page-based code-splitting.
  • Unique command-line generators
  • Business logic management via Services
  • Scaffold generator for CRUD operations
  • Hot module replacement (HMR)
  • Database migrations using Prisma
  • Forms with easy client/server-side and error handling.
  • Easy scaling through serverless functions.
  • JAMstack-style deployment to Netlify.

Redwood helps the developers in many ways such as it makes decisions for them and helps them pick the most favorable technology for the task and organize the codebase into well-structured files.

How Does it Work?

Imagine a React frontend, statically delivered by CDN, that talks through GraphQL with the backend, and deploys all the code via just a git push- this is Redwood.

RedwoodJS strongly pursues two principles-

  • Separation of concerns for frontend (called web) and backend (called api)
  • Unified user experience via simple conventions and faster local development

The architecture of RedwoodJS looks like this -

redwoodjs-merging-jamstack_1.jpg

It takes advantage of JAMstack architecture. Redwood stores the backend and frontend code into a single monorepo, like placing two node.js projects inside one monorepo.

The frontend project is referred to as ‘web side’ and the backend project as ‘api side’. Both of these projects act and deploy separately. While the web side code will run in the user’s browser, the api side code will run on a server.

But how can it use JAMstack in full-stack?

Well, here’s the thing- you can deploy the front-end and backend separately. For instance, when you’re building a fully static site that doesn’t need a database or API layer then you can only deploy the front-end side without any trouble.

In a nutshell, the Redwood architecture renders some amazing features that make the whole user experience worth your while.

Getting Started with Redwood.js

Before getting started, you would need Node.js v12 or higher and Yarn v1.15 or higher installed on your device. Also, the basic knowledge of React, JAMstack, and GraphQL would be beneficial.

You can start your new Redwood project through Yarn via this command -

yarn create redwood-app ./redwoodblog

After completion of the installation process, the file structure of Redwood will be auto-generated which looks like this -

redwoodjs-merging-jamstack_2.jpg

It basically consists of two types of directories -

  • /web directory: It serves as static files through CDN and encompasses code-splitting
  • /api directory: It contains a GraphQL API that contains the backend serverless functions needed as dynamic data for frontend

These directories are also conferred as ‘workspaces’ by Yarn, while Redwood refers to them as ‘sides’ (as we have mentioned above). To install any additional packages, you would have to specify where you would like to install them out of these two workspaces.

What Does Redwood Have In-store?

After having seen the long list of features above that Redwood have to offer, here’re some other unique features that would definitely convince you to use Redwood in your next project-

Routing:

Redwood provides powerful but simple routing via its own built-in featured Redwood Router (inspired by Ruby on Rails, React Router, and Reach Router) for Redwood applications. This is a much better solution than the React Router- more straightforward and easier to work with than the React router.

The RR matches the current URLs to all the routes and only renders those having a matching path. It lists out all the routes in a single file which then can easily track which route will map with which page.

The most exciting part is that it leverages the Named Route functions which allow you to specify a reference name, as you like, in the name prop of the route. It helps the developers to update the route paths in a much safer way without having to break or change any of the Links.

Cells:

Cells are the codified and declarative approach for data abstraction. The traditional web frameworks synchronously retrieve data from the API and follow the conventional pattern where the data fetching comes first and then the frontend loads data on the view layer. This process relays from frontend to backend in a sequence.

But the modern web applications do not follow this sequence instead, they fetch data asynchronously. The frontend and backend parts process independently which is why the view layer can process without waiting for the data-fetching to finish.

Redwood uses the concept of Cells which is a simpler way of asynchronous data fetching. A Cell is a higher-order component that contains graphql queries, states like loading, empty, error, or success. Each of these states can render itself automatically sensing the state in which the cell is in.

When a cell is created, it exports several named constants. Redwood can assemble the cells using these named constants and can perform optimizations from there without even changing any code.

You can create a cell using -

yarn rw generate cell <name>

A Cell file looks like this -

export const QUERY = gql`
  query USERS {
    users {
      id
      name
    }
  }
`
export const Loading = () => <div>Loading users...</div>
export const Empty = () => <div>No users yet!</div>
export const Failure = ({ message }) => <div>Error: {message}</div>
export const Success = ({ users }) => {
  return (
    <ul>
      { users.map(user => (
        <li>{user.id} | {user.name}</li>
      ))}
    </ul>
  )
}

The Cells concept seems like magic. All you have to do is to say what to do and when and Redwood will take care of it for you.

Services:

It is another stunning feature of Redwood that works on keeping things clean and structured. Redwood stores all the business logic inside the /services directory at the backend side. All this logic can be used anywhere in the backend code.

Redwood can import and map resolvers automatically from the corresponding services file to your SDL files. Also, you can call these resolvers as regular functions from other services or resolvers.

// api/src/services/posts/posts.js
import { db } from 'src/lib/db'
export const posts = () => {
  return db.post.findMany()
}
export const post = ({ id }) => {
  return db.post.findUnique({
    where: { id },
  })
}
export const createPost = ({ input }) => {
  return db.post.create({
    data: input,
  })
}
export const updatePost = ({ id, input }) => {
  return db.post.update({
    data: input,
    where: { id },
  })
}
export const deletePost = ({ id }) => {
  return db.post.delete({
    where: { id },
  })
}

These services are like any other JavaScript functions which you use anywhere like in other services, custom APIs, or custom lambda functions. Having your app divided into well-defined services can increase your codebase maintainability and facilitate the separation of concerns.

This was just a basic intro to Redwood. There is a whole lot more to learn and absorb. Check out the detailed documentation of Redwood here.

Do you know that RedwoodJS was named after Redwoods- the giant and the tallest tree of all to grow in the world? One of the founders of RedwoodJS, Tom Preston-Werner, considers the Redwood tree and framework similar in more than one way.

Or, we can say that the properties of Redwoods fascinated him a lot and aspired him to create a new web-app framework having the same powerful aura. For example, Redwoods are majestic, dense, robust, complex yet very simple and structured. This gave him an idea to build a web framework that would be complex but way too structured, managed, and robust.

Thanks for reading!!

Share:
0
+0