skip to content
Video cover art for Lets Learn RedwoodJS - Learn with Jason
Video

Lets Learn RedwoodJS - Learn with Jason

Anthony Campolo joins Learn With Jason to explain how RedwoodJS enables building database-backed Jamstack apps without wasting time on backend configuration

Open .md

Episode Description

Jason Lengstorf and Anthony Campolo build a full-stack blog with RedwoodJS, covering project setup, Prisma databases, scaffolding, and Netlify deployment.

Episode Summary

In this episode of Learn with Jason, Anthony Campolo walks Jason through building a full-stack blog application using RedwoodJS, a framework that brings Rails-like conventions to the JavaScript ecosystem. Anthony, a self-taught developer who transitioned from music education, explains how Redwood assembles existing tools like React, Prisma, GraphQL, and serverless functions into a cohesive, opinionated framework that reduces decision fatigue. The pair initialize a project, generate pages and layouts using Redwood's CLI, define a database model with Prisma's schema language, and scaffold a complete CRUD interface for blog posts in under an hour. Along the way, they discuss how Redwood compares to alternatives like Blitz and Next.js, the broader pattern of expansion and contraction in the JavaScript ecosystem, and the value of curation over creation in framework design. They also explore Redwood's "cell" pattern for declarative data fetching, which automatically handles loading, error, and empty states. The session wraps with a deployment to Netlify backed by a Heroku Postgres database, demonstrating the full journey from zero to a live, database-driven application with remarkably little configuration.

Chapters

00:00:00 - Introductions and Background

Jason welcomes Anthony Campolo to the show after some initial technical difficulties getting the stream running. Anthony shares his non-traditional path into web development, starting as a music teacher who ran cross-country tours and managed a performing arts summer camp before discovering coding through machine learning and Python.

Anthony explains how he eventually gravitated toward web development because of its immediate feedback loop compared to machine learning, and enrolled in Lambda School for full-stack web development. He mentions his passion for RedwoodJS as the main topic for the episode, and the two prepare to dive in by fielding a raid from another streamer and discussing Advent of Code as a resource for aspiring developers.

00:04:43 - Initializing a Redwood Project and Understanding the Framework

Anthony walks Jason through creating a new Redwood project using the yarn create command, and while waiting for installation, explains what RedwoodJS is at a high level: a full-stack serverless framework for the Jamstack that combines a React frontend with a GraphQL and Lambda-powered backend. The project installs in just over a minute, and they begin exploring the generated file structure.

Jason examines the project's API and web folders, the Redwood configuration file, and the GraphQL config. The conversation turns to how Redwood eliminates the cognitive overhead of choosing and connecting individual tools by providing conventions out of the box. They reference the architectural diagram on the Redwood homepage, noting that while it captures the full picture, it only makes intuitive sense after you've built something with the framework.

00:11:10 - Generating Pages, Routes, and Layouts

Anthony introduces Redwood's CLI-driven workflow, showing Jason how to generate a homepage and about page using simple commands that automatically create components, routes, test files, and Storybook stories. They discuss how this convention-over-configuration approach echoes Angular's CLI patterns, ensuring consistency across the project.

The pair then generates a blog layout component, imports Redwood's Link and Routes utilities, and builds a basic navigation bar. Jason styles the layout with plain CSS while they discuss Redwood's unopinionated approach to styling, which supports Tailwind, styled-components, or vanilla CSS. They wire the layout into both pages and get a working multi-page site with navigation up and running.

00:18:05 - Discussing the JavaScript Ecosystem and Redwood's Philosophy

The conversation broadens as they address a chat question about scaling Redwood for large sites, with Anthony clarifying that Redwood's sweet spot is data-intensive applications rather than content-heavy static sites. Jason reflects on the cyclical pattern of JavaScript development where new libraries proliferate, then get consolidated into convention-based frameworks.

Jason frames Redwood as a curation effort rather than a creation effort, assembling the best available tools rather than inventing new ones. Anthony discusses how other frameworks like Blitz take different assembly approaches, such as using RPC instead of GraphQL, and how Vue might eventually get its own equivalent. They explore the tension between Redwood's Rails-like conventions and its Jamstack-friendly decoupled architecture.

00:27:31 - Setting Up Prisma and the Database

The focus shifts to the backend as Anthony guides Jason through Prisma, explaining its evolution from a GraphQL backend-as-a-service to a standalone ORM. They edit the Prisma schema file, renaming the example model to Post with title, body, and createdAt fields, and Jason discovers that the Prisma VS Code extension provides helpful autocomplete suggestions.

After defining the model, they run Redwood's database commands to create a migration and apply it, generating SQL that creates the actual database tables. Jason appreciates the automatically generated migration readme that documents every schema change, noting this kind of record-keeping is something developers often skip but shouldn't. They confirm the database is ready and move on to scaffolding.

00:34:24 - Scaffolding the Blog and Understanding Cells

Anthony introduces the scaffold command, which generates a complete CRUD interface for blog posts in one step, including forms, list views, and detail pages styled with Tailwind. Jason creates a test post and confirms data persistence, impressed by how much functionality was generated automatically. They then generate a Redwood cell, a declarative data-fetching pattern that defines loading, empty, error, and success states for GraphQL queries.

Jason imports the cell into the homepage and builds a custom display for blog posts with titles, bodies, and timestamps. While the cell's magic of automatically handling query states initially puts Jason on his back foot, he recognizes the power of the abstraction. After a brief debugging moment where they forget a return statement, the blog renders correctly with live data from the database.

00:52:32 - Deploying to Netlify with Heroku Postgres

With the blog working locally, they move to deployment. Anthony shows that Redwood has a generate deploy command that creates a Netlify configuration file automatically. Jason pushes the code to GitHub, initializes a Netlify site from the command line, and the first build starts. They switch the Prisma data source from SQLite to Postgres for production use.

Jason creates a free Heroku Postgres database, copies the connection string into Netlify's environment variables, and triggers a fresh deploy. While waiting for the build, they discuss Tom Preston-Werner's involvement with both Netlify and Redwood, deployment alternatives like Vercel, and the Netlify Masker Chrome extension for hiding secrets during livestreams. The deploy succeeds, and chat members begin creating posts on the live site.

01:06:58 - Authentication, Wrap-Up, and Next Steps

Anthony briefly covers the authentication options available in Redwood, including Netlify Identity, Auth0, and magic link authentication, noting that the tutorial's auth section and the RBAC cookbook provide deeper guidance. Jason reflects on the impressive amount they accomplished in under an hour: a Postgres database, Prisma ORM, GraphQL API, routing, page generation, a scaffold admin UI, custom display logic, and a live Netlify deployment.

The discussion closes with thoughts on where Redwood fits on the spectrum between prescriptive frameworks and do-it-yourself approaches, with Jason noting its particular value for teams that need shared conventions quickly. Anthony announces he's joining the Redwood core team and encourages viewers to check out the community forums and Discord. Jason previews upcoming episodes, including an intro to Vue 3 with Ben Hong, and thanks the sponsors and White Coat Captioning for making the show accessible.

Transcript

00:00:04 - Anthony Campolo

It's funny, I was getting messages like, are you guys live yet? I know.

00:00:09 - Jason Lengstorf

Hello everybody and welcome to another episode of Learn with Jason. Sorry for the technical difficulties, but we are here and we're ready. With me today is Anthony Campolo. Thank you so much for taking the time to join us today.

00:00:23 - Anthony Campolo

Hey, I am so excited to be here. Thank you so much for having me. I'm someone who am a budding developer advocate, developer educator myself, and your work has been such a huge inspiration to me. So it's really great to be here.

00:00:37 - Jason Lengstorf

Thank you so much. That's my warm fuzzy for the day. Now that we're done battling the computers and we are live, we're ready, we're talking to everybody. I'm going to send a tweet that I meant to send out a while ago. Let's see, might just be the trick. https://twitch.tv/jlengstorf — my computer just rebelled and it wouldn't cooperate at all. It wouldn't stream. It was just yelling at me. It was being rude. It hurt my feelings. But we are up and running now and I am just plain thrilled about it. So AJCWebDev, which y'all should be following.

00:01:18 - Anthony Campolo

The one.

00:01:21 - Jason Lengstorf

Okay, tweeting it has been tweeted. Now chat, thank you for hanging out with us. Appreciate y'all spending time. So Anthony, for those of us who are not familiar with your work, as you said, you are a budding web developer or a dev advocate. What's your background? What have you been up to?

00:01:45 - Anthony Campolo

Yeah, I'm someone who came through the non traditional background. I was originally a music teacher. That's partly why I really resonated with your story. You know, someone who came up in touring bands and you know, worked on your band's website and yeah, all that stuff was like, yeah, no, I did all that. I did, you know, a cross country like 22 state tour back in the day. So I lived that whole life and then I spent a couple years running a performing arts summer camp. So it was a camp that I went to myself as a camper and it started as a theater camp and then they added rock band and film and all these other things. So it was like a general performing arts summer camp. And that was really incredible. I learned a lot about just operations and logistics and admin work and how to run events. It was great, but it wasn't really what I wanted to do for the rest of my life. So I eventually found my way to web development type stuff. I originally was interested in machine learning and was learning Python and tensorflow and that kind of stuff, which is cool.

