DEV Community

Alex Spinov
Alex Spinov

Posted on

RedwoodJS Has a Free API That Gives You a Full-Stack Framework in One Command

RedwoodJS is the full-stack React framework with GraphQL, Prisma, auth, and deployment built in. One yarn rw command scaffolds everything.

Cells: Data-Fetching Components

// web/src/components/ProductsCell/ProductsCell.tsx
import type { ProductsQuery } from "types/graphql";
import type { CellSuccessProps, CellFailureProps } from "@redwoodjs/web";

export const QUERY = gql`
  query ProductsQuery {
    products {
      id
      title
      price
      scrapedAt
    }
  }
`;

export const Loading = () => <Spinner />;
export const Empty = () => <div>No products found</div>;
export const Failure = ({ error }: CellFailureProps) => <div>Error: {error.message}</div>;

export const Success = ({ products }: CellSuccessProps<ProductsQuery>) => (
  <ul>
    {products.map((product) => (
      <li key={product.id}>{product.title} — ${product.price}</li>
    ))}
  </ul>
);
Enter fullscreen mode Exit fullscreen mode

SDL + Services: Type-Safe API Layer

# api/src/graphql/products.sdl.ts
export const schema = gql`
  type Product {
    id: Int!
    title: String!
    price: Float!
    url: String!
    scrapedAt: DateTime!
  }

  type Query {
    products: [Product!]! @requireAuth
    product(id: Int!): Product @requireAuth
  }

  input CreateProductInput {
    title: String!
    price: Float!
    url: String!
  }

  type Mutation {
    createProduct(input: CreateProductInput!): Product! @requireAuth(roles: ["admin"])
    deleteProduct(id: Int!): Product! @requireAuth(roles: ["admin"])
  }
`;
Enter fullscreen mode Exit fullscreen mode
// api/src/services/products/products.ts
import { db } from "src/lib/db";

export const products = () => db.product.findMany({ orderBy: { scrapedAt: "desc" } });
export const product = ({ id }: { id: number }) => db.product.findUnique({ where: { id } });
export const createProduct = ({ input }) => db.product.create({ data: input });
Enter fullscreen mode Exit fullscreen mode

Auth: Built-In Providers

// web/src/App.tsx
import { AuthProvider, useAuth } from "@redwoodjs/auth";

// Supports: dbAuth, Supabase, Clerk, Auth0, Firebase, custom

function LoginButton() {
  const { isAuthenticated, logIn, logOut, currentUser } = useAuth();
  return isAuthenticated
    ? <button onClick={logOut}>Logout {currentUser.email}</button>
    : <button onClick={logIn}>Login</button>;
}
Enter fullscreen mode Exit fullscreen mode

CLI: Scaffolding Magic

# Generate everything for a model
yarn rw generate scaffold product
# Creates: SDL, service, Cell, CRUD pages, Storybook stories, tests

# Generate specific pieces
yarn rw generate cell Products
yarn rw generate page Home /
yarn rw generate service Product

# Deploy
yarn rw deploy vercel
yarn rw deploy netlify
yarn rw deploy aws-serverless
Enter fullscreen mode Exit fullscreen mode

Prisma Integration

// api/db/schema.prisma
model Product {
  id        Int      @id @default(autoincrement())
  title     String
  price     Float
  url       String   @unique
  category  String?
  scrapedAt DateTime @default(now())
  reviews   Review[]
}
Enter fullscreen mode Exit fullscreen mode

Build full-stack scraping dashboards? My Apify tools + RedwoodJS = complete data platform.

Custom full-stack solution? Email spinov001@gmail.com

Top comments (0)