
Integrate APIs with StepZen GraphQL Studio - Frontend Horse
Anthony Campolo demos integrating multiple APIs into a unified GraphQL API using StepZen, showcasing its capabilities for simplifying backend dev
Episode Description
Anthony Campolo demos StepZen, a GraphQL API gateway that unifies REST APIs, databases, and GraphQL endpoints into one queryable graph.
Episode Summary
In this final Frontend Horse live stream of 2021, host Alex Trost is joined by Anthony Campolo to explore StepZen, a hosted GraphQL API gateway that lets developers combine multiple backend data sources into a single GraphQL endpoint. The session begins with a boilerplate project returning mock data, then progressively layers in real data sources: first the JSON Placeholder REST API for user data, then the Rick and Morty GraphQL API for character data, followed by a Supabase Postgres database with both read and write capabilities. Anthony then walks through setting up a RedwoodJS full-stack app with Prisma and Railway's Postgres hosting, deploying it to Netlify as a serverless function, and feeding that custom GraphQL API back into the StepZen project. Throughout the build, Anthony explains how StepZen's custom directives — @rest, @graphql, @materializer, and @sequence — eliminate the need to write resolvers manually. The stream concludes with a tour of StepZen's GraphQL Studio, which offers pre-built integrations for services like Google Natural Language, Dev.to, Spotify, and Pokémon, demonstrating sentiment analysis on text input and showing how queries can be chained together for more complex use cases.
Chapters
00:00:00 - Introduction and Stream Setup
Alex Trost opens the final Frontend Horse live stream of 2021 and welcomes Anthony Campolo, a longtime community member and StepZen developer advocate. After some audio adjustments and shoutouts to chat regulars, Alex thanks StepZen for sponsoring the recent holiday charity show that raised $10,000 for Team Seas and removed 10,000 pounds of trash from the ocean.
The conversation sets the stage for the day's topic: a hands-on walkthrough of StepZen, which Anthony describes as a GraphQL API gateway. He explains the core concept — taking different backend services like REST APIs, databases, and other GraphQL APIs and unifying them into a single queryable GraphQL endpoint, comparing it to similar ideas like Gatsby's content mesh and The Guild's GraphQL Mesh, while noting StepZen's fully hosted deployment model.
00:07:28 - First Steps with the StepZen Boilerplate
Anthony guides Alex through the cloned StepZen boilerplate project, explaining the index.graphql entry point and the test.graphql file that defines basic GraphQL types including strings, integers, floats, JSON, and dates. They run stepzen start to deploy the endpoint and open the local GraphiQL editor to execute their first query against mock data.
The pair walks through fundamental GraphQL concepts like type definitions, field naming conventions, the non-nullable exclamation mark syntax, and how StepZen provides a live deployed endpoint rather than running everything on localhost. Anthony explains that the GraphiQL interface runs locally but queries a real hosted endpoint on StepZen's infrastructure, and mentions using tools like Insomnia or Postman to verify the endpoint independently.
00:21:24 - Connecting the JSON Placeholder REST API
With the mock data working, they move on to connecting a real data source by creating a users.graphql file that defines a User type with id, name, username, and email fields. Anthony introduces StepZen's @rest directive, which maps the REST endpoint to the GraphQL query automatically without requiring hand-written resolvers.
Alex queries the endpoint and gets back real user data from the JSON Placeholder API. Anthony explains that unlike Apollo Server where developers must write JavaScript resolvers to transform REST responses into GraphQL-compatible shapes, StepZen handles that mapping automatically based on the schema definition. He also mentions StepZen's JSON-to-GraphQL conversion tool that can auto-generate type definitions from API responses, making the process even more accessible for beginners.
00:30:03 - Adding the Rick and Morty GraphQL API
The next integration uses the Rick and Morty GraphQL API to demonstrate StepZen's @graphql directive for stitching in external GraphQL endpoints. Anthony walks Alex through creating a Character type and a nested Characters type that handles the API's paginated response structure, explaining how GraphQL types can contain fields that reference other types to form a graph.
A viewer asks whether the directives are StepZen-specific, and Anthony clarifies that @rest, @graphql, and all StepZen directives are custom additions built on GraphQL's spec-level directive capability, while the types, queries, and mutations remain standard GraphQL. They successfully query character data alongside the earlier user data, demonstrating how multiple data sources coexist in a single unified graph.
00:38:10 - Integrating a Supabase Database with Mutations
Anthony introduces database connectivity by having Alex spin up a new Supabase Postgres database. He explains Supabase's value proposition as a Firebase alternative built on open source technology, and briefly discusses the broader database landscape including Railway, PlanetScale, FaunaDB, and CockroachDB.
They create a books table, set up a config.yaml file for secure API key storage, and build a books.graphql schema that includes both a query and a mutation using the @rest directive with POST method and a post body. Alex successfully creates a book entry called "Old Man and the Sea" through the GraphiQL mutation explorer, verifies it appears in the Supabase dashboard, and then queries it back — demonstrating full read-write capability through StepZen's unified endpoint.
00:56:41 - Building a RedwoodJS Backend with Railway and Netlify
The session shifts to creating a custom GraphQL API using RedwoodJS, a full-stack JavaScript framework that bundles Prisma as its ORM. Anthony explains how Prisma translates JavaScript into SQL and manages database migrations, while Alex connects a Railway-hosted Postgres database to the new Redwood project.
They define a Post model in Prisma's schema, run a migration to create the database table, and use Redwood's scaffold generator to produce a full admin UI for managing posts. After deploying the Redwood app to Netlify as a serverless function, they wire the resulting GraphQL endpoint into the StepZen project, successfully querying posts alongside all previously connected data sources in one unified graph.
01:24:46 - The Mega Query and Linking Data Sources
With five data sources connected — mock data, JSON Placeholder users, Rick and Morty characters, Supabase books, and Redwood posts — Alex runs queries across all of them through the single StepZen endpoint. He reflects on the practical value this would have had at his previous agency job where combining review data, product information, and location services from different APIs was painful.
Anthony introduces two additional StepZen directives: @materializer for linking types across different APIs, and @sequence for chaining queries so the output of one feeds into the input of another. Alex draws parallels to real-world scenarios like connecting Shopify products with CMS content, inventory data, and review services, recognizing that StepZen's approach goes beyond simple aggregation to enable meaningful data relationships across backends.
01:31:26 - Exploring StepZen's GraphQL Studio
Anthony demonstrates StepZen's GraphQL Studio, a browser-based tool offering pre-built integrations for popular APIs. They connect the Google Cloud Natural Language API and run sentiment analysis queries, testing phrases like "I feel happy" versus "I feel sad" and observing polarity scores, which sparks an amusing exploration of how Google rates various emotional statements.
They also briefly explore the Dev.to API integration and browse other available connectors including Spotify, Pokémon, Twitter, Unsplash, and combined templates like outdoor dining search using Google Maps, OpenWeather, and Yelp. Anthony explains that all these integrations generate the same GraphQL schemas they'd been writing by hand, and projects can be exported and extended with custom code.
01:48:19 - Wrap-Up and Year-End Reflections
Anthony summarizes StepZen as "the front of the back end" — a tool that gives frontend developers access to backend capabilities and helps them become more full-stack. He notes that any framework capable of making a fetch request can integrate with a StepZen endpoint, and points to existing tutorials for React, Vue, and Svelte frontends.
Alex closes the final Frontend Horse stream of 2021 by thanking the community for a remarkable first year of streaming that grew from casual experiments into a thriving Discord community and culminated in a charity fundraiser. Anthony plugs StepZen, RedwoodJS, and his podcast FSJam, which covers many of the tools and projects discussed during the stream. The pair signs off wishing everyone a happy holiday and promising to return in January 2022.
Transcript
00:05:01 - Alex Trost
Hello and welcome to the last Frontend Horse live of the year. Happy 2021. I am so thrilled to be able to end it with our good friend Anthony. Anthony, it is so great to have you on, man. How's it going, buddy? I know you just hopped off from a different stream. You are in demand, my friend. How are you doing?
00:05:27 - Anthony Campolo
I'm feeling great. I'm really happy to be here. It's an honor to get to be on the show with you. I've been watching it for a while, been hanging out in the Discord for a while. So if you're a Frontend Horse regular, you've probably seen my little cartoon avatar popping around. Yeah, just super excited to get a chance to play around with some cool GraphQL stuff with you and get to show the audience what we're doing here at StepZen.
00:05:52 - Alex Trost
Yeah, it's awesome, man. And yes, you've been in the Discord as far as I can remember. I don't remember a time in the Discord without Anthony. I think you might have come in like the first or second week or something. Oh yes, thank you, Ben. I do need to —
00:06:08 - Anthony Campolo
Yeah, it was probably after maybe a month or two. When did the Discord actually start?
00:06:12 - Alex Trost
Hold on one sec. I just got — I have to boost you. We didn't get a chance to do a sound check. Yeah, I need to figure this out on the fly. Unfortunately. Thank you for saying that, Ben. I can drop myself. There we go. Gain. We're boosting that. All right, cool. Can you give me something, Anthony?
00:06:37 - Anthony Campolo
Yes. Check, check, check. One, two.
00:06:39 - Alex Trost
Let me go a little bit higher with you. Almost there, almost there. All right.
00:06:43 - Anthony Campolo
Okay. Hello.
00:06:45 - Alex Trost
Perfect. All right. That seems pretty good. All right. Also, StepZen, which is what we're going to be getting into, was one of the five big sponsors of our holiday show that we did on Friday, which helped raise $10,000 for Team Seas and removed 10,000 pounds of trash from the ocean. So thank you to you and to StepZen for sponsoring that. I really appreciate you guys coming through for that.
00:07:26 - Anthony Campolo
We're happy to do it.
00:07:28 - Alex Trost
Yeah. So StepZen is now an integral part of the Frontend Horse stream and the Frontend Horse community. Let's get into it. First off, what is StepZen? What are we even going to be doing today?
00:07:45 - Anthony Campolo
Yeah, it's hard to give a succinct definition of what StepZen is without using a couple of terms you need to define first. I would call it a GraphQL API gateway. An API gateway is something that sits between different services. So if you want to talk to a database, you'll usually do it through an API gateway — that's a very common pattern. AWS has a service literally called API Gateway, and that's usually a REST API. REST APIs have their own bespoke way of handling resources and mutations and stuff like that. Whereas GraphQL is a standard query language for APIs. So explaining StepZen requires explaining GraphQL also. But I know you have a little bit of GraphQL experience from doing Gatsby, and I think that's probably where frontend-heavy people will have seen it the most. The cool thing about GraphQL is it's actually a very simple, concise language where you just write either the word query or the word mutation, name it, and then specify what the query is and what you want back from it.
00:08:57 - Anthony Campolo
Everything we're going to be doing today is GraphQL, and then there'll be certain things that are specific to StepZen, because the point of StepZen is to take different kinds of backends and turn them into a GraphQL API. Whether that is a REST API, a database, or even another GraphQL API, it will stitch it all together into a single graph for you. If you've ever used Apollo, you may have had to figure out how to get a bunch of different data sources together and write resolvers that move throughout different pieces of the backend to find the right data and stitch them back together into a single object you can query. With StepZen, it does that for you automatically. You just write a bunch of schemas and then you can query it. What we're going to do is end with one giant mega query that's going to hit five or six backends all at once and get all the data in one go.
00:09:52 - Anthony Campolo
So that's kind of the high-level pitch — what is StepZen?
00:09:55 - Alex Trost
Got it. So it's my one-stop shop for all the data that my project needs, basically.
00:10:01 - Anthony Campolo
Yep, that is the idea. Whether that backend data is living in a CMS, a database, or just some random endpoint some developer gave you at some point in time — here you go.
00:10:13 - Alex Trost
Got it. Yeah. I know with my projects they might start out where I just have one source of data — maybe just Prismic, or even Markdown, or just Supabase. We just did a project that needed to fetch donations from Supabase. But as you continue to add onto that project, you keep piling on different data sources and it starts to get clunky. Like, I need the Supabase data to integrate with my Prismic data and all these different things. So if I have an API gateway that can handle that and manage the merger of that data for me, and I just have to talk to StepZen and not all these ten different data sources — that sounds like what I love about Gatsby. My interest is piqued.
00:11:21 - Anthony Campolo
Yeah. The terms "data mesh" and "content mesh" come up frequently with Gatsby. They were calling it a content mesh, and I think that's a really good term for it because it just kind of unifies everything into one fabric. You also hear the term GraphQL Mesh from The Guild, because they have an open source project that does a similar thing to StepZen — you can take all these different backends with different languages and types and put them all together into one thing. The main difference is that with StepZen you also get a fully hosted experience. When we build out the project, you'll be able to run a command that will deploy your endpoint, and that gives you a deployed endpoint that you can then use in any frontend you want. For someone who already knows how to work with a GraphQL API and knows how to send queries from whatever their favorite frontend framework is, you will immediately have an endpoint you can start querying and working with, which is really cool.
00:12:26 - Alex Trost
Great. Love it. So how do we want to get started here?
00:12:32 - Anthony Campolo
Yeah. So the first thing — I see Michael
00:12:34 - Alex Trost
Chan in the chat. Great to see you, my friend.
00:12:37 - Anthony Campolo
Always good, buddy.
00:12:39 - Alex Trost
Yeah, yeah.
00:12:40 - Anthony Campolo
Good to see you. While we start, you can clone the StepZen boilerplate that I had shared with you, because this will be a good way to —
00:12:48 - Alex Trost
I'm a step ahead, Anthony. I am ready. I'm here. So I did a few things to prep for the stream, just to fill in chat in case you're coming here looking to follow along. I cloned this down. Let me actually grab this repo for our friends. Yes, I want to go — I cloned this down, and then I installed the StepZen CLI.
00:13:24 - Anthony Campolo
Yep.
00:13:25 - Alex Trost
So those were kind of —
00:13:26 - Anthony Campolo
The CLI is what you're going to be using to actually deploy and interact with it. So it's really sweet because you just run a single command, stepzen start, and it does pretty much everything for you. Then why don't we look at each of the different files we have. So go to index.graphql — this is the entry point into your graph. Right now we have one single file, which is test.graphql, and that is going to be our graph. But as we go and add more data sources, we're going to create new files that will be brought in. Every time we create a new file, you have to remember to go back to your index.graphql and add the new filename. We're going to do that a handful of times.
00:14:10 - Alex Trost
Cool.
00:14:10 - Anthony Campolo
Right now it's just a single file. Basic project setup.
00:14:14 - Alex Trost
Great.
00:14:15 - Anthony Campolo
Then if you go to test.graphql —
00:14:17 - Alex Trost
Hold on, give me two seconds. I want to turn that bot off if I can manage it. Oh no, my keyboard is — see if I can turn that off super quick. Sorry about that. First stream since the fundraiser. Okay, it is off. Thank you for letting me do that.
00:14:36 - Anthony Campolo
Except for the snowtacular.
00:14:38 - Alex Trost
Yes, that was the donate link. You can still donate, but I don't want to spam. Trash.
00:14:45 - Anthony Campolo
I decided actually I really like trash now.
00:14:48 - Alex Trost
Yes. Cool. Sorry to cut you off. I just saw that pop up and wanted to nip it. Cool. I want to go where now?
00:14:58 - Anthony Campolo
test.graphql. Cool. This is our first basic GraphQL schema. This can also help anyone who doesn't know GraphQL — we can walk through it real quick. We're defining a test interface and it has some very basic types. You have a string, int, float, JSON, date, and datetime. And then we have a single query called getTest, and that query returns the test interface. Every StepZen schema you have is going to have a directive under the query that connects it to something. We don't have that right now because this is just set up to return mock data, just to make sure your GraphQL API is up and running. This is all you need to get started.
00:15:55 - Alex Trost
Got it. Cool.
00:15:56 - Anthony Campolo
And then go to stepzen.config.json. This will give us an endpoint name. Right now it's going to be api/stepzen-boilerplate.
00:16:07 - Alex Trost
So this is going to be preceded by like stepzen.com and my account name, and then I can determine what this is called beyond the hosted StepZen instance, right?
00:16:21 - Anthony Campolo
Yep, exactly. It's going to map to your name and your own custom domain. So anyone can deploy this and will have the same part at the end, but everyone will have their own part at the beginning because it's being hosted on their own account.
00:16:34 - Alex Trost
Cool. All right, great.
00:16:37 - Anthony Campolo
And then let's go ahead and run stepzen start and see what happens. This is where the magic happens — or the magic blows up and we die.
00:16:49 - Alex Trost
All right, so —
00:16:51 - Anthony Campolo
So you can see two things here right now. Before you go anywhere, this is important to explain because it confuses people when they start. We have a localhost:5001 running with a GraphiQL editor, but that is not the endpoint. The endpoint is not actually on localhost:5001. The endpoint itself is on stepzen.net — it's already a live endpoint, not running on localhost. But you have GraphiQL running on localhost to query that endpoint.
00:17:21 - Alex Trost
Got it.
00:17:21 - Anthony Campolo
Open up localhost:5001. This is also nice because GraphiQL is already giving you your StepZen keys in here, because if you want to hit this from a frontend — which we're probably not going to go into — you have StepZen keys, which I think you showed at the very beginning of your stream, by the way. So we might want to roll those.
00:17:38 - Alex Trost
Cool. Sounds good.
00:17:39 - Anthony Campolo
It was in your account. It was showing.
00:17:41 - Alex Trost
So they just show. Got it.
00:17:45 - Anthony Campolo
This is being included in your GraphiQL right now.
00:17:48 - Alex Trost
Got it. We might want to tuck those behind a little show button for future reference.
00:17:53 - Anthony Campolo
Yeah, it should be. I'm not sure why it isn't.
00:17:56 - Alex Trost
Oh, good.
00:17:58 - Anthony Campolo
So let's write — actually, first thing, open the Explorer.
00:18:02 - Alex Trost
Cool.
00:18:04 - Anthony Campolo
And then hit getTest and hit all the buttons except testMock.
00:18:10 - Alex Trost
Sounds good. Got it.
00:18:13 - Anthony Campolo
There you go. So there's our first GraphQL query. As you can see, we're getting back all of our different types. You have the date and you have a more specific datetime. You got your float, got your int, got your JSON. One is just an empty JSON object, so you have kind of two JSON test cases — like, what happens if they just throw an empty JSON object. So yeah, this is just our first get-up-and-go thing. Questions so far?
00:18:40 - Alex Trost
Not for me. This is making sense so far. So this is like — I had to make sure in my head — just because it's string: String, the first one is just the name and the second one is the type.
00:18:57 - Anthony Campolo
Yes. Yeah, that's a little confusing based on this example, but that's exactly it. You wouldn't necessarily have to call these the exact same thing. That's just so when the data pops out, you can see what's what. You could call it anything and it would return either the string, or the int, or the float.
00:19:13 - Alex Trost
So like, as long as — like that. And yeah, it'll — if I refresh, maybe it'll refresh and —
00:19:21 - Anthony Campolo
The Explorer will update. Yeah, so try name.
00:19:24 - Alex Trost
Yeah, name.
00:19:25 - Anthony Campolo
There it is, all the way at the bottom.
00:19:27 - Alex Trost
Yeah. So obviously that's not a real name, but I just want to point out — this is the key, here is what we're calling it, and that's the type. And then the exclamation mark means it's required. Is that correct?
00:19:40 - Anthony Campolo
Yep, exactly.
00:19:42 - Alex Trost
Awesome. Yeah.
00:19:42 - Anthony Campolo
Or non-nullable. Can't be null.
00:19:45 - Alex Trost
Got it. Cool. Thank you for that clarification. So this is good for me. We've got an endpoint and it is live — down at the bottom it has the stepzen.net URL. So that's already deployed and we can hit it as long as we send it an actual request.
00:20:12 - Anthony Campolo
Yeah. One thing I like to do is have Insomnia open where I'll test that endpoint with my StepZen keys in the header, just to get that verification — okay, it's working through the StepZen thing, but what if I just actually hit this from any API tool? Say, Postman. We did a Postman stream where they showed how to work with something like this using their GraphQL tooling. Most API tools now have GraphQL-specific tooling, autocomplete, and type checking, which is all pretty great.
00:20:51 - Alex Trost
Awesome.
00:20:52 - Anthony Campolo
All right, so the data was populated as just mock data. This is why I'm starting with this as the first example — the data is not coming from anywhere. This is just what StepZen does if you don't give it a real endpoint. The next one we're going to do will use the JSON Placeholder API, and that's where the data will be populated with real content. And then we're going to show how to do a database, so there's going to be data coming from lots of different places. Right now this data is nowhere — it's just built into StepZen as a mock test thing.
00:21:24 - Alex Trost
Cool. Awesome. So now what do we want to do?
00:21:30 - Anthony Campolo
Create another file and let's call this users.graphql.
00:21:41 - Alex Trost
Cool.
00:21:41 - Anthony Campolo
Yep. And then we're going to create a type this time — not an interface. So it's going to be type User, then curly braces, then we're going to have id: ID.
00:22:03 - Alex Trost
Like that or —
00:22:05 - Anthony Campolo
Yeah, both capitalized — both ID. Yeah, because that's another GraphQL thing, is that there's usually an ID for each type.
00:22:16 - Alex Trost
Hey, Steph.
00:22:17 - Anthony Campolo
Then we're going to add just a bunch of strings, which are going to be name, username, and email. The type has to match up with the API we're going to hit. So before we actually do that, we should show the JSON Placeholder API. Last one was email: String.
00:22:44 - Alex Trost
And do you want these non-nullable?
00:22:47 - Anthony Campolo
Let's put exclamation points after all of them.
00:22:49 - Alex Trost
Yeah, okay.
00:22:53 - Anthony Campolo
Cool.
00:22:53 - Alex Trost
All right.
00:22:54 - Anthony Campolo
And then let's do type Query now, outside of the type User block.
00:23:02 - Alex Trost
Yeah, my keyboard's being funky.
00:23:05 - Anthony Campolo
Yeah, luckily there's not a whole lot of typing we'll be doing. The stuff we're writing is going to be very concise. Cool. So we're going to do getMockUsers — camel case. Cool. Sorry, users, because it's going to return an array of users. Then do colon and then inside brackets do User. Basically what this means is that it's going to return an array of these User objects. That's the whole query. And now here's where the StepZen stuff comes in. So make another line under getMockUsers, indent two spaces — or tab if you're one of those people — and then do @rest. All lowercase, then parentheses, then endpoint: and then quotation marks. And inside there you're going to use the JSON Placeholder URL. Do you want me to read it out or do you want to just grab it? I dropped it in the chat.
00:24:28 - Alex Trost
Yeah, I'll grab it. Is it the gist? Where are you dropping it? Oh, did you drop it in the chat? Got it. Was not sure.
00:24:41 - Anthony Campolo
Yeah. Which is easier for you when I'm sending you stuff?
00:24:44 - Alex Trost
If you want to share it with chat — like if it's something like, hey, here you go, if you're following along — that works. If it's not something chat's really going to care about, then you can drop it in the DMs.
00:25:02 - Anthony Campolo
Either way, I'm going to drop a gist, which is essentially a script of what we're doing here. It can get confusing if you start looking ahead.
00:25:13 - Alex Trost
So I do this — like I drop all that in there?
00:25:17 - Anthony Campolo
No, no, no, no.
00:25:18 - Alex Trost
Okay.
00:25:18 - Anthony Campolo
Yeah, just the endpoint.
00:25:22 - Alex Trost
Yeah, okay. Just the URL.
00:25:24 - Anthony Campolo
Exactly.
00:25:24 - Alex Trost
Yeah, got it. Okay.
00:25:25 - Anthony Campolo
Exactly. Yeah. So what's going on here is this is essentially telling StepZen we are going to run a query with the type we've defined, and then it's going to resolve it with this endpoint.
00:25:39 - Alex Trost
Okay, got it.
00:25:41 - Anthony Campolo
Now let's save that and then go back to index.graphql because we have to add —
00:25:46 - Alex Trost
Add the file.
00:25:48 - Anthony Campolo
Yep, exactly. It'll be exactly like that — users.graphql. Cool. All right, you can go back to your GraphiQL editor. You should refresh anytime you change something so you'll have it in the Explorer. Cool. Yeah, so this is really great because you don't really even have to know how to write these queries. The problem right now, unfortunately, is your screen resolution. Normally it's not as big of an issue.
00:26:26 - Alex Trost
This is not a StepZen thing — this is a GraphiQL thing, the editor that you use.
00:26:31 - Anthony Campolo
Yeah, it's a popular open source library that we're just sticking our logo on top of.
00:26:36 - Alex Trost
Yeah. But I mean, that's what Gatsby and everyone does. Yeah, yeah, it's a wonderful tool.
00:26:43 - Anthony Campolo
We're going to go ahead, do all four of those. Yeah. Awesome.
00:26:48 - Alex Trost
Okay, so that is pulling from here, right? From this — Leanne Graham. Is that what it's doing?
00:26:56 - Anthony Campolo
Cool. Now you can see — if you've ever done GraphQL before, this is where you'd have to write resolvers in Apollo Server, because you'd have to hit the REST endpoint and then write JavaScript code to take the object and map it into something that makes sense to your schema. That's what StepZen is doing for you. It's letting you skip writing resolvers and just go with a schema and the query, and it figures out how to do the resolvers. Which is mind-blowing.
00:27:35 - Alex Trost
Yeah. So there's nothing special about this endpoint necessarily. I could have put in any REST API here and it would have taken care of it. It's not like you've explicitly mapped out the JSON Placeholder endpoints — it's already figured out.
00:27:58 - Anthony Campolo
The only thing we had to figure out was the User type itself. And we even have a tool that lets you convert JSON to GraphQL. I've done this enough that I can just look at an API and quickly figure out the types. But there's actually an auto-generating tool we have that can do that part for you, which is really great. This actually makes a lot of stuff more accessible to beginners. This is why I've been really passionate about this project, as someone who's still relatively new — StepZen is actually my first tech job. I was in a bootcamp before this. So having access to all these APIs really quickly because of the power it gives you is really, really cool. Having people wrap their minds around it is important to me. Because when you first look at StepZen, it can be hard to understand what it's really doing, because you're writing so little code.
00:29:05 - Anthony Campolo
But once you understand it, it's a very easy way to work with a lot of stuff all at once, which is really great especially with Jamstack. There's just so many services now and so many ways to connect to different stuff. But every API is different — every single API is different.
00:29:25 - Alex Trost
Yeah, that's why I'm just trying to make sure that this — yes, every API is different. So to make one solution that takes them all in feels near impossible to me. So I'm just clarifying — this isn't something you've already mapped out beforehand because it's a REST API in a certain format. When we can tell StepZen what that format is and what we're expecting, then we can work with that in our GraphQL API. Got it.
00:30:02 - Anthony Campolo
All right.
00:30:02 - Alex Trost
Okay.
00:30:03 - Anthony Campolo
So the next one we'll do is going to be almost identical, but instead of an @rest directive, it's going to be an @graphql directive.
00:30:11 - Alex Trost
Got it.
00:30:12 - Anthony Campolo
So we're moving to GraphQL. And we'll be using, of course, the ever-fantastic Rick and Morty GraphQL API. Are you a Rick and Morty fan?
00:30:22 - Alex Trost
I have — no, I'm not. I just haven't really gotten into it. The fan base keeps me away, to be honest.
00:30:31 - Anthony Campolo
Oh, that's too bad. I'm a fan of the show, but I've been a fan of lots of things with terrible fan bases. I used to like Tool, so I get it.
00:30:41 - Alex Trost
Yeah, I mean, it's not that I'm explicitly against it or anything, just haven't dipped my toes in too far. All right, cool.
00:30:49 - Anthony Campolo
It can be pretty aggro. So yeah, let's create a file called characters.graphql.
00:30:59 - Alex Trost
Cool. We're going to do a type here.
00:31:01 - Anthony Campolo
And then let's go ahead and add that into our index.graphql right now.
00:31:03 - Alex Trost
All right, characters.
00:31:09 - Anthony Campolo
Austin knows what I'm talking about.
00:31:12 - Alex Trost
Yeah. Austin, how's it going? Good to see you. And yeah, that was an excellent quote — used to like Tool. All right, cool.
00:31:23 - Anthony Campolo
Type Character.
00:31:26 - Alex Trost
Cool.
00:31:27 - Anthony Campolo
With an ID field of type ID again. And then name and image, which will both be strings. One of the things I'm doing here is not having you write out the entire schema — I want to show the directives, which is the important part.
00:31:51 - Alex Trost
Cool.
00:31:51 - Anthony Campolo
If you really want to work with something like this and send any kind of query, you'd have to get the entire schema. But we also have auto-generating tools to introspect a GraphQL schema. One of the great things about GraphQL schemas is that they usually — if it's a public one — will let you introspect them and basically say, "what are the types?" and they just tell you. We've built tools that will let you do that as well. I'll drop that link in the chat too. You can introspect —
00:32:26 - Alex Trost
Yeah. It's good to see you, Mike. Welcome to the chat, buddy. Hello. Okay, cool.
00:32:34 - Anthony Campolo
We're not going to do that right now though, because it'll give us like a 10,000-line file.
00:32:39 - Alex Trost
No worries.
00:32:41 - Anthony Campolo
Yeah. Cool.
00:32:42 - Alex Trost
Back to this. All right, so we got a Character with ID and name.
00:32:45 - Anthony Campolo
All good. Yeah. And then we're going to create a type Characters. This is because the Rick and Morty API is kind of nested — the thing we really want is going to be the characters, but to get there we have to do this. So do results, all lowercase, then colon, then in brackets Character. Yeah, exactly. So now what happens is the field is — this is a little more GraphQL jargon here — the types have fields, and the fields can return other types. This is why it's a graph: you can have things nested within each other as much as you want. Now we're going to write a query that returns Characters, but without wrapping it in brackets.
00:33:51 - Alex Trost
Okay, not following yet, but I will once it comes back.
00:33:54 - Anthony Campolo
Sure. Yeah. So just do type Query outside of the Characters type, and then characters, all lowercase, returning Characters with a capital C. We're not putting it in brackets because it's already going to return an array — the array is within the results field. So that's why we just return the Characters type. This is just a little bit of GraphQL stuff you need to know. And there's a question in the chat: are the REST directives unique to StepZen? Yes, all of the directives we're showing here are unique to StepZen. The @rest one was unique, and now we're about to do an @graphql one. These are the special sauce of StepZen, because everything else — you're still writing queries and types, your schema is pretty much unchanged — but the directive is what does all the stitching together of the endpoint to those queries. The ability to write directives and give them custom behavior has been in the GraphQL spec from the beginning. You just don't see it that often because people typically build GraphQL projects from scratch. This is a nice way to have StepZen-specific built-in conventions.
00:35:28 - Anthony Campolo
Built-in conventions into GraphQL that are StepZen-specific.
00:35:33 - Alex Trost
Awesome. Great questions, Cynthia. Really appreciate it.
00:35:39 - Anthony Campolo
Yeah, definitely. Keep the questions coming. I'm always a fan of explaining. I used to be a teacher, so that's actually one thing you and I haven't touched on.
00:35:46 - Alex Trost
Yeah.
00:35:48 - Anthony Campolo
And then now we're going to do @graphql, all lowercase, and then exactly like the other one — parentheses, then endpoint:. Yeah. And then make sure to save.
00:36:03 - Alex Trost
Yep, hit save. Heading to our characters results — ID, image, name. Okay, there we go.
00:36:15 - Anthony Campolo
Cool. Yep. So now that's coming from the Rick and Morty API. And now yeah, let's hit a couple of these.
00:36:23 - Alex Trost
Yeah. Kind of want to — so you have our characters up here at the top, and then a little bit further we have our mock users. And then getTest was in the middle. All right. Got it. Perfect.
00:36:42 - Anthony Campolo
Awesome. Cool. Right, yeah. Now we're able to basically work with the entire thing as if it's one unified graph and write any kind of queries we want to get any sort of data. This was the promise of GraphQL from the beginning — that you would be able to do this from the frontend. The creators of GraphQL, who worked at Facebook at the time, have said they started from the mental model of a frontend developer and worked backwards. They basically said, what is the nicest possible query we could write, and then created an entire language to facilitate writing those kinds of queries. So StepZen really leans into that.
00:37:22 - Alex Trost
And you can do stuff like this, right, where if I want it to have a different name — there's just lots of small details in GraphQL that make it really nice to work with. I can't believe we've already got two different APIs built into this.
00:38:04 - Anthony Campolo
Yeah, two APIs and some mock data. Now we're going to get a database.
00:38:10 - Alex Trost
Okay. All right. Nice. Checking off the GraphQL API. We're fine.
00:38:14 - Anthony Campolo
It can't just be any kind of database. It needs to be a Supabase database.
00:38:19 - Alex Trost
Supabase database. Got it. Nice. Awesome.
00:38:24 - Anthony Campolo
You already know how to use Supabase at least a little bit — at least spin it up — because it takes a minute or two, and then we'll start writing code.
00:38:32 - Alex Trost
How do you want me to do that? You want me to use one of mine?
00:38:38 - Anthony Campolo
I mean, if you want, you can just make a brand new one, or I can make a new one. If you hit your limit, you just make a new organization and then you can make more.
00:38:45 - Alex Trost
Yeah, I mean, I can spin one up. Give me one sec.
00:38:50 - Anthony Campolo
Yeah. And then I can talk a little about — for people in chat who may not know all the new dev tool companies out there — Supabase is a way to host a Postgres database with a really nice UI, because they want to essentially mirror the functionality of Firebase but with a relational Postgres database. If you've ever used Firebase before, you know it's not just a database — it's also a querying language and client libraries and authentication and storage and serverless functions. Supabase is the equivalent of that, built on an entirely open source stack. I'm a really big fan because I like using Postgres. I've been using Redwood, so I'm very familiar with Postgres. Having the ability to spin up a Postgres database in a minute or two and just start using it is really, really powerful, because you'll never need to install Postgres locally ever again. These things just work so well, and they're free for the most part.
00:40:00 - Anthony Campolo
It's great for beginners who just want to get their hands on a database but don't want to worry about breaking something or paying a $40 bill to Amazon because their database was the wrong type and all that kind of stuff.
00:40:12 - Alex Trost
Yeah. And everything includes auth, storage — they've got a whole bunch of stuff now. It's just great. And there's a few of them too. Like I've been using Supabase, but PlanetScale is another one that's kind of up and coming. FaunaDB, right?
00:40:32 - Anthony Campolo
Yeah, I've used almost all of them. I'm actually a really big fan of Railway because Railway supports Postgres, MySQL, Redis, and MongoDB, so you can use any of those just as an add-on. You can actually have multiple different types of databases all at the same time, which is really weird but works pretty well. CockroachDB also has a serverless offering. So if you're into databases, this is like the golden age of databases right now.
00:41:01 - Alex Trost
CockroachDB — I just don't understand why they would name it that. Because the database can't die, right? But I mean, not a lot of people like that thing. I don't know. Anyway, Egad says Railway is dope. Yeah. I think we might be trying to play with it after Supabase. Is that right?
00:41:27 - Anthony Campolo
We'll see if we end up with enough time. Because I have another example that will involve a Redwood backend with Railway. So yeah, see if we get to that.
00:41:38 - Alex Trost
So I do have Supabase up. Would it be fine if we use the data from the donations project we just worked on Friday? Or do I do something totally different?
00:41:51 - Anthony Campolo
We're going to want a fresh database, because what we're going to do is show how to essentially hook into the RESTful API. So yeah, we're going to want a fresh table on a database.
00:42:05 - Alex Trost
So do a fresh table. All right, do we want anything — pull this over. This should all be fine. Anything here that we want to —
00:42:20 - Anthony Campolo
So yeah, just add a column and have that column say name, then make it text.
00:42:37 - Alex Trost
Okay.
00:42:37 - Anthony Campolo
Yep. That should be good. Save. Yep.
00:42:42 - Alex Trost
All right. Creating new table.
00:42:48 - Anthony Campolo
Okay. And then there's going to be some code I'm going to send you privately. We're going to need your API key, which you probably want to grab off stream. And then we're going to want the endpoint. Because Supabase gives you an endpoint that exposes a RESTful API. This is something people may not necessarily know about Supabase — they include this library called PostgREST, which is an auto-generating REST API for your tables. Pretty interesting.
00:43:31 - Alex Trost
So where do I put this configuration thing that you just sent me?
00:43:35 - Anthony Campolo
You're going to create a new file called config.yaml. Yep.
00:43:41 - Alex Trost
Okay.
00:43:42 - Anthony Campolo
Yep. And that's where it's going to go. Where the XXXX is, that's going to be your API key that you get from your Supabase dashboard. That's what you need to make sure you don't expose.
00:43:52 - Alex Trost
And where does the endpoint go? We're going to use that in the GraphQL query like we've been doing.
00:43:59 - Anthony Campolo
Yeah. I just sent you another chunk of code. Make a new file called books.graphql.
00:44:06 - Alex Trost
Okay. So do we want the public key or the secret one? Just probably the public one, right? For the API key there's always two. The secret one has like unlimited power. And then the public key you can —
00:44:22 - Anthony Campolo
I'm pretty sure it's the public one.
00:44:24 - Alex Trost
Cool.
00:44:24 - Anthony Campolo
Yeah.
00:44:25 - Alex Trost
All right. Saved that. And the public one's kind of fine to expose honestly — for the most part I've got it locked down anyway. Okay, so I got that done. Egad said — how do you miss the holiday party? What if we're going to do that today? Yeah. Great to have you. Thank you so much for coming through. This is the last stream of the year, so you're just in time. Let me go over and grab this. So type Book { id: — all right. What do we want to call this file?
00:45:02 - Anthony Campolo
Yeah, let's just call it books.graphql. And I'm realizing now because of how we named the table, we might have to modify this a bit. So instead of books, the endpoint path is going to be stepzen.
00:45:19 - Alex Trost
Okay. So typically, chat, you're going to name your thing not after the company that you're working with.
00:45:27 - Anthony Campolo
Can we go back? Let's see — can we rename the table?
00:45:30 - Alex Trost
Honestly, one thing that's been a pain with Supabase has been renaming tables and changing stuff, so I'm skeptical.
00:45:38 - Anthony Campolo
Okay, just delete that table and then create a new one called books.
00:45:42 - Alex Trost
Okay, well let me try it because I don't want to totally count them out. Let me refresh and make sure this actually worked. It seems like we were successful. Yeah, books. Got it. Awesome.
00:46:06 - Anthony Campolo
The only other thing you need to fill in is the XXXX in your endpoint URL. That's something you'll be able to get — since you're already having that REST API exposed, they give you this endpoint and then all you do is add a route for the name of the table. So cool. I think if you also already got your key in your config.yaml, that should be everything we need. This should restart. I should actually explain some of this code though. There's a lot happening here that wasn't in the others, so go back to books.graphql.
00:46:44 - Alex Trost
Sounds good. To do that.
00:46:46 - Anthony Campolo
Yeah. So the first thing we have here is that we're including now a configuration along with the endpoint. If you look at the @rest below books, it's very similar to the other one where it has the endpoint — but now we also have headers with an API key. This is where when you're building real projects, you're going to have API keys, auth headers, all this stuff, which can be hard and confusing to manage. Basically, all of your secret stuff will always be in config.yaml. Everything that's not in config.yaml should not be secret. Then actually, real quick, let's make a .gitignore just as good practice and put your config.yaml in that .gitignore file.
00:47:45 - Alex Trost
Thank you for the follow. Welcome to the stream. Good to have you.
00:47:52 - Anthony Campolo
Cool. Then the other thing — now we're writing a mutation and not just a query. Again, GraphQL: you write queries to get data and mutations to change data. We have the endpoint with the configuration and the headers, but we also specify the method, which is going to be POST, and then we're going to do a post body. The post body code is the one area where things get a little hairy, and it's going to be useful to have a StepZen example already written because I've figured out how to write this somewhat complex thing. It does a lot of character escaping. Basically it grabs the name, which is what we're going to input into our createBook mutation — we want to give the book a name when we create it. We write a GraphiQL query to create a book, give it the name, and it maps that to the post body. If we go back to our GraphiQL editor now —
00:48:53 - Anthony Campolo
Let's clear all this out. Yeah. Oh, we didn't add the file. Yeah, we forget at least once.
00:49:01 - Alex Trost
books.graphql. All right, cool.
00:49:10 - Anthony Campolo
Takes a second to save. Cool.
00:49:13 - Alex Trost
Good. Nice.
00:49:14 - Anthony Campolo
Yep.
00:49:14 - Alex Trost
"I'll say from the start, I'm no coder, but very much an ideas man. Background is Domino technical architect."
00:49:20 - Anthony Campolo
Interesting.
00:49:22 - Alex Trost
A Domino technical architect. I'm interested in what that is like — Domino's pizza?
00:49:27 - Anthony Campolo
Domino's? Or Domino — guessing it's Lotus Notes.
00:49:35 - Alex Trost
I've heard of those. All right, I've heard of that, but that's really interesting. It's great to have you, though. Always great. I'm a big believer in outside perspectives. Both Anthony and I come from different backgrounds as well. We are not classically trained developers, so yeah, definitely welcome the outside experience.
00:50:00 - Anthony Campolo
Okay, hold up.
00:50:01 - Alex Trost
Yeah, sorry, I got clicky.
00:50:04 - Anthony Campolo
Yeah. But there should be a createBook. Oh, I know why — because we're only looking at queries right now.
00:50:10 - Alex Trost
Yeah.
00:50:10 - Anthony Campolo
Underneath your stream thing — you can't quite see it because you pulled up the — yeah, there you go. Yeah, you select your mutations.
00:50:22 - Alex Trost
Okay.
00:50:23 - Anthony Campolo
And then hit the plus button. Cool. There we go. Now we're talking. Yeah.
00:50:33 - Alex Trost
Oh, okay. So I'm going to get rid of the query. Is that right?
00:50:37 - Anthony Campolo
Yep, correct. And then you can write the name in on the left or in the query itself. "Old Man and the Sea" — that is a book. And then just return the ID and name. Let's see.
00:50:52 - Alex Trost
All right.
00:50:53 - Anthony Campolo
How it does with that. Okay, so that's fine. But if we go back to our Supabase table now —
00:51:03 - Alex Trost
I'm sorry, what did you just say, Anthony? Did you say "super base"?
00:51:09 - Anthony Campolo
Oh, Supabase.
00:51:12 - Alex Trost
Thank you. Hey, look at that. It got in there.
00:51:16 - Anthony Campolo
Yeah, there's a slight bug there — it should actually be returning the ID and name. Something for me to figure out one day. But it actually does write it to the database. That is the far more important part.
00:51:27 - Alex Trost
That's really cool.
00:51:28 - Anthony Campolo
Now if we do the books query again, we should get back the book.
00:51:32 - Alex Trost
Oh nice. Okay, so how do I close out of the mutation? How do I get the queries back?
00:51:42 - Anthony Campolo
Yeah, I think you need to go back to the bottom and hit plus on query.
00:51:46 - Alex Trost
Yeah, I just closed.
00:51:47 - Anthony Campolo
Yeah. When you're working with both queries and mutations, the explorer gets a little dicier.
00:51:51 - Alex Trost
Got it. All right, so books — I should be able to get that back. Awesome. All right, nice. So with StepZen, I can create mutations that work with these same databases that I'm able to query from, and just through the one tool. I can't tell you how much I enjoy just using one thing, learning one thing. Through StepZen, I'm able to not only query all my data but maybe update user data. Or, as we just showed, if I'm doing a personal library app and I also want to call in reviews from Amazon and connect it to a books database and something else — I can have all of that coming in through one API.
00:52:44 - Anthony Campolo
Exactly.
00:52:44 - Alex Trost
That's really nice.
00:52:51 - Anthony Campolo
Watching GX Ray's snow tackling infrastructure in real time.
00:52:55 - Alex Trost
Yeah, right. Because that's kind of what we had to do. Team Seas — the charity we raised all the money for — had an API that was open, we didn't need to authenticate or anything. But it also wasn't documented, so we didn't know how to use it beyond a quick request for the Frontend Horse total. It was paginating at 150 and we had no idea how to go beyond the first page of results. So we set up Supabase to hold all of the donations just in case we went over 150. We were close — we were at like 125 or something. So it was a good call to have that as a backup. We had to combine those two different sources of data, and yeah, it was a little bit of a pain. Having something like StepZen to manage all those things is super cool.
00:54:14 - Alex Trost
"Can I ask your advice on something? Can wait till later if you're busy."
00:54:18 - Anthony Campolo
Yeah. Feel free to drop any questions in the chat. Always happy to help.
00:54:22 - Alex Trost
It's not just Anthony and I here — we've got some fantastic, much more knowledgeable people in the chat, so absolutely ask away. If it's something I'd like to give a more fleshed-out response to, either we can take it to the Discord or I'll let you know. But there's a good chance that people like Ben and Michael and everyone else can help.
00:54:46 - Anthony Campolo
You've got quite the hive mind built up in chat.
00:54:49 - Alex Trost
Yeah, there's good folks there. Awesome. So we connected a database, and not only to read from — I didn't expect us to be able to write to it so easily. It was a bit of copy-paste, but not a ton of code. That's awesome.
00:55:08 - Anthony Campolo
Where we're at right now, with time, we'll probably skip over the FaunaDB one. But people can check out the gist — there's an example where we would have done the exact same thing with Supabase but with FaunaDB. And there you're just writing regular native GraphQL mutations, and you don't have to do that weird post body thing. That's like the next step, and even nicer. But yeah, if you want to just go down to the FaunaDB section — yeah, there you go. So FaunaDB will give you a bunch of mock data for a store. You create a store type, and then you can find a store by ID, return all stores, create a store, update a store, delete a store. I think people pretty much get the idea at this point of the GraphQL endpoint and the config and all that. All right, well, that's a long one.
00:56:07 - Alex Trost
Yeah.
00:56:09 - Anthony Campolo
"Basic code, but needed touching up. As I'm no coder, I gotta flower it up, so to speak. I paid five grand. Whoa. That's a lot."
00:56:16 - Alex Trost
We can — I think we can come back to that in a bit, Anthony. I don't want to cut you off. But I think maybe Ben in chat or someone can help. Yeah, it seems like a detailed question that I definitely want to help with. Mostly Disco, just don't want to derail this entirely, but I appreciate you bringing it here. So what do we want to do next, Anthony?
00:56:41 - Anthony Campolo
Yeah, next I want to show you how Redwood works. So follow along with the Redwood API with Netlify functions. If you scroll down just a little bit more —
00:56:53 - Alex Trost
Cool.
00:56:54 - Anthony Campolo
There's a command right there. And then baby —
00:57:01 - Alex Trost
All right. I did actually — no, I did not. Okay. Should I do it in the boilerplate or outside?
00:57:12 - Anthony Campolo
Outside the boilerplate.
00:57:13 - Alex Trost
Okay.
00:57:13 - Anthony Campolo
Yeah.
00:57:16 - Alex Trostyarn create redwood-app horse-zen-redwood. Yeah.
00:57:18 - Anthony Campolo
Actually, you should —
00:57:21 - Alex Trost
I can stop it. I can stop it.
00:57:23 - Anthony Campolo
No, no. Well, now this might create a folder you're going to want to delete. So first delete that folder if it created one, and then get a new VS Code window open.
00:57:34 - Alex Trost
It did not create a folder. We are good.
00:57:36 - Anthony Campolo
Okay, great. So just get a new VS Code window open.
00:57:39 - Alex Trost
Okay.
00:57:39 - Anthony Campolo
And then keep this one where it is. You can have your Redwood project and your StepZen projects both open at the same time. But yeah, to simplify our lives, we just keep them separate.
00:57:47 - Alex Trost
Okay, cool.
00:58:06 - Alex Trost
Correct, yes.
00:58:09 - Anthony Campolo
Redwood is actually how I got into the whole open source coding world in general. My job at StepZen was actually a direct result of the work I was doing on Redwood. It's a full-stack JavaScript framework for apps, and it says here it's for startups — but honestly, you can use it for all sorts of things. The idea is that it's a great tool for getting going really fast with a full-stack project. And when people say full-stack these days, it's not always clear what they mean — people refer to things like Next.js as a full-stack framework. But the real difference with Redwood is that it includes an ORM, which is Prisma. Have you ever used Prisma?
00:59:03 - Alex Trost
No, but I have used ORMs before. And thank you for the bits, Mostly Disco. I appreciate it. I will be reading and checking that out. Thank you.
00:59:13 - Anthony Campolo
Yeah, this will be great then, because we've got a Prisma employee in the chat — Austin.
00:59:18 - Alex Trost
Austin, yeah. Okay.
00:59:20 - Anthony Campolo
Yeah, yeah. And so Prisma is —
00:59:22 - Alex Trost
We've got to talk, buddy.
00:59:24 - Anthony Campolo
Yeah, you should definitely get him on to show you some Prisma stuff. So it's a way to turn JavaScript into SQL, because we all know we just want to write JavaScript. No one wants to write SQL, even though they probably should learn. I should learn at least a little SQL.
00:59:43 - Alex Trost
I should learn more. There's so many things I should learn, though.
00:59:47 - Anthony Campolo
But the great thing about Prisma is that you don't necessarily have to worry about writing SQL ever again. And you'll also be able to use it to do migrations on your database. This is part of the real power you get — the ability to set up your database programmatically. The thing we did manually through Supabase's UI, we're going to do programmatically through Prisma now.
01:00:14 - Alex Trost
Oh, nice. Got it. Okay. My ORM experience, just so you know where I'm coming from, is mainly through Django, the Python framework.
01:00:26 - Anthony Campolo
Great.
01:00:26 - Alex Trost
Yeah. So I really enjoyed their ORM that stopped me from having to do a whole bunch of SQL stuff, and that was a joy on my first web dev project. ORMs are very nice, I'm a fan. Should we check on that install and see if we're still running?
01:00:47 - Anthony Campolo
Cool.
01:00:47 - Alex Trost
Oh, Redwood has Prisma under the hood, is that correct?
01:00:51 - Anthony Campolo
Yes. So Redwood is bundling Prisma for you. You can use Prisma by itself and bring it into a Next.js project — this is common with Remix too, the docs show you how to bring in Prisma as well. Redwood is saying: we want to assume from the beginning that you want Prisma and actually bake it into the CLI itself. So we're going to run some commands that are prefixed with rw, but are actually just aliasing to a Prisma command. When you're learning Redwood, knowing where the boundary between Redwood and Prisma actually is can be a little fuzzy until you've gotten through the process of, like, ripping Prisma out and seeing what breaks — which is a fun experiment but not really recommended. When you're learning, just stick with using Prisma as Redwood provides it. You don't need to figure out how to integrate Prisma into your project; it's just assumed by default, and there are a lot of nice downstream effects of that.
01:01:50 - Anthony Campolo
Cool. While that's still going though, let's open up Railway.
01:01:53 - Alex Trost
We are here. It looks like we're good.
01:01:56 - Anthony Campolo
It takes longer on Windows than Mac unfortunately. Normally that would take about half the time if you ran it on an M1.
01:02:04 - Alex Trost
I don't know why my code thing broke — ever since, I can't open VS Code the fun way. So horse-zen-redwood. Okay. Yarn Redwood dev. Open folder. Is it horse-zen or is it horse-zen-redwood?
01:02:24 - Anthony Campolo
It was horse-zen-redwood.
01:02:28 - Alex Trost
There we go.
01:02:29 - Anthony Campolo
Cool.
01:02:30 - Alex Trost
Select folder. All right, nice. We are in.
01:02:32 - Anthony Campolo
Yep.
01:02:33 - Alex Trost
All right. And should we do yarn now?
01:02:35 - Anthony Campoloyarn redwood dev. Yeah, this will kick off our dev server.
01:02:39 - Alex Trost
All right.
01:02:39 - Anthony Campolo
And it'll just give us a nice little splash page. Don't worry about that.
01:02:45 - Alex Trost
Okay, cool.
01:02:45 - Anthony Campolo
Yeah. Don't use the Redwood IDE. It tells you to check it out, but honestly that's kind of a weird beta project that doesn't actually work that well. So don't use redwood ide.
01:02:57 - Alex Trost
Good tip. All right, cool.
01:02:58 - Anthony Campolo
It will be very cool one day. That day is not today.
01:03:02 - Alex Trost
Got it. All right, so kicked off a localhost. Yeah.
01:03:06 - Anthony Campolo
And then this is going to give us a splash page. It'll get there, don't worry.
01:03:13 - Alex Trost
Cool. All right. Nice.
01:03:16 - Anthony Campolo
There we go. Yeah. Cool. Now we got that set up. We want a database we can use in our Redwood project. If you go to Railway, we're going to show how to do Railway. Cool about Railway is it spins up a database in 10 seconds. Unlike Supabase, which does take about a minute or so. This is really the fastest way to get a Postgres database up and running. So go ahead and do new project.
01:03:43 - Alex Trost
Okay.
01:03:45 - Anthony Campolo
What do we want to deploy? Provision PostgreSQL. Yeah. This will assume you already want Postgres when it sets up. Do you have many WordPress people in?
01:03:58 - Alex Trost
We have a couple, but we tend to lean more Jamstack, which you can do with WordPress — but typically more headless CMSs. I work for a headless CMS called Prismic, so I don't have a ton of WordPress experience. I've been mainly using headless CMSs. But we definitely have some people around who are at least familiar with WordPress. My friend Colby Fayock is really good with WordPress. "Web dev has let you down. Sorry to hear that."
01:04:41 - Anthony Campolo
If you go to Postgres on the left, then a little bit further down, go to Connect. This will hide your keys for you. We're going to want the bottom one — there are two things here. There's the psql command, which will let you directly connect to your database, but we don't need that because we're going to connect through Prisma. So we just need the connection URL.
01:05:10 - Alex Trost
Okay.
01:05:10 - Anthony Campolo
So you should go off screen for a second.
01:05:13 - Alex Trost
All right. And then with this, or with my code — with this. Right?
01:05:20 - Anthony Campolo
Yeah. You'll be able to copy this without exposing it, but you're going to have to drop it into your project in your .env file.
01:05:30 - Alex Trost
Yep, just the .env. Yeah, that makes sense.
01:05:34 - Anthony Campolo
Yeah. In .env, it'll have a commented-out part where it says DATABASE_URL. So you want to uncomment that and put the connection string in there.
01:05:45 - Alex Trost
Cool. DATABASE_URL. TEST_DATABASE_URL. Which one do I want?
01:05:51 - Anthony Campolo
DATABASE_URL, not TEST_DATABASE_URL. You can keep everything else commented out.
01:05:57 - Alex Trost
And I'm going to turn on — nope, didn't mean to do that.
01:06:04 - Anthony Campolo
Those mask-your-keys things.
01:06:07 - Alex Trost
So we've got that in there — just so chat can see, there is stuff here, it's just masked out. So save that. That is set. Do I need to restart the dev server?
01:06:23 - Anthony Campolo
Yes. Then keep the dev server off for a second.
01:06:30 - Alex Trost
Okay.
01:06:31 - Anthony Campolo
Then go back to — so first, let's set up our schema. Go to the api folder.
01:06:39 - Alex Trost
API. Okay.
01:06:41 - Anthony Campolo
Yep. And then db/ and then schema.prisma. Yeah, so let's change the default model — change it to say Post instead of User. Just a single word, Post. Yep.
01:07:01 - Alex Trost
Cool.
01:07:02 - Anthony Campolo
Yep. And then change email to title. And then get rid of the unique constraint. And then get rid of name: String. Yeah, and that should be good. We could add a createdAt field or something like that, but that's not really important to what we're demonstrating right now. So let's keep it simple. Save that. And then run: yarn rw prisma migrate dev --name posts. Let me explain this before you run it. What's happening is we're telling Redwood to run the Prisma command, and the Prisma command is migrate dev, and we're creating a migration named "posts." This is going to create a table in our Railway database for our posts, as specified with the Post model we just wrote.
01:08:25 - Alex Trost
Got it. I'll be honest, the word "migrate" just gave me a little — oh right, I remember the stuff I didn't like about databases and ORMs. The stuff I struggled with as a first-time developer in my Python app, breaking stuff. Migrations can go poorly once you have a lot of data and you don't know what you're doing. So that word hit me. I had to roll back to snapshots and all that kind of stuff. Sorry, just took a mental trip back in time.
01:09:04 - Anthony Campolo
That's a great point though. When you ran migrations in Django, were you able to see the SQL it was actually using to set up the database?
01:09:13 - Alex Trost
Maybe. But this was maybe like three years ago.
01:09:17 - Anthony Campolo
Great. So run this command. I'm going to show you something really cool. Oh, we forgot one other thing — change SQLite to PostgreSQL at the second line. Yeah. So this is because you could originally just do a SQLite database, but we already have Postgres. What's really cool about the way Prisma handles migrations is that it's going to spit out a SQL file and show you exactly what that is. It's very transparent about what the migration is doing. And I don't think we had Copilot doing anything — there's Copilot working.
01:10:10 - Alex Trost
Copilot.
01:10:10 - Anthony Campolo
Yeah, Copilot.
01:10:11 - Alex Trost
It's on. I mean, it tried to help me finish the Postgres bit.
01:10:16 - Anthony Campolo
Oh, nice.
01:10:19 - Alex Trost
Yeah.
01:10:20 - Anthony Campolo
Oh yeah, that's cool.
01:10:22 - Alex Trost
Did help me.
01:10:23 - Anthony Campolo
Now if we look at the migrations folder in db/, we can see that migration. There's the SQL it's going to write for us.
01:10:32 - Alex Trost
Okay, cool. Very cool.
01:10:35 - Anthony Campolo
All right, and now we're going to do one more command: yarn rw g scaffold post.
01:10:53 - Alex Trost
Okay. Run it.
01:10:55 - Anthony Campolo
Yep. And what this is going to do is give us a whole admin UI for our posts. So now go back — run yarn redwood dev again.
01:11:07 - Alex Trost
Okay. I do like the built-in admin UI that Django had. So if you have that, that's wonderful. yarn redwood dev.
01:11:17 - Anthony Campolo
Yep, yep. And then we're going to go to localhost:8910/posts/new.
01:11:32 - Alex Trost
localhost:8910/posts.
01:11:37 - Anthony Campolo
Oh, yep. Yep.
01:11:43 - Alex Trost
Create a post title. "Anthony is super cool." Wow.
01:11:53 - Anthony Campolo
And then that's our thing. Right now this isn't set up to actually work with the frontend at all because the frontend is not really important for this project. Because what we're going to do now is deploy this to Netlify and it's going to put the API into a serverless function. It basically takes your entire Redwood backend and bundles it into one giant function, exposing that through a Netlify function. And then we feed that into StepZen.
01:12:21 - Alex Trost
That is wild. Okay.
01:12:23 - Anthony Campolo
Wow.
01:12:24 - Alex Trost
Okay. I'm trying to wrap my head around it. That's really cool. I just like getting free admin stuff — this can come in handy in so many different ways. And this is just a layer over my Prisma database. Wait, who owns the Prisma database? Is Prisma always — oh, it's Railway. Sorry.
01:12:54 - Anthony Campolo
Yeah, yeah, yeah. Moving pieces here.
01:12:57 - Alex Trost
We grabbed that. Yeah.
01:12:59 - Anthony Campolo
It was right there in your Railway dashboard. So yep. And then the post —
01:13:06 - Alex Trost
"Anthony is super cool." All right, cool. I love that. I really love that. That's just a nice little abstraction that I get for free on top of — that's so good. Awesome. All right, so we want to deploy. This is what you said, right?
01:13:23 - Anthony Campolo
So you want to get it on a git repo and then connect that git repo to — oh sorry, one more command. So you got to set up the deployment. You can turn your dev server off. We're not going to need that.
01:13:37 - Alex Trost
Am I even in — there we go.
01:13:41 - Anthony Campolo
Yeah. So then do yarn rw setup deploy netlify.
01:13:55 - Alex Trost
It's off screen a little bit. Let me —
01:13:58 - Anthony Campolo
Yeah, yeah, that's good. So then run that and this will generate a netlify.toml file for us. Cool, cool. Yep. So you scroll down to netlify.toml. Yep. Yeah. And so this gives us a command and it's going to deploy all of our things. So then all you have to do now is get this in a git repo, connect that repo to Netlify, and then you'll also have to include your database URL. I'll let you know how to do that once we get there.
01:14:34 - Alex Trost
Cool. Do you know how to use the GitHub CLI?
01:14:42 - Anthony Campolo
I do. So okay, gh repo create [name] --public. It used to just work like this, but now you got to do --public.
01:14:59 - Alex Trost
Okay.
01:15:00 - Anthony Campolo
And then hit enter and that should do it.
01:15:02 - Alex Trost
Yeah, I realize you can't see it again. There we are. All right.
01:15:07 - Anthony Campolo
Yep. I've started using this HTTPS — I guess, authenticate git?
01:15:22 - Alex Trost
With a web browser. Sure. Should I be showing this on stream? I don't even know.
01:15:31 - Anthony Campolo
Probably not.
01:15:35 - Alex Trost
Device activation. All right. Should be good. Authentication complete. Awesome. I'm going to run that again. Cool. git init.
01:15:58 - Anthony Campolo
No.
01:15:59 - Alex Trost
An origin. git remote add origin to local repository. Yes. We didn't get a git init. Cool. git init — that's not how you say that.
01:16:09 - Anthony Campolo
Git ignition.
01:16:13 - Alex Trost
All right, cool. So now we just git push. I know we did add and commit. Cool.
01:16:32 - Anthony Campolo
Do git add . Just git add .. Yep. And then git commit -m and then give it a message.
01:16:41 - Alex Trost
I already committed everything. Yeah.
01:16:43 - Anthony Campolo
Oh, you did? Okay.
01:16:44 - Alex Trost
Yeah. It just says publish branch because we're on master and I think it —
01:16:49 - Anthony Campolo
Maybe do a git status real quick. Okay, great.
01:16:54 - Alex Trost
Yeah.
01:16:54 - Anthony Campolo
Push it. Or set the remote and then push it.
01:16:59 - Alex Trost
Just git remote set-url.
01:17:02 - Anthony Campolo
This is the one I always blank on.
01:17:04 - Alex Trost
Yeah. Honestly, I always just copy and paste from GitHub.
01:17:07 - Anthony Campolo
Yeah.
01:17:07 - Alex Trost
Yeah. Let me —
01:17:11 - Anthony Campolo
Yeah, because you should have a blank repo there now.
01:17:13 - Alex Trost
Yeah. I'm not sure if I'm logged in. I am logged in. Cool. So horse-zen. Nope. Find. Yeah, horse-zen-redwood. Cool.
01:17:21 - Anthony Campolo
Yep. Perfect. Yep. So it's those last two commands.
01:17:33 - Alex Trost
All right. Should be good, I think.
01:17:35 - Anthony Campolo
Okay, cool. Great.
01:17:36 - Alex Trost
Sweet.
01:17:37 - Anthony Campolo
I think the GitHub CLI set it for you already.
01:17:40 - Alex Trost
Awesome. Now Netlify — I should probably log in. Pull this off just in case I need to do anything.
01:17:49 - Anthony Campolo
Can you refresh that just to make sure the project is there. The GitHub one. Yeah.
01:17:56 - Alex Trost
Add new site, import an existing project.
01:17:59 - Anthony Campolo
Cool.
01:18:00 - Alex Trost
Adding from GitHub. Authorized. Sweet. horse-zen-redwood. Sweet. Okay, so now it's probably going to —
01:18:11 - Anthony Campolo
And then here's where you're going to add your database. Under Show Advanced. Everything is good, don't change anything, and then add a new variable — that's where you'll grab the DATABASE_URL and put it in. Cool.
01:18:25 - Alex Trost
All right, so I'm going to do a little bit of this off screen. Actually, you know what, I'll do it this way so it's a little bit easier, chat. There's not much else to show. This is just easier. I'm in the wrong repo in general. All right, so that was under my .env, DATABASE_URL.
01:18:49 - Anthony Campolo
Getting the URL — the whole gamut of services today.
01:18:55 - Alex Trost
Yeah. Right. Okay. So it is in and it's hidden. So we can actually — the cool thing is I could have done that on camera.
01:19:04 - Anthony Campolo
Because Netlify has the extension to hide it for you.
01:19:07 - Alex Trost
Yeah, I'm hiding it here and they're hiding it there. So I could have done that. Sorry, chat. You didn't miss much though. All right, cool. So it looks like it's detected the build command already because we have the netlify.toml. Right, because that is what it's reading. Awesome. So deploy.
01:19:27 - Anthony Campolo
Yep, deploy. And then this will take probably five to ten minutes. We're going to set up the StepZen schema. So let's go back to our StepZen project.
01:19:41 - Alex Trost
Is that going to be five to ten minutes every time I push a change to Redwood?
01:19:49 - Anthony Campolo
It kind of depends what the change is and what needs to change. This first time it has to build a whole bunch of stuff, including the API. If you're just changing the frontend, that won't necessarily need to rebuild.
01:20:04 - Alex Trost
It'll cache certain things and just —
01:20:07 - Anthony Campolo
At least I think so. I may be talking out of my butt, but it's usually a situation where you're not really deploying your Redwood app multiple times a day, because you're not creating fast-changing blog content with it. You're setting up an API, and the API is handling when data is updating. So you're not constantly rebuilding lots of pages all the time, because that's not really what Redwood's for. That's why the build time itself is not a huge issue.
01:20:47 - Alex Trost
Right. It shouldn't be compared to, like, 11ty builds this fast, because it's a very different beast. The same thing that you're building in Eleventy, you wouldn't build with Redwood.
01:21:00 - Anthony Campolo
Right. Exactly. Yeah.
01:21:01 - Alex Trost
Cool. Awesome. All right, so we've got that. Did you say you wanted to do something in the meantime?
01:21:10 - Anthony Campolo
So yeah, let's go back to the StepZen project.
01:21:15 - Alex Trost
StepZen. Here we go.
01:21:17 - Anthony Campolo
Yep.
01:21:18 - Alex Trost
Cool.
01:21:20 - Anthony Campolo
Then let's create another file called posts.graphql.
01:21:27 - Alex Trost
posts.graphql.
01:21:27 - Anthony Campolo
Let's add that to index.graphql.
01:21:38 - Alex Trost
Got it.
01:21:41 - Anthony Campolo
And then now this will be type Post. Yep. Which will have an ID, which is just Int!.
01:21:53 - Alex Trost
Cool.
01:21:54 - Anthony Campolo
And then title — let's say title — that'll be a String!. And then we'll have a query. type Query. Yep. And that'll be posts, all lowercase. Yep. Which will then return an array with Post. Yeah.
01:22:18 - Alex Trost
Cool.
01:22:18 - Anthony Campolo
And then add @graphql after that. Yep.
01:22:25 - Alex Trost
Okay.
01:22:26 - Anthony Campolo
And then endpoint:. And that is where the Netlify function URL goes.
01:22:34 - Alex Trost
Got it. So should I grab what this is going to be?
01:22:36 - Anthony Campolo
Let's first give it a nice name. So go to your site settings and just change the domain settings. I usually just call it the same thing as the repo for simplicity's sake.
01:22:47 - Alex Trost
horse-zen-redwood. What was it?
01:22:50 - Anthony Campolo
Redwood, yeah. horse-zen-redwood. Yep. And then save that. If we go to the site —
01:22:58 - Alex Trost
Name is already taken. Did you already grab it?
01:23:01 - Anthony Campolo
Yeah. Okay, so give it a slightly different name. Cool. Actually, you don't need to grab that first. Just save it. And then go to Functions — the fourth tab at the very top. Not quite there. Scroll all the way up to the top and go to Functions. And then click graphql. There you go. That is your function endpoint. I don't think it's done building yet, but you can go ahead and pop that in your StepZen endpoint.
01:23:34 - Alex Trost
Cool.
01:23:35 - Anthony Campolo
Now this is the thing we haven't done yet — this is why we just went through that whole rigmarole to get to this point. Because what we have done now is deployed our own custom GraphQL API connected to our own custom database, that we can now feed into our StepZen project. We're not connecting to an API that's being given to us by Supabase — we actually created our own API with Redwood.
01:24:03 - Alex Trost
Right. And so now we can pull that in once that's built. Published.
01:24:12 - Anthony Campolo
All right, cool, great.
01:24:13 - Alex Trost
404 pages.
01:24:14 - Anthony Campolo
So let's see if we can run that.
01:24:17 - Alex Trost
To be expected.
01:24:18 - Anthony Campolo
That's to be expected because we did not build a frontend. Right now we are just accessing the serverless function. We could have created a frontend with a cell that queries our backend and shows it, but that would have added another ten minutes or so.
01:24:30 - Alex Trost
So this will only show on dev. This isn't going to show on production, in other words.
01:24:36 - Anthony Campolo
Yeah, exactly.
01:24:37 - Alex Trost
Cool. Okay, cool.
01:24:38 - Anthony Campolo
If you want to actually show someone something, you would just create a frontend pretty quickly. But right now we're only working with the Redwood API via the serverless function.
01:24:46 - Alex Trost
Sounds good. Okay, cool. So now I've saved this.
01:24:51 - Anthony Campolo
Is our StepZen server still running? Yeah. So I do stepzen start here. And then if the Redwood one works, might want to kick that off and just try it again. Oh, that's interesting. Oh, you're in the wrong directory.
01:25:16 - Alex Trost
Ah, good call. cd into the stepzen boilerplate. Cool.
01:25:22 - Anthony Campolo
There we go. Okay.
01:25:23 - Alex Trost
Yeah, we did leave it to create that other thing. Cool. All right, deploy.
01:25:28 - Anthony Campolo
If the Redwood query works, then we can run the mega query, which will be all the queries.
01:25:33 - Alex Trost
All right, nice.
01:25:33 - Anthony Campolo
This is posts. Yep. ID, title. And then did it work?
01:25:43 - Alex Trost
Wow, cool. So that's coming from Railway through our RedwoodJS API through our Netlify function. Yeah. Wow, that's wild. I added that in with the Redwood admin thing and there it is. We also have our test data — that's coming from StepZen's mock service, correct?
01:26:19 - Anthony Campolo
Yeah.
01:26:21 - Alex Trost
Then we also have our mock users, which is coming from the public REST API. We get a bunch of users back from that. We also have the Rick and Morty API here with a whole bunch of characters that we can query — we get Educator Rick, lots of characters. And then books — we should get "Old Man and the Sea" in here too. That was the one where we wired up a mutation with Supabase and created it in the GraphiQL explorer itself. We used that in the same kind of way we used the RedwoodJS admin to create an item. Wow. Now here's the question — is there anything nice that we can do either with GraphQL or with StepZen where all of this data was more interconnected? I'm thinking of use cases where — whoa. Cynthia, thank you so much for the sub. Really appreciate it. It's great to have you here, and I really appreciate the support. Thank you so much.
01:27:57 - Anthony Campolo
So if I have linked types together through APIs and things like that?
01:28:01 - Alex Trost
Yeah. Say I have a product that's in Shopify and I want the content I've written about it in Prismic to be linked to it, coming in from the Shopify API. And I also want to check my database to see how many sales we have on it, or check some review service, and bring all of that together so I can just request "give me information about this shoe" and not have to make all these different requests. Just pull that in with StepZen. Is that something that StepZen does, or is it something that GraphQL natively does but StepZen unlocks because it's giving me this one API to hit?
01:28:44 - Anthony Campolo
Yeah, there are a couple of directives we didn't talk about that I included in the chat — particularly @materializer and @sequence. @materializer lets you link types together, and @sequence lets you feed the output of one query into the input of another query.
01:29:03 - Alex Trost
Okay.
01:29:04 - Anthony Campolo
So you can chain queries together. There are other things built in that let you do more complex stuff like that.
01:29:13 - Alex Trost
Awesome. Okay, so is @sequence — I think Cynthia asked earlier — is that a StepZen-specific thing or a GraphQL thing?
01:29:30 - Anthony Campolo
Yeah, so all of the directives are the StepZen-specific part. Anytime you're writing the @ symbol and then a directive and feeding something into it, that is something StepZen is doing for you. Anytime you're writing types or queries or mutations, you're just writing GraphQL. So the boundary between the two is actually pretty clear once you start working with them.
01:29:49 - Alex Trost
Got it. So that's a StepZen thing. Okay, cool. Because that, to me, is where our example here gets powerful. We can get books and Rick and Morty characters and it's fun, but the real power comes from having all these different services. At the agency I worked at, we had to pull in review data about a pet food, but also hit another API to see where that pet food was sold — all these different services. That's a big thing with Jamstack, where you're connecting all these different things. There's not typically one service that handles all of that. But we had to connect all these things and it wasn't fun to do as a frontend developer. I wanted to focus on other things. So StepZen as a service — to not only combine all of those things into one API but also allow me to through @sequence and —
01:30:54 - Anthony Campolo
@materializer.
01:30:55 - Alex Trost
Yeah, @materializer. Allow me to combine that into one query — "give me this specific pet food item" and I get back the reviews for it, where it's sold, its locations, how much is in stock — all the things I need to display on the frontend. That is kind of the dream, and that is really, really nice that I can do that with StepZen.
01:31:26 - Anthony Campolo
Yeah. And so there's just one more thing I want to show with our remaining time here. Imagine now that everything we did — creating schemas, hooking in endpoints, all of that — imagine all of that was already done for you, and you could just literally write a query and get stuff back. That is the StepZen GraphQL Studio. Whoops, not that. Can you delete that?
01:31:52 - Alex Trost
Actually, I don't know, Ben. Can we delete that?
01:31:58 - Anthony Campolo
Those are not super important. I can roll both of those. That was not supposed to end up in my keyboard when I copy-pasted that.
01:32:06 - Alex Trost
I don't know how to do it from my interface.
01:32:10 - Anthony Campolo
Yeah.
01:32:11 - Alex Trost
Ben Myers deleted the message. Ben, you are great. Mod of the year, my friend. Really appreciate you.
01:32:18 - Anthony Campolo
That is by far the dumbest thing I've ever done on stream.
01:32:22 - Alex Trost
You'll have to — oh, good call. Still on the thing. There we go. The GraphQL Studio. Can I click here? The GraphQL Studio. Yep, that's it.
01:32:38 - Anthony Campolo
Cool.
01:32:39 - Alex Trost
Get started with GraphQL Studio. Ben, thank you again, I greatly appreciate you. You'll still need to reroll those, but at least harder to copy-paste now. Yeah.
01:32:55 - Anthony Campolo
Yeah.
01:32:56 - Alex Trost
I don't know how you did it. You'll have to teach me. Cool. So get started with the GraphQL Studio. "Create your own GraphQL API in just a few clicks. No resolvers to write, no data connections to code, no servers to build. Your API runs on StepZen." Okay, I'm intrigued, but I'm not fully appreciating it yet. So what should I do here? Just hit next?
01:33:25 - Anthony Campolo
Yeah, so let's hit next and then keep hitting next.
01:33:30 - Alex Trost
All right. Build a studio.
01:33:33 - Anthony Campolo
Build a studio. All right, so what we've got here is basically all the different integrations on the left. So hit "No thanks" there actually.
01:33:45 - Alex Trost
Okay.
01:33:46 - Anthony Campolo
Yeah, so these are all the different things we can connect to right now. These are pre-built integrations that you can just click and get going with. We're going to start with the Google Natural Language API.
01:34:06 - Alex Trost
Cloud Natural Language API. Yeah, cool. Just hit plus.
01:34:10 - Anthony Campolo
Yeah. This one will need some keys — which is actually what I accidentally dropped into the stream. So I just sent you a message. And we're going to end up rolling these afterwards anyway, so I don't really worry about taking anything off screen at this point.
01:34:27 - Alex Trost
Sounds good. Where am I?
01:34:30 - Anthony Campolo
This is one of the nice things actually about having API keys that are easy to roll. If you're working with a service that does not let you easily roll your API keys, that should be a huge red flag, because these things are really easy to expose.
01:34:41 - Alex Trost
Yeah, newsletter API keys are not re-rollable. And I'm like, that's not good.
01:34:50 - Anthony Campolo
Yeah, that's not good.
01:34:51 - Alex Trost
Yeah. Where am I putting these keys?
01:34:54 - Anthony Campolo
Where it says Configure, yes — top left, right next to the name. Yeah, yeah. All right, I think I'll just drop it in there.
01:35:05 - Alex Trost
Is that going to hide?
01:35:06 - Anthony Campolo
I think right now it's hiding it. So I'll show it. Yeah, there you go.
01:35:08 - Alex Trost
My keys.
01:35:09 - Anthony Campolo
Just save, don't hit Create Account. Thank you. Yeah. And then so I've got a query that I need to —
01:35:20 - Alex Trost
So what is the Google Cloud Natural Language API? I'm not even familiar with it.
01:35:26 - Anthony Campolo
Yeah. It's basically Google exposing their natural language processing capabilities through an API. Google has tons of things like TensorFlow and all these deep learning services on their cloud. This is a way that you can use those without needing to know how to train a model yourself and do all that stuff.
01:35:53 - Alex Trost
Got it. Cool. All right, so am I still going to run this, or —
01:35:59 - Anthony Campolo
Hold on one second.
01:36:00 - Alex Trost
Sorry, I had to click the button. I couldn't not click the button.
01:36:06 - Anthony Campolo
Yeah, see what it's spitting out for you?
01:36:09 - Alex Trost
So, "classify text." Oh, so I'm asking Google to use its big brain and tell me what this text is about. The content — "the weekend side of our hard-working hoodies with a relaxed fit and ultra spongy fabric, 100% cotton, French Terry, blah, blah, blah." So Google comes back — and chat, there's not a great way for me to make this big and have you see things. I can't minimize this site or anything. So I'm going to make it a little smaller and read it.
01:36:39 - Anthony Campolo
Grab the query I just dropped in your Discord messages and run that, because this is going to show us exactly what we want.
01:36:47 - Alex Trost
Austin, I'm so sorry. Sorry, I'm triggering Frugal Homes. Gotta be careful. Sorry about that, Austin. That's my fault. All right, so I did grab the query. Drop it in here or schema?
01:37:05 - Anthony Campolo
Yeah, no, in query.
01:37:07 - Alex Trost
Okay, cool. All right.
01:37:10 - Anthony Campolo
So what this is going to do is send the message "I feel happy," and it will let us know how happy it actually feels. Yes. So now change the word "happy" to "sad" and rerun it.
01:37:23 - Alex Trost
This is how they become sentient. Interesting.
01:37:27 - Anthony Campolo
So what it's doing is giving you what's called the polarity of your speech. It basically looks at the words and says whether it's positive or negative, and how strongly so. "I feel..." — I usually try to feel exactly in the middle. Yeah, this is funny.
01:37:45 - Alex Trost
Even "neutral." If I say "I feel neutral," that's still somewhat positive. "I feel —"
01:37:51 - Anthony Campolo
I feel exactly in the middle.
01:37:54 - Alex Trost
"I feel nothing." "Meh" is worse than nothing. "I feel nothing" is pretty dark to me, but Google thinks it's not as bad as "meh." All right. I'm learning a lot about humans and people and about Ben.
01:38:14 - Alex Trost
Wait, hold on. Let's see what we got. All right. "It's a step in the right direction." I wonder if spaces matter. Nope. This is interesting. Still a nine. All right, let's make some marks. So what is special about what we just did? Can you explain what's neat about this?
01:38:57 - Anthony Campolo
Yeah. If you click over to where it says the schema now, so next to query — yeah. What you see here is what we have been writing throughout this whole episode. We've been writing these GraphQL schemas. And if you keep going down to query, eventually you'll see where it's actually feeding in the endpoint itself. All of this GraphQL code has been written for you. So if you don't want to connect your own bespoke API and just want to deal with these already-known services, the schemas are all there for you. You don't have to write a single line of GraphQL to do this.
01:39:33 - Alex Trost
Got it. Okay, so basically — if I'm understanding this correctly — is there a way to make this part bigger? No. So this is like, hey, you're almost doing an "if this, then that" or a Zapier kind of thing where these are all popular APIs that you might want to hit, and here's that integration. Now you can write the queries without having to come up with the schema itself. It feels like where Zapier is a no-code solution, this is still a code solution, but a lower-code solution. Like, I would love to integrate with Trello and Spotify, but I need more than what Zapier would give me. I need a bit more nuanced querying. But I don't want to go through the pains of actually integrating with Spotify — and assume this is going to — oh, whoa. Did that just — oh, wow. Is that going to actually work?
01:40:53 - Anthony Campolo
So you might need a Spotify key.
01:40:56 - Alex Trost
So that's what I thought. Yeah, yeah. Absolutely, would need to configure. I was just clicking around. But that's awesome.
01:41:06 - Anthony Campolo
And so there was one other one I wanted to show. So add in the Dev.to one.
01:41:09 - Alex Trost
Dev.to.
01:41:11 - Anthony Campolo
Yeah.
01:41:11 - Alex Trost
This is great — "configure Dev.to API keys." Should I go grab one or did you drop me one?
01:41:18 - Anthony Campolo
I dropped you one? Yeah.
01:41:19 - Alex Trost
Cool. I thought I did see it in chat earlier.
01:41:22 - Anthony Campolo
Nope. Yep. Cool. And then I have a query too. So for this one, basically what you do is you have a "get comments by" — yeah, let's try that one. So what I'm going to do is have it return comments on an article specified with the article ID. The reasoning for that is — the goal here, what I've already showed how to do in a blog post, is that you are able to chain the query that gets you your blog comments into the — I have another one I was testing, but the comment it shows actually has a swear word in it. So I don't want that popping up on screen right now. I think it's just because of the ID we're feeding it.
01:42:47 - Alex Trost
Click what Ben dropped in chat. I have no shock. Yeah, that was definitely the mood there, Ben. I agree. All right, we're here. Interesting. Did you drop me something yet? Wasn't sure.
01:43:11 - Anthony Campolo
Yeah, this is fine. This gets across the idea. So go to the thing I just linked. I'm just going to kind of walk through it. Since we're almost out of time, the next step you can do is export this project and extend it with anything you want. What this is is basically what we just walked through here. So keep going, keep going — and then where it says @sequence. Yeah, right there. And if you bump up your font a little bit.
01:43:57 - Alex Trost
Yeah, okay, awesome.
01:43:59 - Anthony Campolo
This is essentially taking the first query — the "get comments by article ID" query — and feeding it into the "get natural language analyze sentiment" query, mapping the body HTML to the content. Now, that's not going to work — no, yeah, because this needs to be in the schema. This is why you would need to export the project and then add it in and spin up stepzen start. There is a bit of friction there. But if you scroll down a little more, then you'll see — there you can feed in the comment, and this is a positive one, so it's giving 0.8. And if you scroll down a little more, it's an article I wrote where there are some salty comments, so it has a polarity of -0.04.
01:44:55 - Alex Trost
That's funny. That's really interesting that you can use that bit of AI to assess which of your posts made people the most happy — not just, did they engage with it. And do people engage more with the stuff they're angry at or the stuff they enjoy? Based on social media and the world today, I'm willing to bet they engage more with the negative comments. I'm not encouraging that — I'm just saying. It's very interesting what you can do with things like this, and really cool that StepZen allows you to pipe one into the next and surface it all in one API. That's great. "How do you add a secret, e.g., OpenWeather?" It's over on the left under config.
01:45:49 - Anthony Campolo
That was the configure button we were clicking earlier.
01:45:54 - Alex Trost
Got it.
01:45:54 - Anthony Campolo
Yeah. Any time you click an integration that needs a key, you'll have a configure button next to it, and you just add it in.
01:46:02 - Alex Trost
Really cool. And then the Pokémon one is open, right? So we can just query for Pokémon. "Deploying your endpoint." That happens so quick I barely even noticed.
01:46:23 - Anthony Campolo
You gotta get your Pokémon.
01:46:25 - Alex Trost
Gotta. Pokémon abilities. Pokémon. Snow — so it gives me all the abilities and it gives me ten actual Pokémon, the first ten. Really cool. And then so with @sequence, I can get one, maybe put the description of a Pokémon into the Google Natural Language and see what they think about how friendly that one is or something. Lots of stuff you can do here. And then you can also eject — this is what you said.
01:47:07 - Anthony Campolo
Yeah, exactly. If you click the publish button, it'll publish it for you, and then basically that just spits out a project that is like the one we were creating throughout the first hour.
01:47:17 - Alex Trost
Got it. Oh, and then you have pre-built combinations.
01:47:20 - Anthony Campolo
So these are already kind of combined. So like the social media sentiment analysis brings in some other sentiment analysis stuff. And you can do currency conversions. You can do image search. All sorts of stuff.
01:47:33 - Alex Trost
Oh, this is cool. Yeah — Twitter and Unsplash contextual image search. Outdoor dining search: Google Maps plus OpenWeather plus Yelp. Really cool stuff. But it doesn't lock you in the way that an "if this, then that" — or a no-code solution like Zapier — would. This is a way to search and combine different sources of data and also connect your own. This is so cool, man.
01:48:19 - Anthony Campolo
Yeah, awesome. I'm glad you're enjoying it. I hope you'll find use for it and possibly use it for something. It would definitely be super fun to just get to hack on some of this stuff together and build something actually useful, because we don't want this to just be a theoretical project — people build actual real useful things with this. I'm always happy to get a chance to show it off and see people's reactions. This has been really, really fun. If anyone has any other questions, feel free to drop them in the chat. But that's essentially everything I wanted to show. I didn't show how to build out a frontend and connect it to a StepZen API, but we have lots of tutorials for that — whether it's a React, Vue, or Svelte frontend. Anything that can make a fetch request can integrate with this. It's a really great tool. The front of the back end — that's what I think of it as. People always talk about the front of the front end and the back of the front end.
01:49:19 - Anthony Campolo
This is the front of the back end. It's a cool tool to give you access to a lot of backend powers and make you more full-stack as a frontend dev.
01:49:29 - Alex Trost
That's great. Awesome, man. Thank you so much. Chat, do we have any questions? I think we've been mostly answering them as we go. Has anyone wondered anything? No, I did not plug it and I didn't see anyone do that. So I apologize for not — makes sense.
01:49:50 - Anthony Campolo
All good.
01:49:50 - Alex Trost
Yeah, seems pretty clear.
01:49:51 - Anthony Campolo
Seems pretty clear.
01:49:53 - Alex Trost
It's awesome.
01:49:53 - Anthony Campolo
Good to hear. Because this thing confused the crap out of me when I first learned StepZen — made no sense for like a month or two. Glad I can hopefully make it a little more comprehensible to people.
01:50:05 - Alex Trost
Cynthia says it's great. It's awesome. Disco, are you still here by chance? Because maybe we can take that one offline. Don't want to —
01:50:13 - Anthony Campolo
Yeah, he was asking about money things.
01:50:15 - Alex Trost
Yeah. I don't know if I'm going to be the best person for that. Sorry — "give them the dude, share the profits." Especially if there's real money involved.
01:50:32 - Anthony Campolo
Yeah, you should talk to a legal expert.
01:50:34 - Alex Trost
"Made me around 2.5 mil. Yeah, he's had around $250,000." Yeah. There's this much money involved — it's going to come down mainly to lawyers and proof unfortunately. And I know that's not fun. Sorry that you're going through that.
01:51:03 - Anthony Campolo
Alex Trost told me.
01:51:05 - Alex Trost
I mean yeah — but Anthony, this was really cool. Thank you. Chat, you were all fantastic. Really appreciated the questions and just having you all here. And Ben, thank you for saving our butts with that quick deletion. You are top pro. Igad, thank you. Folks, this is — in case you didn't hear me say it before — the last stream of the year. And I just want to say, wow, it has been a phenomenal year. We started really streaming in February. We haven't even been streaming for a full year yet. We did a couple of streams the year before, but not really. So I just want to say thank you so much for everything — for showing up, for being so supportive, for asking questions, and for all of this. It's been an honor to make it to the end of the last stream. Amit, great to see you, my friend. Brent, great to see you. So yeah, thank you for a phenomenal year. And Anthony, and everyone like Amit and like Ben and others who have come on and given us their time and energy and taught us so much this year.
01:52:34 - Alex Trost
We've had a lot of episodes and yeah, just really want to say thank you for an awesome year. We will be back in January.
01:52:41 - Anthony Campolo
Thank you for hosting and for putting it all together and doing the thing.
01:52:45 - Alex Trost
Of course, man.
01:52:46 - Anthony Campolo
The community very much appreciates you.
01:52:48 - Alex Trost
Thank you. Yeah, it's honestly been a joy. Did not expect all of this coming into the new year. Came into a new job, and the stream kind of — oh yeah, we can mess around with the stream — and then it seemed like we needed a Discord, and it's just been this incredible community thing that ended the year with us doing a good thing for the world as a community. So I'm excited to see what happens next year, and just appreciate all of you. Hope everyone out there has a wonderful holiday and wonderful new year. Whoa. Ben, thank you so much for those gifted subs. Really appreciate you. So kind, my friend. Super generous. Thank you so much. But yeah, hope everyone has a phenomenal holiday and great new year. I'll see you in 2022. If you're not in the Discord, I would love to see you before then. So join the Discord. Let me see if I have the button here. I do — that's the Discord. There's the button. Thank you so much. And Anthony, you want to plug anything before we head out?
01:53:55 - Anthony Campolo
Oh, I mean, stepzen.com for StepZen stuff, redwoodjs.com for Redwood stuff. And then I'd be remiss not to mention fsjam.org — this is my podcast. We've had the great Alex Trost as a guest, along with Ben and other people. Had Cassie Evans just very recently. So fsjam.org is my podcast that I've been doing with Christopher Burns for over a year now. We started October of last year, so we're about a year and two months in. We've got about 60 episodes right now. That's a very fun, fulfilling thing for me to do. We have lots of conversations with people from — like we've had people from Supabase and a lot of the tech we've shown here. If this interests you, if you think these projects are cool and you want to learn more, it's a really great resource to dig into this huge cornucopia of stuff that we've looked at today.
01:54:57 - Alex Trost
Great. Awesome. Yes, definitely check out fsjam.org. And you were so much fun to talk to, so I really appreciate it. And Cynthia says she's gonna check it out. Thank you so much, Cynthia. So folks, that's it. Hope you have a great day and we will see you later. Take care. Let's find someone to raid — let's go drop by there and have a great new year. Bye.
01:55:43 - Anthony Campolo
[unclear]