00:02:50 - Anthony Campolo

Still, like really passionate about, but it was like hard to really make progress there. Whereas, like web dev, you can like just start building stuff like throw up an HTML page and just like see the results. And so a lot of people, you know, have talked about the virtues of that kind of like feedback loop. And I eventually joined Lambda School studying full stack web development. And so I'm still currently in that program. I'm going through the computer science unit, which is kind of like the final unit after all the web stuff. So I'm getting near the end of that. Cool. And I'm like really passionate about Redwood js and I'm kind of here to talk about that.

00:03:28 - Jason Lengstorf

Absolutely. Yeah. So you mentioned before we started. Hey, Chris, what's up? Thank you for the raid. Hello, everyone.

00:03:36 - Anthony Campolo

Good person to raid.

00:03:39 - Jason Lengstorf

I know Chris was doing Advent of Code, which if you haven't heard of Advent of Code, it is — oh, thank you, Chris, for the sub as well — Advent of Code is a challenge in the month of December with some puzzles, code puzzles that'll help you kind of sharpen up. It's especially useful if you are trying to break into tech coding. Interviews can sometimes be like algorithm challenges or things like that. And these questions are very similar to that. So it'll help you kind of think in that mode. So if you want to give that a shot, it is Advent or Advent of Code. That's the one. So feel free to go hit that. It's a good time. But yeah, thanks Chris, for joining. Thank you everybody for coming along for that raid. And you had mentioned before we started that it can take a second to get a project with Redwood initialized. So instead of doing what I usually do, which is talk about Redwood and then initialize a project. Let's initialize and then we'll talk about it. So can you walk me through what my first step is if I want to create a new Redwood project?

00:04:43 - Anthony Campolo

Absolutely. Do you have yarn? I'm assuming you do.

00:04:46 - Jason Lengstorf

Yeah, I do.

00:04:50 - Anthony Campolo

Great. So the first thing will be yarn create, and then redwood-app, and then a dot forward slash. And then you'll give like the name of your project so you can call it whatever you want to call the project.

00:05:11 - Jason Lengstorf

Let's call this one. What did I name this episode? Let's learn Redwood js.

00:05:19 - Anthony Campolo

Okay, so this will do the whole generation of the project. Usually it takes a couple minutes because there's quite a lot to do. It also installs your dependencies.

00:05:28 - Jason Lengstorf

Yeah. So maybe what we can do to start is we can talk a little bit about what RedwoodJS is. So I've heard the name, but I'll be honest, this is the first thing that I've ever done with Redwood js. So I'm brand new to this as a technology. So what is it at the high level?

00:05:46 - Anthony Campolo

Yeah, we say that RedwoodJS is taking Full Stack to the jamstack and the longer version of that is it's a full-stack serverless framework for the Jamstack. There's a lot of buzzwords there. Really what I want to get across is that it's a project with your front end, which is like a Create React App, and then also a back end, which is like Lambda functions, GraphQL-type backend stuff. So it's about taking all these pieces of modern web development and the way people are wiring up their own kind of Full Stack projects and formalizing that with conventions.

00:06:26 - Jason Lengstorf

Okay. In one way that I've heard this described. Oh, that went so fast. Okay. I am installed. Wow. Okay. I was expecting that to take way longer.

00:06:40 - Anthony Campolo

It took 66 seconds.

00:06:42 - Jason Lengstorf

All right, so now that we're in here, I'm just going to open this up. Let's open it up over here, actually. There we go.

00:06:52 - Anthony Campolo

Yeah. So this is great. I find actually looking at a project is much easier than trying to, theoretically.

00:06:58 - Jason Lengstorf

Yeah. One second. I got to get in here so that it doesn't dim everything. How about now?

00:07:05 - Anthony Campolo

And we'll probably be deploying this also.

00:07:08 - Jason Lengstorf

Much better. Okay, so now we've got a project. I'm trying some new VS code settings that I saw mentioned by. I think it was Burk Holland's idea. And then Niki Muhleman pointed me toward these of having the VS code file on the right, which still getting used to it. But I think I like it.

00:07:31 - Anthony Campolo

It's very interesting.

00:07:32 - Jason Lengstorf

Yeah. Okay, so now if I look in here, I can see I've got an API folder, I've got a web folder. So let's look at the top level here. We've got our Redwood Toml. Okay, we've got a README. READMEs are always great, but today you are my readme. We've got GraphQL config, Babel configuration, an example env file. Now, I assume we're going to have to create a database. It doesn't do that for us.

00:08:11 - Anthony Campolo

Yeah. The database question is an interesting one. The way it's set up and the way we'll probably do it today is you create a Heroku postgres database and grab the environment variable and throw it into netlify where your front end is deployed.

00:08:24 - Jason Lengstorf

Got it? Okay, cool. All right, so where should we start if we want to pick this apart? Because what you said, it lands with me because I think that jamstack has so much potential and I think that there's a general perception at first, at least, that when you build a jamstack site that there are severe limitations on what you can do with it. But I think that as you dig further into that, that becomes less and less true. You can kind of do whatever you want with jamstack sites because static assets don't necessarily mean static experiences. And so what Redwood is promising then is to take a lot of the question marks out because getting from static assets to a highly dynamic experience with databases and serverless functions and all these things, there are some decisions to be made. Because serverless functions, that's a whole mental model. You have to build databases, that's you got to choose a service, you got to choose a database flavor, you got to figure out how to configure that, you got to decide how you're going to secure it and lock it down. All of those things are. That's cognitive overhead.

00:09:35 - Jason Lengstorf

Right. And so what you're saying is that Redwood is trying to eliminate a lot of that decision making process by giving us a ready made. Like this is an app building framework that has made the decisions to give you a good shot of doing this the right way. Is that a safe assumption of how to frame that?

00:09:55 - Anthony Campolo

Yeah, that's a great way to put it. It's as we say, convention over configuration. We have, if you look at historically we had really strong conventions around full stack development with things like Ruby on Rails and then as single page JavaScript applications have become more of the main thing, we've gone away from a lot of those conventions. And this is trying to take everything we've learned over the last five years or so with things like React and GraphQL and these new modern web paradigms, and stitch those back together into conventions that make sense and that eliminate a lot of the decision fatigue and choices that go along with just how you set up your file structure, how you connect your front end to your back end, how everything speaks together. And it's trying to do that in a jamstack paradigm by taking what we all like about the jamstack and the benefits of the jam stack in terms of performance, reliability and security, and extend that to the entire Stack.

00:10:56 - Jason Lengstorf

Absolutely. Okay, that makes sense. I have a brand new project. If I want to get this up and running I assume. Is this already ready to serve? Can I just start it?

00:11:10 - Anthony Campolo

Yeah. The first way you would get it going is the main command to start your dev server is yarn rw, which is the alias for Redwood. You can either type redwood or just rw, and then dev.

00:11:29 - Jason Lengstorf

Okay.

00:11:31 - Anthony Campolo

Yeah. So this is going to give us our main splash page and then from there we'll just start generating pages and that's kind of the first thing that we can get into. I find that just start kind of building out the project like incrementally. You learn the different pieces and how they all fit together. And if you tried to like explain the whole thing, there's an architectural diagram. Go to the homepage real quick, like the RedwoodJS homepage. And scroll down, keep scrolling. Yeah, that thing right there. Yeah. So that architectural diagram, that's a picture of like the whole project. I find that if you're someone who like likes architectural diagrams that may be really useful but it's like a lot to take in. It didn't really make sense to me until like I had already built like the whole thing and then I went back and looked at that picture like eh, now it makes sense.

00:12:18 - Jason Lengstorf

Yeah, yeah, yeah. And I mean it's, you know this is what's always interesting about these, is that this is just about any app is going to look pretty similar to this, whether it's built on Jamstack, on a traditional like Lamp stack, you're going to have, you know, you've got your web bits, you have to deliver markup, CSS and JavaScript to the browser and then you have your kind of like API or dynamic layer where you're sending requests back to some kind of a server. So in this architecture. And that's the front end, back end split. I like this dotted line to kind of signify that.

00:12:53 - Anthony Campolo

Yes you do. I tell people, start with look at the left side and that's like your actual directory structures when you're looking at your web folder and your API folder and those are all contained in the Mono repo.

00:13:02 - Jason Lengstorf

Yeah, yeah. All right, so this all makes sense. I mean I'm excited to see how it actually works, but in the abstract I get where we're going. So now that I've got this site running, it's over here we can see we've got Redwood router. Okay. So that's a thing that we're gonna have to learn. But this looks pretty similar to like React router or reach router if you've used those. So that's good. It feels familiar. What? So, yeah, I guess like I saw it, it set up, it said a Prisma client. Does that mean that it also set up a database or it just set up an empty client to start?

