DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’» is a community of 963,673 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Cover image for RedwoodJS - Create a full stack application in minutes
pacholoamit
pacholoamit

Posted on

RedwoodJS - Create a full stack application in minutes

Isn't it annoying re-inventing the wheel? Imagine this, you get a new idea for a startup or even just a basic project you'd like to do for yourself because you can. Here's what you're gonna start thinking about...

  • I've gotta write some boring boilerplate code for the client
  • I've gotta write some boring boilerplate code for the server/api
  • I've gotta do GASP auth... again.
  • I've gotta think about a deployment strategy.
  • Insert another annoying situation here that makes you rethink your career because you're so damn tired writing the same code over and over again for each project

I think I've made my point. Let's not reinvent the wheel and not repeat ourselves cough... DRY principle cough...

RedwoodJS solves most, if not all of these issues!

I hear you my fellow brethren & sistren with that out of the way, if you want to have a better quality of life as a developer please continue to read on and let's get coding!

Lets do this!

Step 1: Create a Redwood project

Let us start by creating a Redwood project from scratch to see how easy the process is. Reference to the quick start docs here

### Instantiate a new JS project

yarn create redwood-app my-redwood-project # OR

### Instantiate a new TS project

yarn create redwood-app my-redwood-project --typescript

cd my-redwood-project
yarn rw dev
Enter fullscreen mode Exit fullscreen mode

Bingo! you've got an API server w/Graphql, a front-end client, and a database ORM (Prisma)

Amazingly, with those 3 commands executed in the terminal here's what we've already done.

[x] Created a boilerplate for the client with ReactJS
[x] Created a graphql server with prisma as our ORM

Hey, if you ask me that's a pretty good deal ain't it!

If you visit the following ports on localhost you'll see all the magic that happened

localhost:8911 - API server
localhost:8911/graphql - Graphql playground
localhost:8910 - ReactJS front-end

Step 2: Generate a database model for Prisma

Lets try generating a model for Posts. Go into api/db/schema.prisma and add the following model:

# api/db/schema.prisma

model Post {
  id        Int      @id @default(autoincrement())
  title     String
  body      String
  createdAt DateTime @default(now())
}
Enter fullscreen mode Exit fullscreen mode

Then try running:

yarn rw prisma migrate dev # Runs the prisma migrations
yarn rw g sdl post # Creates sdl definitions
Enter fullscreen mode Exit fullscreen mode

This will create the prisma migrations for you, you will be prompted for a name for the migration, in this case you may name the migration as Create post or something like that.

Note: If you're facing problems here concerning types, this usually can get resolved by running:

yarn rw g types # Generates the necessary types. Usually fixes type errors
Enter fullscreen mode Exit fullscreen mode

Step 3: Check our model and add in some data

I prefer using Prisma studio to check our model since no components or pages get added to the web folder. All you have to do is run:

yarn rw prisma studio
Enter fullscreen mode Exit fullscreen mode

If you then proceed to localhost:5555 you should be greeted by Prisma studio

Prisma studio

Feel free creating, modifying, and/or deleting records here by clicking on Post. You will be greeted by this screen to perform CRUD operations within Prisma studio:

Prisma studio tables

Try clicking the Add record button to add some data to our database (currently it's in sqlite but RedwoodJS has integrations with many databases including MySQL & Postgres.)

Prisma studio new rows

Step 4: Create pages in the web folder

Let's shift our focus to the front-end. To generate a new page in RedwoodJS, all you have to do is run this command

yarn rw g page home /
Enter fullscreen mode Exit fullscreen mode

This will do the following:

  • Create a page located at web/src/pages/HomePage/
  • Create a test file located at web/src/pages/HomePage/
  • Create a a storybook file located at web/src/pages/HomePage/
  • Update the routes file

If you visit web/src/Routes.tsx you'll see it's been auto-magically updated for you

// web/src/Routes.tsx
import { Router, Route } from '@redwoodjs/router'

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

export default Routes
Enter fullscreen mode Exit fullscreen mode

and now if you visit http://localhost:8910/ you'll see a really good looking home page.

Home page

Step 5: Tying things together

Ok, to recap so we've:

  • Created a database model
  • Added some data into our sqlite database
  • Created a default Home page in our web application

Now, how do we fetch data from our back-end? RedwoodJS has this concept of cells (no, not the ones you learned in biology.)

In a nutshell, Cells serve 1 purpose and that is to display the correct components depending on the state of the data being fetched. Let's try creating a cell by running this command:

# Note: make sure it's plural `posts`

yarn rw g cell posts 
Enter fullscreen mode Exit fullscreen mode

After running the command, you'll see another auto-magically generated component in web/src/components/PostsCell

// web/src/components/PostsCell/PostsCell.tsx
export const QUERY = gql`
  query PostsQuery {
    posts {
      id
      body // Add this to see the body of your post
      title // Add this to see the title of your post
    }
  }
`

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

export const Empty = () => <div>Empty</div>

export const Failure = ({ error }: CellFailureProps) => (
  <div style={{ color: 'red' }}>Error: {error.message}</div>
)

export const Success = ({ posts }: CellSuccessProps<PostsQuery>) => {
  return (
    <ul>
    // Make this look good on your own time
    // I ain't getting paid for this
      {posts.map((item) => {
        return <li key={item.id}>{JSON.stringify(item)}</li>
      })}
    </ul>
  )
}

Enter fullscreen mode Exit fullscreen mode

As you can see the component renders depending on the current state of the data being fetched (Empty, Failure, Success,Loading) say goodbye to manually updating asynchronous data in your web app.

Now, this is just a component. It hasn't been used yet, to use it, you may want to import it in your home page for now:

import { MetaTags } from '@redwoodjs/web'
import PostsCell from 'src/components/PostsCell' // IMPORTANT

const HomePage = () => {
  return (
    <>
      <MetaTags title="Home" description="Home page" />

      <PostsCell />
    </>
  )
}

export default HomePage


Enter fullscreen mode Exit fullscreen mode

You should get an output like this:

Home page with cell

Bingo banggo bonggo! You just made a full-stack application in minutes πŸŽ‰πŸŽ‰πŸŽ‰

What about authentication and deployment?

You liar!

I know, I know... It ain't here but that's only because we've only scratched the surface. If we could get a fullstack web app in minutes, do you really think the deployment pipeline & setting up authentication will take longer? (Spoilers: It doesn't!)

If you want to proceed with setting up auth you may want to run this command so redwoordJS can help you set it up:

# RedwoodJS has adapters for many Auth providers too!
yarn rw setup auth --help
Enter fullscreen mode Exit fullscreen mode

For deployments:

# RedwoodJS also has many adapters for deployment providers
yarn rw setup deploy --help
Enter fullscreen mode Exit fullscreen mode

Conclusion

If you haven't noticed by now, RedwoodJS takes care of all the heavy lifting when it comes to setting up a project. We only have to run a few generator commands Laravel flashbacks inbound... and we only have to write code that matters...

We're called developers for a reason, let's develop new stuff

Top comments (0)

Need a better mental model for async/await?

Check out this classic DEV post on the subject.

β­οΈπŸŽ€ JavaScript Visualized: Promises & Async/Await

async await