00:13:41 - Anthony Campolo

Yeah. So right now it's initialized and set up to where you could get your database going really quickly. We haven't quite gotten to that point yet. We'll start off in the front end generating some pages and routing those together. And then we'll get into the Prisma database, type stuff. But out of the box, everything is very much ready to go in terms of it's already wired up for SQLite for development and then you just have to change a single variable in one of the config files to make it for postgres. But this is getting ahead of where we are right now. Sure. Okay, what we should do is you should keep your terminal running and then we should get another terminal open so we can run commands to generate pages and stuff like that.

00:14:25 - Jason Lengstorf

Cool. So I'll just keep this one running in the background. We'll use the VS code one for everything else. So I'm ready.

00:14:34 - Anthony Campolo

Cool. The first one, everything is going to have basically yarn, redwood or RW is going to be the first starting commands. Then for this one, it's either G or generate. Just the letter G is the alias for generate and then page and then space and then all lowercase home and then space and a forward slash. What this is going to do is this is going to create a homepage for us and it's going to create a route to our just main homepage. That's what the slash is for. That's going to generate the route and the home is. So it's going to name the. It's going to be like homepage, going to the name of our component and it's going to be in a folder called homepage and it's going to generate a whole bunch of stuff. So that's the command, so go ahead and run that.

00:15:22 - Jason Lengstorf

So to just repeat this back and make sure that I get it, we're using Yarn so that we don't have to globally install the Redwood cli.

00:15:29 - Anthony Campolo

Correct.

00:15:31 - Jason Lengstorf

And that's because it's installed in our package JSON down here. And so when we have Redwood, then we can run this redwood command. G is for generate, Page is the type of thing we're generating. Home is the name of it. And this is the path, like what we want it to be from the website URL.

00:15:54 - Anthony Campolo

Yep, got it.

00:15:55 - Jason Lengstorf

Makes sense. All right, so I'm running this command

00:15:59 - Anthony Campolo

and it's also going to generate a couple other things as well. It's going to generate a storybook file and a test file. So it's set up in a way where you can run your storybook automatically. You don't have to configure storybook at all. And you don't have to set up Jest tests. It gives you kind of a base to work from. It sets you up for TDD out of the box. Because, like, this kind of goes along with the Rails influence is they're trying to bring some of the conventions around testing as well into these JavaScript frameworks.

00:16:30 - Jason Lengstorf

Gotcha. Okay. All right, I'm with you. So now that we've created this, we've got a homepage. And so I'm going to open this up and then if you go back

00:16:39 - Anthony Campolo

to where our project is running, it automatically jumps to that, so it gets rid of the splash page. And now this is our homepage, this is our home route. Then we'll have a route splash folder to this. So this is the actual page we're looking at. And if you look at the routes file. Yeah. So this is your kind of whole route. And so part of why Tom built their own router is because he wanted a flat routing structure. You don't want nested routes. So your routing here is essentially every time you generate a route or generate a page, it automatically sets up your route. And this is one of the big things you get, in contrast to something like Next, which also has its own router. So a lot of these frameworks, the routing layer is a really big piece.

00:17:25 - Jason Lengstorf

Gotcha. Okay, I'm seeing in this some echoes of the angular style of setting things up. Where what this does is we're using the CLI because there are connections throughout the file. So when you create a page, you have to create a homepage, and then you also have to update the routes and potentially some other things as well. So the CLI is kind of making sure that everyone does everything the same way. And that's what you mean by convention over configuration. We know that things are predictable now because in order to work, it has to be done according to this convention.

00:18:05 - Anthony Campolo

Yeah. And to answer the question in the chat, so if we were generating 500 pages of your blog, when we do the scaffold command, each blog post gets its own page based on an auto-generated ID, that's the way that works. But honestly, the blog format is a good way to understand a Redwood project, but it's not really the sweet spot for Redwood. It's more about creating data intensive web applications with multiple clients and less so about generating tons and tons of pages. But that is something you can kind of do with it. So. Yeah, sure.

00:18:42 - Jason Lengstorf

Okay. Well, yeah, so now that I've got this homepage we're set up here that is cool. And it's already got a link, which is also nice. I do like that the examples kind of get done in place. I think that's a good way to. Yeah, this makes me happy to see that sort of stuff. But yeah. Hey, what's up, Peyton? Thank you for the host. Then. Then what, what should we do next?

00:19:12 - Anthony Campolo

What I would usually do here is I would just kind of like edit this just to kind of make it a little clean, like give your own title and. Yeah, and you can actually take out the, the link. Because what we're going to do is we're going to create a layout that's going to wrap our pages, that's going to have our links for, for us in a nav bar.

00:19:30 - Jason Lengstorf

Okay.

00:19:34 - Anthony Campolo

Yeah. And then the next thing we would do is we would basically do that previous command again, but now with about instead of home. And you don't have to specify a path at all because it's going to create a path to about and it's going to create an about page. It's going to do both of those.

00:19:50 - Jason Lengstorf

Gotcha. Okay. Doing it.

00:19:54 - Anthony Campolo

And it also will generate the same kind of extra files and all that. Okay, so if you project, you'll just want to type it in. Yep, you got it.

00:20:12 - Jason Lengstorf

All right, that's, that's intuitive. I get it.

00:20:15 - Anthony Campolo

Yeah, yeah. So this is a lot of the stuff you get for something like next where like you get very simple like page based routing. Like you're just creating pages. Your pages are your routes. Like this. This to me is kind of like a no brainer. But now what we're going to do is we're going to do the yarn redwood generate command, but instead of generating a page, we're going to generate a layout and then call the layout. Just blog, all lowercase.

00:20:43 - Jason Lengstorf

Okay. And I'm assuming that's going to show up in my layouts.

00:20:49 - Anthony Campolo

You got it.

00:20:50 - Jason Lengstorf

Blog layout. All right.

00:20:55 - Anthony Campolo

Okay, so this will be a bit of typing here. So what we want to do is we want to import. So go up above your component and import and then it's going to be Link with an uppercase L and. Yes, you got it. And then comma. And then routes, lowercase. Then that's going to be from RedwoodJS router.

00:21:20 - Jason Lengstorf

Okay.

00:21:21 - Anthony Campolo

Yep.

00:21:22 - Jason Lengstorf

And then here I'm going to. Let's. Let's do one of these, and we'll set this up with just some basic semantics. Right? So we'll make this our main element. And then up above it we can do like a header. And we'll start. I guess we can just do like a nav. And for each of these. Oh, wait, that's not what we want. We want the link. Remind me what the syntax is here?

00:21:57 - Anthony Campolo

So it'll be to equals, and then brackets. Like this. Yeah. Brackets, not quotes.

00:22:09 - Jason Lengstorf

Brackets, not quotes.

00:22:10 - Anthony Campolo

Okay, not quite. Yeah. So brackets, not quotes. Inside the brackets is going to be routes, home and then parentheses after.

00:22:20 - Jason Lengstorf

Interesting. So now I've got like, dynamic.

00:22:23 - Anthony Campolo

It's a function.

00:22:24 - Jason Lengstorf

Yeah.

00:22:25 - Anthony Campolo

Named route function is what we call them.

00:22:27 - Jason Lengstorf

I like this because now what that means is that if I change the path, I don't have to go find everywhere in my app that has that path. Interesting. Okay, perfect. I'm into that. And then I'm going to set about and about. And what does Redwood say about styles? Like, what's its opinion here?

00:22:51 - Anthony Campolo

It's very unopinionated about styles, in the sense that you can use styled-components, you can use Tailwind. There's like a tailwind generator to configure tailwind really quickly because people love tailwind. But you can just go into your index CSS file and just style it naturally. Also, that's usually what I do because I'm not big CSS framework kind of guy.

00:23:13 - Jason Lengstorf

Gotcha. So if we just set this up to be, like, go nuts. Okay, so we'll just. We'll make this kind of. Obviously, we should probably go with a darker color than that. Let's just make it a dark gray. And then for our main. We will display block and max width 90, width of 500 and. Probably don't want. Yeah, that'll be fine. So that's good enough. But we're not using it yet. So how do I actually use this layout?

00:23:56 - Anthony Campolo

So what we want to do is you want to go to the page you want to use it in. So we'll put into both of our pages. So you start with home or either about, and then you're going to import it. So it's just a component and it's import. Blog. Layout. Blog and layout are both capitalized. Yep. And then from. So you're not going to do any dashes or slashes or. There's no. There's no, like, relative routing of between. Between paths. You're just going to do SRC layouts, forward slash, blog layout. You just give it the exact directory the thing you're importing is from. You don't do a JS or anything at the end. And then you're going to wrap it like that, and that should do it.

00:24:38 - Jason Lengstorf

Okay, we'll do the same thing here. All right. And aside from the fact that that is atrocious, let's fix that real quick. So we'll go up here and set a margin of zero. We'll give this a color of white, and we'll give it some padding of like 2rem. And how about that? Oh, but I need to style my links. How about that? Okay, that looks useful. And then we also want to add a little bit of spacing around these. So let's go display flex and we'll do a gap of 1rem. Beautiful.

00:25:32 - Anthony Campolo

Nice. This is something that's still a huge gap in my knowledge, being able to just, like, write CSS on the fly. We learned, like, CSS like, a week in our boot camp.

00:25:42 - Jason Lengstorf

Okay, so this. Now we've got, like, a pretty basic setup. Right. Like, this is. I'm into it.

00:25:48 - Anthony Campolo

Yeah, right. It's killer. Right.

00:25:50 - Jason Lengstorf

I'm going to do one more thing just to give us some. I have a shortcut to make that happen. So now we've got the default system fonts.

00:26:01 - Anthony Campolo

Just laughing in the chat, someone's like, wait, why is this files on the right?

00:26:04 - Jason Lengstorf

I know, I know. I've upset everyone. I'm sorry, Nate. Yeah. Nicky just linked to the tweet that shows the setup. But there's a really good reason for this, actually. I'll show you why. I like to toggle my files open and closed, and it doesn't bounce the code around anymore. So this is actually enough of a reason for me to do it.

00:26:27 - Anthony Campolo

That makes a lot of sense. That makes a ton of sense. I'm constantly opening and closing my thing on the left to try and get more space. Yeah, that makes a ton of sense.

00:26:37 - Jason Lengstorf

Yeah. So it's just those little things. Like, I didn't even realize that my eyes were tracking that left and right until I wasn't doing it anymore. And I was like, oh, that's pleasant. I like that.

00:26:49 - Anthony Campolo

Okay, so what we've done so far is we have, like, generated our pages. We create a layout, we've routed them all together. Like this is really good stuff that you get from a front end framework like Gatsby or Next in terms of like having a sensible way to organize your front end. Now here's where the really interesting stuff starts happening. So now we're going to start getting into Prisma. We're going to want to go into our API folder now instead of our web folder. So this is now our back end and we're going to have a DB folder. And in that DB folder we have schema Prisma. So let's open that up. Tell me again, what was your. Have you used Prisma before?

00:27:31 - Jason Lengstorf

I have used Prisma. I think it may have been the previous version.

00:27:38 - Anthony Campolo

Prism 1 and Prisma 2 are different and this is confusing. GraphQL was the original, as Chris points out there. GraphQL was originally a backend as a service, and then Prisma 1 was a GraphQL server thing that also would talk to a database. And Prisma 2, the Prisma we're now using, is an agnostic tool — not tied to a GraphQL API. It is simply a ORM query builder type.

00:28:10 - Jason Lengstorf

Have they steered into ORM now they're calling it Norm.

00:28:14 - Anthony Campolo

They finally caved.

00:28:16 - Jason Lengstorf

I'm glad because that's definitely what it is.

00:28:19 - Anthony Campolo

It's Norm. I'd always say it's like. Yeah, it's mapping your objects to relations. It's certainly not Norm though.

00:28:26 - Jason Lengstorf

Yeah. If you're not familiar with what an ORM is, it's just a tool that does this. So. Yeah, so now I have. And let's actually, let's pull up Prisma. It's Prisma IO right? Yeah. So this is Prisma if you want to check it out. And so Redwood is bundling Prisma as like a tool. So Redwood and I think this is worth just kind of calling out again. I think we talked about it a little bit. But Redwood is not new technology. Redwood is an assembly of existing technology to help you make good choices quickly. I guess that's not entirely true because the router is new, but largely it's an assembly of existing technology. React, Prisma postgres, things like that.

00:29:16 - Anthony Campolo

Yeah, it's about taking all of the best options that we have available. They looked at a lot of different clients. So they've looked at urql instead of Apollo Client, and they've looked at different form libraries instead of React Hook Form. They went through the process of vetting the React ecosystem and coming up with their own conventions around it. And what's interesting is there are other frameworks like Blitz or Bison that are creating full-stack frameworks around similar tools, but they may use React Query instead of Apollo, or they may use Chakra UI instead of Tailwind. So there's a lot of different kind of assemblages of these different tools. Just because there's been such an explosion of all this stuff and there's like a lot of really great, amazing technology, but it can be really hard to leverage it, especially for someone like me who's like fairly new and like having to learn GraphQL and AWS Lambdas and you know, your some ORM tool and like how to learn all those and put them together yourself.

00:30:23 - Anthony Campolo

Right. Like you'll never get anywhere. So they're basically trying to give you the power of all these modern technologies in a way that is more accessible for sure.

00:30:32 - Jason Lengstorf

Okay, so now I went ahead and installed the prismavscode extension so that this file would get syntax highlighting. It's a little easier to spot now. So up here we're defining a data source, then we have a generator and then we have a model. Now I can kind of figure out what this is. I'm assuming that the generator is the tool that we're going to use to build out how we interact with the database. And then the model, I'm making an assumption looks very similar to a GraphQL schema definition, but I can see that it's not exactly the same. There's some magic in here.

00:31:14 - Anthony Campolo

Yep, you pretty much got it. So it's like you said, it's a model. So you're going to be defining essentially your fields and then what the type of your field is. And then you can do some other stuff like we have auto incrementing ID there and you can set constraints like unique. And this is why, you know, we say it's an ORM. It's allowing you to just create like this JavaScript object. And so that's why it says Prisma Client JS, because you can create clients in different languages and that's like the thing that's translating your objects into your SQL. So we're going to, we're going to edit this and then we're going to run a command and we can actually look at the SQL it generates. Real quick though, I want to answer this question in the chat because this is something that, is something I'm very Interested in is Redwood JS4VUE. If it's a thing if it will be a thing. I don't think it is yet a thing. I absolutely think it will be a thing. I think if you look at the progression of these different libraries and frameworks, we have Meta frameworks and we have Meta.

00:32:14 - Anthony Campolo

Meta frameworks now, because you have something like Next is four years old, whereas Blitz is like a year old. But it's building on top of Next. So I think there's going to be something like Blitz in Vue that's going to build on top of Nuxt. And it's basically you just take Nuxt and slap an RM on it. It's like a bam. Like you're. You're half the way there, you know? So I think that it's kind of a question of how motivated you are to assemble the pieces yourself. And then once you've kind of done that, people can start to agree on what's the best way to do that, and then that gets formalized into a framework. It takes a long time.

00:32:50 - Jason Lengstorf

Meta. Meta.

00:32:51 - Anthony Campolo

Meta Framework's been in development for, like, two years.

00:32:54 - Jason Lengstorf

Yeah, yeah, yeah, yeah. And I mean, it. Like, I feel like there are expansions and contractions of the ecosystem, Right. For a long time, what we were seeing is that there were a lot of new JavaScript libraries focused on trying to create new functionality, right? And we saw this huge spread. And now what I'm seeing is that the libraries that are coming out are not so much about creating new technologies, but about organizing the thing. So we're almost seeing a contraction. We're moving down to a set of standards, and I suspect that we've got a little ways left before the next expansion. It kind of seems to be like a pyramid and then an inverted pyramid where we just go expand and then we contract, and then we expand and then we contract. And that pattern is we want to see what we can do. We get frustrated with the existing tools, so we build a bunch of new ways, and then we get frustrated because we can't decide what to use. And so we come up with conventions, and then we get frustrated with the conventions, and so we start all over again. I kind of like this.

00:33:54 - Jason Lengstorf

This, to me, feels like curation. I think that curation is a really important part of building anything. So what Redwood is doing is it's curating over creating and for tools. I think that's the right way to go about it. Don't invent things if you don't have to. Right. But yeah. Okay, so to get off my soapbox and get back to writing some code, what should we do next here. So I'm assuming we're going to mess with the model.

00:34:24 - Anthony Campolo

Yes. We're going to rename it to just Post instead of the example User model, because that's what we're going to be creating. We're going to be creating a post. You can leave the top line exactly the way it is and then change email to title and get rid of the unique constraint. Then change name to body. Then get rid of that question mark. Yeah. And then add one line and it's going to be created at one word with capital A for at.

00:35:00 - Jason Lengstorf

Yeah.

00:35:00 - Anthony Campolo

And then date, time, capital D and T and then at default and then now with parentheses at the end.

00:35:12 - Jason Lengstorf

Nice. And I don't know if anybody was paying attention, but it just auto suggested all of that. So if I were to do something like a slug and then I can I just hit control space and it pulled up my options so I can see what's in here and then I can come out here and I can hit command space and it shows me my options here. So that's very cool. And this is one of those things that I think is just a benefit of. I assume this is all written in typescript, so we get a ton of benefits through the tooling that way.

00:35:46 - Anthony Campolo

That's amazing.

00:35:48 - Jason Lengstorf

Now, I've defined a post and we know this is going to be the ID or the primary key. We know that it's going to default to an auto incremented number. Perfect. The date time defaults to. Now that makes sense. Title and body. I assume the question mark makes it optional, which is inverted from GraphQL where you need an exclamation point to make it required. This looks like it's required by default. Is that correct?

00:36:13 - Anthony Campolo

That's funny. I don't know the answer to that question. I don't know what the question mark does, but I would assume. I think that is correct.

00:36:19 - Jason Lengstorf

Yeah. I feel like I had a conversation with the Prisma team when they were doing this and that was a decision that they made was to make these fields required by default. And then if we wanted it to be optional like an empty body, you could add a question mark to make it optional. If I'm wrong, please correct me.

00:36:36 - Anthony Campolo

Chat. Yeah, this is interesting because Prisma is a huge chunk of Redwood, but you don't actually have to use Prisma. I've created projects with FaunaDB, and you lose all the nice ORM-ness that you get from Prisma, but you don't necessarily have to use it. It's not as tightly coupled as something like ActiveRecord is with Rails. I don't think anyone would ever use Rails without ActiveRecord, but that's not really the case here. Most people probably wouldn't use Redwood without Prisma, but I'm a weirdo, so I do.

00:37:09 - Jason Lengstorf

Yeah. Okay, well. And like Chef Brent is in the, in the chat. What's up, Brent, Good to see you. And he's saying, you know, I remember Rails, which. That is kind of what this is. Right. One of the things that people miss about JavaScript is the prescriptiveness and the done for you ness of Rails. I think that was what made Rails such a popular framing development tool at the time, because Ruby is great. Ruby on Rails was like, you're so fast, you're done so quickly. I've heard a lot of people independent of the Redwood community say they wish that there was a Ruby on rails for JavaScript. And it sounds like Redwood is attempting to fill that gap.

00:37:51 - Anthony Campolo

It is, and so is Blitz as well. I think it's really interesting to see the way they go about it because Redwood is all in on GraphQL, whereas you don't use GraphQL in Blitz. It's set up in what's called a no-API layer. So you're doing RPC calls directly into your backend, which is more of a monolithic idea. So I would compare Blitz a little bit more to Ruby on Rails, but Redwood is going for that same convention-over-configuration thing. I find it really interesting because it's also trying to be jamstacky and decoupled, and not as tightly integrated. So it's trying to give you the Rails experience without the same drawbacks that people find in Rails in terms of being a really tightly coupled monolith. That's why there's this weird tension in terms of how Rails-y it is versus how Rails-y it isn't. It's very interesting.

00:38:47 - Jason Lengstorf

Okay, sorry, I'm going to fall into all these rabbit holes the whole time, but in the interest of actually getting something working, we should probably keep moving. So I've got the post defined here and then you had mentioned we're going to use something else, right? Not SQLite.

00:39:08 - Anthony Campolo

For now, we're going to use SQLite because you'd want to develop locally with your SQLite database. And then when you're ready to deploy, you can deploy to Postgres. And if you write all your SQL in a generic way, SQLite and Postgres should be compatible in terms of the SQL you write. That's the idea here. What we're going to do now is you're going to enter command. These are going to be Prisma commands, although you're not really able to tell. It seems like a redwood command. But we're going to do yarn, RW and then DB and then save. This is going to. Since we changed our schema, Prisma. Now it's going to create a migration with the post model that we just created.

00:39:51 - Jason Lengstorf

Cool. It prints out the whole data model and then it says it just created a migration. Prisma shows us.

00:40:02 - Anthony Campolo

Here's the migration with another schema and a readme. And the readme will show you all the SQL that's generated.

00:40:09 - Jason Lengstorf

Nice. Okay, so let's take a look at that, actually. Cause that's very cool. So this. Oh, nice. Okay, so it's just showing us what's being done and what our changes are. Yeah, I like that a lot. And that's cool because this is the sort of stuff that you want

00:40:31 - Anthony Campolo

when

00:40:31 - Jason Lengstorf

you're doing database changes, but that a lot of times people don't do. So having this kind of record of what happened and when and what the changes specifically were.

00:40:41 - Anthony Campolo

Yeah, it eliminates a lot of room for error.

00:40:43 - Jason Lengstorf

Yeah, absolutely. That's nice. Okay, so now that we've got this, are we done? Is it a blog?

00:40:51 - Anthony Campolo

Almost. Very, very close. We're extremely close. We got two more commands. So yarn redwood db up instead of db save. Now that we generated the migration, this is actually going to apply the migration to our database. That SQL that we saw — those SQL commands are now being run. We now have a database with tables and all that stuff. The very last thing we need to do will be yarn redwood generate scaffold. Same as before, we generated pages and layouts. Now we do scaffold and then post. We're going to scaffold our post interface. This is going to create a whole bunch of stuff. This is like the famous Rails scaffold command where it kind of like this is the blog is.

00:41:41 - Jason Lengstorf

Oh, it just did everything. Okay, so I'm closing this going out here. We've got.

00:41:45 - Anthony Campolo

And let's not look at any of this yet. Let's go back into our browser

00:41:52 - Jason Lengstorf

here and here. Yep.

00:41:56 - Anthony Campolo

And then go to slash posts. And this should be fairly intuitive in terms of how you create a post. Pretty cool, right?

00:42:16 - Jason Lengstorf

I'm gonna I'm gonna test it.

00:42:19 - Anthony Campolo

Ooh, wow. This is done with tailwind.

00:42:27 - Jason Lengstorf

That is slick. Okay, and then I'm reloading the page. It's still there.

00:42:35 - Anthony Campolo

You can't really see because of how your CSS is set up, but you can scroll in that table to the right. So, like inside the table.

00:42:41 - Jason Lengstorf

Oh, yeah. Show, edit, delete, show. There's my post.

00:42:46 - Anthony Campolo

Okay, your route right now. See how it's slash one?

00:42:50 - Jason Lengstorf

Yeah, that is slick. That is really slick. I. I am. Yeah. Okay. Color me impressed. Now, a lot of decisions were made here. Like, I couldn't publish this, of course, because the chat would immediately troll the hell out of us by, you know, entering new posts. So this is all just the generated react component. So in here we've got all of these kind of editing posts. You hackers. You dirty hackers. Exactly that. Exactly that. You hackers. Okay, so, yeah. All right, so where should I look? I'm kind of poking around, but show me what I should actually be looking at.

00:43:36 - Anthony Campolo

Yeah, this is a great question. I wrote an entire blog post explaining all of this code. There's not really a good one place to look at as the access point.

00:43:44 - Jason Lengstorf

Where do I find that blog post?

00:43:47 - Anthony Campolo

This is on. Well, that's kind of funny. I need to actually. I have this very long blog series about RedwoodJS called. So just search A first look at Redwood js. Yeah.

00:44:05 - Jason Lengstorf

Hello, brotas. Thank you for the host.

00:44:08 - Anthony Campolo

Yes, that's the community forum. And this is kind of like in flux right now. I'm in the process of redoing this. So this thing is actually not really ready for prime time. It was like a month ago, but everything's kind of in flux right now. But it was part four. So if you look at part four, you see it. Basically I just explain each one. This is. This. Here's the code. Here's what it's doing. This is why I say this isn't really touched on in the tutorial at all. It's just there. You could poke around with it if you want. What we want to do next is we want to actually generate a cell that's going to do our data fetching for this. Then this is going to help us understand. Yeah. So we're going to do generate cell, and then it'll be blog posts, capital B and capital P. Yeah, exactly. This is going to generate our cell. And so go ahead and run that command. And this will be in our components folder, in our web folder.

00:45:17 - Jason Lengstorf

Okay,

00:45:20 - Anthony Campolo

then. Yeah. So what's happening here? And let's see Are you getting an error? Because I'm not sure you should be. Basically what happens now is depending on how your tooling is set up, sometimes It'll suggest what GraphQL query you want to be writing. Let's just look at the cell. Let me explain what's going on here. What's happening here is this is a Redwood concept that is a declarative way to do your data fetching. If you look at what's happening here, there's a query at the top. And if you've ever written a GraphQL query before, that should look totally understandable. You're querying for your blog posts and you're asking for the ID of your blog posts. Then what happens is you have these four different states that your data can be. And it can either be loading, it can be empty, it can have an error, or it can be successful, in which case we are using JSON stringify to render the blog post ID to the front page. What we want to do now is where it says blog posts, the three places we want to just change that to posts. One word, all lowercase.

00:46:34 - Jason Lengstorf

Like that?

00:46:36 - Anthony Campolo

Yep.

00:46:37 - Jason Lengstorf

Okay.

00:46:37 - Anthony Campolo

And then we're going to save that and then we're going to go back to our home page and we're going to import this blog post cell.

00:46:46 - Jason Lengstorf

Okay. What's the.

00:46:49 - Anthony Campolo

You don't need to do that. You don't need to do the brackets. You're just going to import that whole component. So blog posts sell is what it's called. Source components. Blog post cell.

00:47:03 - Jason Lengstorf

Wait a minute, how does that work? Because there is no default export here. So is Redwood doing some magic to bundle all that up?

00:47:12 - Anthony Campolo

Yeah.

00:47:13 - Jason Lengstorf

Okay.

00:47:14 - Anthony Campolo

It just works. All this just works.

00:47:17 - Jason Lengstorf

Okay. And then do I just like drop it straight in?

00:47:22 - Anthony Campolo

Yep. Self closing tag.

00:47:25 - Jason Lengstorf

Interesting.

00:47:30 - Anthony Campolo

That's fascinating.

00:47:32 - Jason Lengstorf

Okay.

00:47:35 - Anthony Campolo

Yeah. This is where it all comes together.

00:47:38 - Jason Lengstorf

So that magic, I'm not gonna lie, puts me a little bit on my back foot. Like, how do I debug that? I don't know what to do. You just have to know it's gonna run this query, these are the potential states it's going to hit, and it's going to build the component that shows the appropriate state.

00:48:01 - Anthony Campolo

So. Yeah, so basically anytime it is able to tell whether you're getting the error or whether you actually are getting a successful state, whether you have like a 200 or 400 or anything like that. This is why this framework took two years to build. I get you understand they call it the magic. It's just people spending the time to figure out how this stuff works. But if you go to the query at top, leave everything like that on the homepage.

00:48:27 - Jason Lengstorf

Where was I here?

00:48:28 - Anthony Campolo

Yeah, go back to your blog post cell and then bring it all in. So add title body created at. Then let's just see what that changes.

00:48:37 - Jason Lengstorf

I wonder why it's not pulling that in for me. It feels like it should. I probably just need to configure something.

00:48:43 - Anthony Campolo

But regardless, boom, now we're getting everything. And what we can now do is we can style this, or not necessarily style, but we can turn it actually into a component. Yeah, exactly. Right there where it's returning. You can spit out the article, key on post ID, and then post title, post createdAt, post body, and just kind of do all that.

00:49:10 - Jason Lengstorf

So we'll do one of these and then we'll get a key equals post ID and we'll do a link, which means I need to import that, but it'll auto import it for me. Good, good. And then I'm going to. Oh, here's a question. How do I link to a post? Because it's not gonna work with that routes thing.

00:49:36 - Anthony Campolo

Yeah, there's a way to do this. I don't know how to do it offhand like right now, but there's definitely a very simple way to do this in terms of setting your.

00:49:45 - Jason Lengstorf

And I'm realizing now that we haven't actually built a post page. So how about I don't do that just yet? So I'm going to. Instead, we'll make an H2 with the post title and then we'll do a div.

00:49:57 - Anthony Campolo

Er.

00:49:57 - Jason Lengstorf

It's just a single. That's just plain text. Right. Okay, I'm gonna set it as a paragraph. We'll do dangerously set innerhtml and we'll make it the post body. And then finally down here, we will save created at. Post created at.

00:50:22 - Anthony Campolo

Okay.

00:50:26 - Jason Lengstorf

Did I break it? I broke it.

00:50:28 - Anthony Campolo

Possibly. Yeah. So try getting rid of the dangerously set innerHTML part and just do a plain post body. Regular post body. Try that.

00:50:51 - Jason Lengstorf

Where's my error? No error.

00:50:56 - Anthony Campolo

So let's see, it might be the way we're mapping over the posts. So can I just shoot you some text and you can like copy paste it?

00:51:09 - Jason Lengstorf

Yeah. Send it to me as a Twitter DM though, because we're between two computers. Yes, and while you're doing that, I just realized I forgot to shout out the sponsors today. So let's do that really quickly. Today's show is being live, captioned as always by White Coat Captioning. We've got Rachel in helping us out today. You can see that over@lwj.dev live. And the captions are being provided by our sponsors, Netlify, Fauna Sanity and Auth0. Thank you to all of them for making this show more accessible to more people. So make sure you check that out again. It is lwj.devlive and we forgot to return this. No, we didn't. Oh, we forgot to return this. Oh, my goodness.

00:51:55 - Anthony Campolo

Yeah, I knew we were making an error somewhere in the mapping.

00:51:58 - Jason Lengstorf

Thank you, Chat. Hey, look at it go. First try, right?

00:52:07 - Anthony Campolo

Viewers are so talented. Sorry, what was that?

00:52:12 - Jason Lengstorf

Okay, so now we've got. Yeah, we're good. We've got that running. We go to posts and create a new one. Did that just work? Save that, go back home. There we go.

00:52:30 - Anthony Campolo

So there's your blog.

00:52:32 - Jason Lengstorf

That's nice. We've got a blog. This is slick. We can see how quickly setting this up with another service would have taken significantly longer than the one hour. Well, less than one hour given that we've been screwing around and I took 10 minutes to get started, but what, 45 minutes worth of work and we have a fully functioning blog with a database. And this doesn't not going to win design awards, but this is certainly functional. That's pretty impressive. I can see the appeal of this.

00:53:07 - Anthony Campolo

Yep. So the next place that we could go, probably where we're at now with time, we won't build out the contact form. But if you follow the tutorial, basically what happens is it walks you through creating a contact form that is like name, email and a message and you set some validation and if you open your thing all the way. So you can kind of see that the sidebar.

00:53:33 - Jason Lengstorf

Oh, sidebar. Got it.

00:53:34 - Anthony Campolo

So check on the left. We have done Everything up to SideQuest, I think. Okay. Yeah. So then you have routing params and that's where you can get into figuring out how to do your linking to your different pages that are created from your blog posts. And then you have everyone's favorite thing to build. We make lots of jokes about forms here. And so this will walk you through how to create a contact form. We use React Hook form as like the form layer underneath because they decide it was the most form shaped of all the forms that were available. Okay. I have no idea why they picked React Hook form, but that's like, you don't have to use it. You can just write straight HTML forms if you want to, but you get like a lot of nice error validation and stuff like that out of the box if you're using react hook form.

00:54:26 - Jason Lengstorf

That makes sense. Okay, well, cool. I think We've got about 30 minutes left, right?

00:54:33 - Anthony Campolo

Yeah. That's plenty of time to deploy the front end and the backend.

00:54:36 - Jason Lengstorf

Let's do it. I'm ready. So if I want to deploy, I'm assuming I need to stop this server. And now I have a bunch of code. Let's open it in VS code. It's a little easier to see that way. Here I have all of this and I can't get my. There we go. So this is everything here and I can just start kind of adding certain things. So there are things that I know we need. Like if I want to add my web folder. Right. And then. Hold on.

00:55:07 - Anthony Campolo

Oh, so there's just a command that you need to enter that's going to set up all your deploy.

00:55:13 - Jason Lengstorf

Come on, don't. Really?

00:55:16 - Anthony Campolo

Yeah.

00:55:16 - Jason Lengstorf

All right.

00:55:17 - Anthony Campolo

Okay.

00:55:17 - Jason Lengstorf

All right. Redwood.

00:55:19 - Anthony Campolo

Now what? Yarn Redwood. Generate. Deploy netlify.

00:55:27 - Jason Lengstorf

Okay.

00:55:27 - Anthony Campolo

It's going to create a netlify toml. Okay, so check that out.

00:55:33 - Jason Lengstorf

Let's go up here. Netlify toml.

00:55:38 - Anthony Campolo

And so it gives you your command, publishes to a disk like very standard, kind of like build that you're going to do on netlify.

00:55:47 - Jason Lengstorf

Gotcha.

00:55:47 - Anthony Campolo

Okay, now you're going to want to actually commit this and get this all into a repo. Your whole project exactly the way it

00:55:54 - Jason Lengstorf

is right now and just all of it.

00:55:56 - Anthony Campolo

Actually, there's one more thing. Let's just do this. Now go to your schema prisma. This is where we have flip SQLite to Postgres.

00:56:04 - Jason Lengstorf

Got it.

00:56:06 - Anthony Campolo

Then that should be all the configuration we need to do. Yeah.

00:56:11 - Jason Lengstorf

Bingo bango, bingo bango bongo.

00:56:14 - Anthony Campolo

All right, get that sucker up on a repo, get your netlify connected to it, and you'll deploy it and it'll have all your build commands there. And yeah, that should be fairly, fairly easy to do.

00:56:26 - Jason Lengstorf

Okay,

00:56:28 - Anthony Campolo

well, you're asking there, Ben. Will this prevent people from going which route? There's a lot to talk about in terms of deployment. So if we're asking about other ways to deploy, then we can definitely get into that.

00:56:41 - Jason Lengstorf

Going to the new post creation route. Oh, no, I don't think it will. So I think when we deploy this, you all control the heck out of us.

00:56:50 - Anthony Campolo

Well, we're going to set up an actual database that's going to have an environmental variable that we're going to link up to. If we hide that, then they can't troll us.

00:56:59 - Jason Lengstorf

Okay. So I'm going to GitHub, repo, create, learn with Jason. I switched over to the actual GHCLI as opposed to hub and I'm still learning it. So I think this works. Let's find out.

00:57:14 - Anthony Campolo

Yeah, this is where the most potential for error comes in when I'm doing stuff like this live.

00:57:21 - Jason Lengstorf

Done. Okay, so now I can git push upstream origin main. Good, good. And. That's the wrong tab. You're not helping.

00:57:43 - Anthony Campolo

Here we go.

00:57:43 - Jason Lengstorf

All right, so this is the code that's up and running here and now. It didn't it configured for netlify deployment, but it did not deploy to netlify. Is that correct?

00:57:55 - Anthony Campolo

Correct. Now we need to actually go into our netlify account and link the repo. Okay.

00:57:59 - Jason Lengstorf

So I can do that also from the command line. Yeah. So I'm going to netlify init and we want to create and configure a new site. I'll put it on my team and we'll call this let's Learn Redwood js.

00:58:18 - Anthony Campolo

I've never done this from the command line before. I always just go there. Their dashboard.

00:58:23 - Jason Lengstorf

Okay. And now it's gonna get overridden by everything, but I'm just gonna go ahead and type that one in to make sure it doesn't explode on us. Okay, so now that we've got that open in the right window. Always the wrong window. Here, over here. This is the one. So now we've got our site building, but we're missing that database URL. This is going to fail.

00:58:50 - Anthony Campolo

Yes, it's not going to fail. It's going to generate our page and it's going to give us an error because our cell knows how to do error handling.

00:58:58 - Jason Lengstorf

Okay. All right, I'll take that.

00:59:00 - Anthony Campolo

So your front end is still going to work. It's just not going to render any posts. Gotcha. But what we want to do now is. Do you have a Heroku account?

00:59:09 - Jason Lengstorf

I do.

00:59:10 - Anthony Campolo

Yeah. So we'll create a Heroku and just provision a postgres database on the free tier.

00:59:15 - Jason Lengstorf

Okay, let's see how quickly I can get into Heroku. Let me pull this off screen. Actually, I think I have it logged in over here. Yes, I do. So I'm just gonna pull over this tab and we're gonna create a new app. Okay. And do I need anything else here?

00:59:47 - Anthony Campolo

So now you're going to go to Resources. This is all fine. You don't need to touch any of that and then find more add ons on the right.

00:59:56 - Jason Lengstorf

Is it the Postgres here?

00:59:58 - Anthony Campolo

Postgres? Yeah, that's the one.

01:00:02 - Jason Lengstorf

Free. So we can set this up on a free. Now the limitation with a free postgres is like 10,000 records. So for a lot of folks that'll be enough, depending on what you're planning to use this for. I know that because I just hit that limit on another account.

01:00:21 - Anthony Campolo

Yeah, this is going along with this whole kind of like serverless idea is that everything starts on the free tier and it's only once you start hitting a certain limitation of usage do you actually start getting. Do you actually start getting charged. And for anyone who's just like building these projects and is just trying to learn this stuff or get things spun up, it's like you're never gonna hit a limit. And then for people who are even building companies with this, if they architect it correctly, they can get a lot for really cheap as well.

01:00:47 - Jason Lengstorf

Now I need to pull some settings, so I'm going to do this off screen.

01:00:50 - Anthony Campolo

Yeah, you're going to want to grab the environmental variables, I don't think. You don't have to actually go into this part. This is still going to be in your regular Heroku dashboard, not really your postgres dashboard. And then it'll be under Settings, I think Settings. And then. Yeah, so then you'll. That's what you want to take off screen, where you're going to reveal your config variables and then you're going to grab that and plug it into your environmental variables in netlify.

01:01:14 - Jason Lengstorf

Got it?

01:01:17 - Anthony Campolo

Yeah.

01:01:17 - Jason Lengstorf

Yeah. And this is the part that failed, right? It said, oh, oh, yeah, because we don't have. Got it. All right, so then I'm going to come back here, go to my site settings and then we'll pull up the environment variables. And then let's see. Is my thingy working? It is. So I'm going to drop that in here.

01:01:35 - Anthony Campolo

Whoa.

01:01:35 - Jason Lengstorf

And we'll go database URL. Right. That was what we called that.

01:01:40 - Anthony Campolo

I believe so, yes.

01:01:42 - Jason Lengstorf

So I'm going to save that and now we can just start it again, retrigger the build. All right, so that's basically done. So I'll come out here instead and let's trigger a new deployment.

01:01:58 - Anthony Campolo

Then once that's done, that should be it.

01:02:02 - Jason Lengstorf

Okay.

01:02:03 - Anthony Campolo

Did everything correctly? Used to also have to set the flavor of Linux that it was because netlify had some weird thing or it was like Red Hat Linux or some other version of Linux and that was fixed in the most recent version of Prisma. So you don't have to worry about that anymore. Which is great because worrying about flavors of Linux is the least jamstack thing I could ever think of.

01:02:22 - Jason Lengstorf

Yeah. Just to repeat this for anybody who is wondering how you would do this with Heroku. Once I created this database, if I click this button, it just gives me there's an environment variable called databaseUrl and then a value. I just copy pasted that value over to netlify. So that's all we need from Heroku is that step. We went to resources, we searched for Postgres here, got Heroku, postgres, went to Settings, click this, reveal config fares and then we move that over into our deploy settings on netlify. So nice and nice and slick. I'm into it. So I think what happened, we didn't wait for netlify to finish the first build, so we didn't get the cash from that one for this one. So we're waiting for it fresh this time. So, you know, time for coffee, I guess. Someone want to play some elevator music for us? Thank you, mickey.

01:03:39 - Anthony Campolo

I make some jokes about the build logs in my blog post where it's just like logs, logs, logs. Like, let the logs wash over you and through you.

01:03:58 - Jason Lengstorf

Yeah. The environment variable masker is something that Sarah Drasner put together because generally speaking I find that when something is useful on the Internet, Sarah Drasner had a hand in it. That tends to be like a good rule of thumb.

01:04:12 - Anthony Campolo

Yeah, that's great. So it's a Chrome extension.

01:04:14 - Jason Lengstorf

It is, yeah, it's a Chrome extension and Ximena posted a link to it. So let me grab that link.

01:04:22 - Anthony Campolo

Yeah. Because that's something I run into doing live streams for sure. So that's like going to be very handy.

01:04:27 - Jason Lengstorf

Yeah.

01:04:28 - Anthony Campolo

Sarah, this is the tool.

01:04:30 - Jason Lengstorf

It's called netlify Masker. You can search for it. I will include a link in the show notes as well. All right, so we got through. No errors this time. There's our build command.

01:04:40 - Anthony Campolo

I think it's still building.

01:04:42 - Jason Lengstorf

It's working on our functions.

01:04:43 - Anthony Campolo

Yep.

01:04:44 - Jason Lengstorf

And that hopefully will have nice somewhat

01:04:48 - Anthony Campolo

we can kind of talk about as this is going on is like other ways to deploy this. So you know, some people know this, some people don't. Tom Preston Warner was like a very early investor in netlify and has kind of been involved in this whole thing since the beginning and now he's on the board and Redwood and netlify, they're very tightly integrated. Redwood was built with netlify as the original deploy target in mind. But with that said, it's not meant to only work with netlify. Obviously lots of people talk about lock in and worries about this. Sure. This is very much about enabling the ecosystem to build whatever we want. You can deploy this on Vercel just as easily as you have here. See how it says empty? Because it's not going to carry over. It blew away our old data because it was.

01:05:36 - Jason Lengstorf

Because it was SQLite.

01:05:38 - Anthony Campolo

Yeah. So now we're going to go back to our posts route in our deployed app and just create some new posts.

01:05:44 - Jason Lengstorf

Okay, so here's chat where you're going to be able to troll us mightily. Let's see. This is a RedwoodJS powered blog. Okay. Now remember chat, keep it pg13 or else I'm gonna have to take away your fun.

01:06:08 - Anthony Campolo

Yeah, so yeah, you're right. I guess they can still troll us here. There is an authentication part.

01:06:14 - Jason Lengstorf

What up Chat.

01:06:17 - Anthony Campolo

But yeah we, so we skip the authentication part. Use like netlify identity and you can you implement like a login form and yeah authentication there. So this would be the kind of final layer. This is the very last part of my multi part blog series is explaining the authentication layer. And you can also do like magic link. You do auth0 as it says there's a. If you go to the cookbooks on the left there's a more complicated RBAC role based authentication cookbook. So this is. David T has done a lot of really fantastic work on this. So if you want to build out real more sophisticated apps with authentication, there's a lot of stuff in there for you.

01:06:58 - Jason Lengstorf

Very cool. Yeah, I mean this is some pretty powerful stuff. Right. Like there's a lot of potential here. A lot of things that we can build that are very cool and very powerful and I love that this makes it so just quickly approachable. Right. Like that's, that's a lot of power. I also like turtles.

01:07:17 - Anthony Campolo

Wow. Fizz the buzz. It's good stuff.

01:07:21 - Jason Lengstorf

I always appreciate your wholesomeness. Chat. It's, it's always. It's just good. I just like it. I like you guys, but yeah, okay, so I'm into this. This is fun. So from here I think this is probably as good a place as any to stop because we can't go too much further without running out of time. So where should someone go if they want to take further steps? We've got a list. So we've got a link to your first look at Redwood js. We'll be on the lookout for your next version of that. We've got the tutorial, we've got your Twitter. So I'm gonna make sure that everyone goes and follows you on Twitter.

01:08:00 - Anthony Campolo

I used to have it as anthonyCampolo with a lowercase a, like camel case. But I recently learned the term screaming Snake case.

01:08:07 - Jason Lengstorf

Screaming Snake case. That is one of my favorites. Yeah, I did. I actually did some screaming Snake case fan art. Hold on 1, 1 second. I find my on here from Syntax FM.

01:08:21 - Anthony Campolo

They mentioned it like a week or two ago.

01:08:24 - Jason Lengstorf

This is my screaming Snake case fan art that I did. But yeah, so, okay, so we've got your Twitter. Where else should we go? Where's a good. Oh, sorry.

01:08:39 - Anthony Campolo

You did a whole like, where my writing really is. So it's linked on my Twitter, but it's also, it's the same handle, ajcwebdev. I got the same handle everywhere.

01:08:50 - Jason Lengstorf

ajcwebdev. Okay, so here is a collection of writing.

01:08:58 - Anthony Campolo

Yeah. And so you'll find like 20 or so articles about like GraphQL and Redwood and all this kind of stuff. And I've written like stuff about svelte, written stuff about nuxt. I've written about like, you know, the cloudflare, durable objects. I mean, all sorts of stuff.

01:09:12 - Jason Lengstorf

Very, very cool. Well, yeah, so, I mean, this is wonderful. I feel like this is a good testament to the power of RedwoodJS that we finished 15 minutes early and we built a lot. We created a Postgres database. We hooked that up to a website. We configured PRISMA to act as an ORM over our Postgres database to give us a TypeScript auto completing GraphQL API to use. We were able to stand up routing. We were able to get our pages configured. We were able to create blogs. So create a UI admin for creating our blog posts. We were able to pull those blog posts and write a custom display logic for it. And we were able to deploy all of that to Netlify. And that's a lot of work. That's a huge amount of stuff that we were able to accomplish in a very short window.

01:10:06 - Anthony Campolo

And I think the real testament is that it is hopefully understandable at every point along that journey, what you're doing and why you're doing it and how it fits into the larger picture. That was what really got me so fired up about this, is that it made sense to me in a way that learning all this other modern web development stuff didn't. Wasn't clicking. I couldn't quite figure out how to fit the pieces together in a way that would actually get the friggin thing to just deploy and work. And so getting to be brought along on this journey of this thing being built in a way where you're not just copy pasting stuff like actually understand what the code is doing. And people are going to hit different limitations in terms of that understanding based on how well they know things like GraphQL or GitHub or Netlify or the command line itself. It's not set up for someone going from totally from zero, but as someone starting almost from zero.

01:10:59 - Jason Lengstorf

Yeah, well, and I think like, you know, redwood is not going to be everybody's speed because it falls on a spectrum of letting decisions get made for you so that you can be quickly productive or making all of your own decisions so that you have a deep rooted understanding of what's going on. And we all fall somewhere on that spectrum, you know, and redwood is not by any means the most prescriptive option. It's just further on that spectrum than other choices out there. But what I think is really interesting about this is it gets introduced on the spectrum depending on the project that you're going to do. If I'm working with a team and that team is not a group that I've had a lot of time to build a shared language of how we write code or how we think about data or anything like that, something like Redwood is a great way to immediately create shared language. We know that you're going to create cells to interact with data. We know that you're going to use the generate command to build new code. We know that the router is going to work like this.

01:12:02 - Jason Lengstorf

There are a lot of opinions that have already been established. It's sort of like having a really strong ESLINT file. It's, you know, you're saying we've decided as a team that we're going to do things like this and then you don't need a code cop to go in and police that because the tools are making those decisions for you. That can create a lot of really good team unity. If you're an individual, then it's just down to taste. Do I want to have to think about how this is constructed? Is that fun for me? Am I learning or am I trying to get something done? And I just want to ship it really fast and depending on where you land on the spectrum for today's given project, and I'll tell you, I land all across that spectrum depending on the day of the week and how busy I am. And I can definitely see this being a good, really, really valuable tool when we just need to get something out the door when we want something that we know is going to work, that we know has that error handling, that we know is built on tools that are going to function well together.

01:13:00 - Jason Lengstorf

That seems like a really strong. This seems like a great starting place. So with that being said, do you have any parting words for the chat today?

01:13:12 - Anthony Campolo

Just, like, thanks for having me. Thanks for giving me a chance to talk about Redwood and why I'm so passionate about it. I really enjoy getting to introduce people to it. And it's really cool getting to do these YouTubes because you're a very experienced developer and you know how all this stuff works. So I figured you would pick this stuff up pretty quickly. For someone like me, kind of learning it as I went, it took me maybe a month or two to make it all the way through this whole tutorial. That's why I wrote the article series as I was going. The article series is basically me documenting my journey through doing the tutorial, and it's what I've been able to go back to now to really help me continue to refine these things. I've been kind of rerunning it. Like I said, I'm kind of redoing it and making it compatible with the current version. But I just recommend people check out the forums and check out the Discord.

01:14:05 - Anthony Campolo

Like, it's a really awesome community. I've had a ton of help from the core team, and some of that actually isn't going to be officially announced until Thursday. But I can give you the scoop: I'm being invited onto the core team as a core member now.

01:14:19 - Jason Lengstorf

Oh, cool. Congratulations.

01:14:21 - Anthony Campolo

Yeah.

01:14:23 - Jason Lengstorf

And I just dropped a Discord link if you want to join. The Discord.

01:14:28 - Anthony Campolo

Yeah.

01:14:29 - Jason Lengstorf

Geez, that's very cool. And I saw that you're on the hunt for work, so somebody hire this guy. But yeah, with that being said, a little extra shout-out for our captioning today, provided by White Coat Captioning. Thank you so much. That's made possible by the sponsors Netlify, Fauna, Sanity, and Auth0, all of them kicking in some cash to cover the cost of captioning, which makes the show more accessible to more people, which I very much appreciate. Also, make sure you take a look at the schedule. We've got Nate, you asked for Vue, I got Vue. We're not doing an episode this Thursday. I'm taking it a little easy during the holidays, right? So we're not doing an episode this Thursday, but we're back next Tuesday with Ben Hong. Ben Hong just joined my team at Netlify. He's also a core contributor on Vue. He is brilliant and funny, and we're gonna learn a lot. We're gonna do an intro to Vue 3. I'm super, super pumped. We're actually going to do a whole separate episode in January about the Composition API.

01:15:34 - Jason Lengstorf

So we're going to do two episodes.

01:15:36 - Anthony Campolo

I talked about the Composition API for Vue NYC yesterday.

01:15:39 - Jason Lengstorf

Oh, nice, nice, nice. Yeah, yeah. I'm super pumped about that. We've also got Emma Bostian coming back to the show. We are going to make fun of her taste in tacos, and I'm really looking forward to that. I've got a few more that are going to get added to the schedule soon, so keep your eyes peeled, but definitely mark your calendars. Remember, we have a Google Calendar that you can join that I think is here, not there, here. I don't know. Schedule. Oh my God. Does anyone remember my... I forget what the command is to share the calendar. Whatever.

01:16:14 - Anthony Campolo

We'll.

01:16:15 - Jason Lengstorf

We'll find out later.

01:16:16 - Anthony Campolo

Is it a Twitter command?

01:16:17 - Jason Lengstorf

I don't know. It's a twitch chat command that I've forgotten. But yeah, so

01:16:24 - Anthony Campolo

[unclear]

01:16:25 - Jason Lengstorf

Yeah, I think we've got a calendar here. This is the calendar. So let me copy that link address. We are gonna drop that in here. Thank you very much to JChaps for finding that for me. And I think that's as good a place as any to call it done. So, Anthony, thank you again for taking the time to hang out with me today and teach us all about Redwood. This was a lot of fun, chat. Thank you so much for hanging out. It is always a pleasure. I love that this is a wholesome chat where we can just leave an unsecured database open, and nobody does anything terrible. Stay tuned. We're going to raid, and we will see you next time.

On this pageJump to section