E-Commerce Use Case
Build a complete e-commerce backend with Backflow.
Overview
This guide demonstrates building an e-commerce API with:
- Product catalog management
- Shopping cart functionality
- Order processing with Stripe
- Inventory tracking
- Customer notifications
Route Aliasing
Use route aliases for domain-specific endpoints.
json
{
"routeAliases": {
"products": "/api/v1/products",
"cart": "/api/v1/cart",
"orders": "/api/v1/orders",
"checkout": "/api/v1/checkout",
"reviews": "/api/v1/reviews"
}
}Product Catalog
List Products
json
{
"path": "/products",
"method": "get",
"supabaseQueries": [{
"table": "products",
"operation": "select",
"select": "*, categories(name), variants(*)",
"filters": [
{ "column": "is_active", "operator": "eq", "value": true }
],
"order": { "column": "created_at", "ascending": false },
"limit": "{{query.limit || 20}}",
"offset": "{{query.offset || 0}}"
}],
"cache": {
"enabled": true,
"ttl": 300
}
}Search Products
json
{
"path": "/products/search",
"method": "get",
"supabaseQueries": [{
"table": "products",
"operation": "select",
"select": "*",
"filters": [
{ "column": "name", "operator": "ilike", "value": "%{{query.q}}%" },
{ "column": "is_active", "operator": "eq", "value": true }
]
}]
}Get Product by ID
json
{
"path": "/products/:id",
"method": "get",
"supabaseQueries": [{
"table": "products",
"operation": "select",
"select": "*, categories(name), variants(*), reviews(*, users(name))",
"filters": [
{ "column": "id", "operator": "eq", "value": "{{params.id}}" }
],
"single": true
}],
"cache": {
"enabled": true,
"ttl": 600,
"key": "product:{{params.id}}"
}
}Product by Category
json
{
"path": "/categories/:slug/products",
"method": "get",
"supabaseQueries": [
{
"table": "categories",
"operation": "select",
"filters": [
{ "column": "slug", "operator": "eq", "value": "{{params.slug}}" }
],
"single": true,
"alias": "category"
},
{
"table": "products",
"operation": "select",
"filters": [
{ "column": "category_id", "operator": "eq", "value": "{{results.category.id}}" },
{ "column": "is_active", "operator": "eq", "value": true }
]
}
]
}Shopping Cart
Get Cart
json
{
"path": "/cart",
"method": "get",
"requireAuth": true,
"supabaseQueries": [{
"table": "cart_items",
"operation": "select",
"select": "*, products(id, name, price, image_url)",
"filters": [
{ "column": "user_id", "operator": "eq", "value": "{{auth.sub}}" }
]
}]
}Add to Cart
json
{
"path": "/cart",
"method": "post",
"requireAuth": true,
"validation": {
"body": {
"product_id": { "type": "string", "required": true },
"quantity": { "type": "number", "min": 1, "required": true },
"variant_id": { "type": "string" }
}
},
"supabaseQueries": [{
"table": "cart_items",
"operation": "upsert",
"data": {
"user_id": "{{auth.sub}}",
"product_id": "{{body.product_id}}",
"variant_id": "{{body.variant_id}}",
"quantity": "{{body.quantity}}"
},
"onConflict": ["user_id", "product_id", "variant_id"],
"select": "*, products(name, price)"
}]
}Update Cart Item
json
{
"path": "/cart/:itemId",
"method": "put",
"requireAuth": true,
"supabaseQueries": [{
"table": "cart_items",
"operation": "update",
"data": {
"quantity": "{{body.quantity}}"
},
"filters": [
{ "column": "id", "operator": "eq", "value": "{{params.itemId}}" },
{ "column": "user_id", "operator": "eq", "value": "{{auth.sub}}" }
],
"select": "*"
}]
}Remove from Cart
json
{
"path": "/cart/:itemId",
"method": "delete",
"requireAuth": true,
"supabaseQueries": [{
"table": "cart_items",
"operation": "delete",
"filters": [
{ "column": "id", "operator": "eq", "value": "{{params.itemId}}" },
{ "column": "user_id", "operator": "eq", "value": "{{auth.sub}}" }
]
}]
}Checkout & Orders
Create Checkout Session
json
{
"path": "/checkout",
"method": "post",
"requireAuth": true,
"workflow": {
"id": "checkout-flow",
"steps": [
{
"id": "get-cart",
"type": "database",
"params": {
"table": "cart_items",
"operation": "select",
"select": "*, products(id, name, price, stock)",
"filters": [
{ "column": "user_id", "operator": "eq", "value": "{{auth.sub}}" }
]
}
},
{
"id": "validate-stock",
"type": "transform",
"input": "{{steps.get-cart.result}}",
"operations": [{
"type": "filter",
"condition": "item.quantity <= item.products.stock"
}]
},
{
"id": "create-stripe-session",
"type": "integration",
"integration": "stripe",
"action": "createCheckoutSession",
"params": {
"line_items": "{{steps.validate-stock.result}}",
"success_url": "{{body.success_url}}",
"cancel_url": "{{body.cancel_url}}",
"customer_email": "{{auth.email}}"
}
}
]
}
}Create Order (Webhook)
json
{
"webhooks": [{
"name": "stripe-checkout",
"path": "/webhooks/stripe",
"provider": "stripe",
"secret": "{{env.STRIPE_WEBHOOK_SECRET}}",
"actions": [{
"condition": "{{payload.type}} === 'checkout.session.completed'",
"workflow": {
"steps": [
{
"id": "create-order",
"type": "database",
"params": {
"table": "orders",
"operation": "insert",
"data": {
"user_id": "{{payload.data.object.client_reference_id}}",
"stripe_session_id": "{{payload.data.object.id}}",
"amount_total": "{{payload.data.object.amount_total}}",
"status": "paid"
}
}
},
{
"id": "get-cart-items",
"type": "database",
"params": {
"table": "cart_items",
"operation": "select",
"select": "*, products(*)",
"filters": [
{ "column": "user_id", "operator": "eq", "value": "{{payload.data.object.client_reference_id}}" }
]
}
},
{
"id": "create-order-items",
"type": "forEach",
"items": "{{steps.get-cart-items.result}}",
"step": {
"type": "database",
"params": {
"table": "order_items",
"operation": "insert",
"data": {
"order_id": "{{steps.create-order.result.id}}",
"product_id": "{{item.product_id}}",
"quantity": "{{item.quantity}}",
"price": "{{item.products.price}}"
}
}
}
},
{
"id": "update-inventory",
"type": "forEach",
"items": "{{steps.get-cart-items.result}}",
"step": {
"type": "database",
"params": {
"table": "products",
"operation": "update",
"data": {
"stock": "products.stock - {{item.quantity}}"
},
"filters": [
{ "column": "id", "operator": "eq", "value": "{{item.product_id}}" }
]
}
}
},
{
"id": "clear-cart",
"type": "database",
"params": {
"table": "cart_items",
"operation": "delete",
"filters": [
{ "column": "user_id", "operator": "eq", "value": "{{payload.data.object.client_reference_id}}" }
]
}
},
{
"id": "send-confirmation",
"type": "integration",
"integration": "sendgrid",
"action": "sendTemplate",
"params": {
"to": "{{payload.data.object.customer_details.email}}",
"templateId": "order-confirmation",
"dynamicTemplateData": {
"orderId": "{{steps.create-order.result.id}}",
"total": "{{payload.data.object.amount_total}}"
}
}
}
]
}
}]
}]
}Get Orders
json
{
"path": "/orders",
"method": "get",
"requireAuth": true,
"supabaseQueries": [{
"table": "orders",
"operation": "select",
"select": "*, order_items(*, products(name, image_url))",
"filters": [
{ "column": "user_id", "operator": "eq", "value": "{{auth.sub}}" }
],
"order": { "column": "created_at", "ascending": false }
}]
}Get Order by ID
json
{
"path": "/orders/:id",
"method": "get",
"requireAuth": true,
"supabaseQueries": [{
"table": "orders",
"operation": "select",
"select": "*, order_items(*, products(*)), shipments(*)",
"filters": [
{ "column": "id", "operator": "eq", "value": "{{params.id}}" },
{ "column": "user_id", "operator": "eq", "value": "{{auth.sub}}" }
],
"single": true
}]
}Reviews
Create Review
json
{
"path": "/products/:productId/reviews",
"method": "post",
"requireAuth": true,
"validation": {
"body": {
"rating": { "type": "number", "min": 1, "max": 5, "required": true },
"title": { "type": "string", "maxLength": 100 },
"content": { "type": "string", "maxLength": 2000 }
}
},
"supabaseQueries": [
{
"table": "order_items",
"operation": "select",
"select": "orders!inner(user_id)",
"filters": [
{ "column": "product_id", "operator": "eq", "value": "{{params.productId}}" },
{ "column": "orders.user_id", "operator": "eq", "value": "{{auth.sub}}" }
],
"alias": "purchased"
},
{
"table": "reviews",
"operation": "insert",
"condition": "{{results.purchased.length}} > 0",
"data": {
"product_id": "{{params.productId}}",
"user_id": "{{auth.sub}}",
"rating": "{{body.rating}}",
"title": "{{body.title}}",
"content": "{{body.content}}"
},
"select": "*"
}
]
}Get Product Reviews
json
{
"path": "/products/:productId/reviews",
"method": "get",
"supabaseQueries": [{
"table": "reviews",
"operation": "select",
"select": "*, users(name, avatar_url)",
"filters": [
{ "column": "product_id", "operator": "eq", "value": "{{params.productId}}" },
{ "column": "is_approved", "operator": "eq", "value": true }
],
"order": { "column": "created_at", "ascending": false }
}],
"cache": {
"enabled": true,
"ttl": 300
}
}Inventory Management
Update Stock
json
{
"path": "/admin/products/:id/stock",
"method": "put",
"requireAuth": true,
"rbac": {
"roles": ["admin", "inventory_manager"]
},
"supabaseQueries": [{
"table": "products",
"operation": "update",
"data": {
"stock": "{{body.stock}}",
"low_stock_threshold": "{{body.low_stock_threshold}}"
},
"filters": [
{ "column": "id", "operator": "eq", "value": "{{params.id}}" }
],
"select": "id, name, stock"
}],
"integrations": [{
"condition": "{{body.stock}} <= {{body.low_stock_threshold}}",
"type": "slack",
"action": "sendMessage",
"params": {
"channel": "#inventory-alerts",
"text": "Low stock alert: {{params.id}} has {{body.stock}} units"
}
}]
}Low Stock Report
json
{
"path": "/admin/inventory/low-stock",
"method": "get",
"requireAuth": true,
"rbac": {
"roles": ["admin", "inventory_manager"]
},
"supabaseQueries": [{
"table": "products",
"operation": "select",
"select": "id, name, stock, low_stock_threshold",
"filters": [
{ "column": "stock", "operator": "lte", "raw": "low_stock_threshold" }
],
"order": { "column": "stock", "ascending": true }
}]
}Complete Configuration
json
{
"routeAliases": {
"products": "/api/v1/products",
"cart": "/api/v1/cart",
"orders": "/api/v1/orders",
"checkout": "/api/v1/checkout",
"reviews": "/api/v1/reviews",
"admin": "/api/v1/admin"
},
"supabase": {
"url": "{{env.SUPABASE_URL}}",
"anonKey": "{{env.SUPABASE_ANON_KEY}}"
},
"jwt": {
"secret": "{{env.JWT_SECRET}}",
"expiresIn": "24h"
},
"credentials": {
"stripe": {
"secretKey": "{{env.STRIPE_SECRET_KEY}}"
},
"sendgrid": {
"apiKey": "{{env.SENDGRID_API_KEY}}",
"fromEmail": "orders@yourstore.com"
},
"slack": {
"webhookUrl": "{{env.SLACK_WEBHOOK_URL}}"
}
},
"cache": {
"provider": "redis",
"url": "{{env.REDIS_URL}}"
},
"routes": [
{ "path": "/products", "method": "get", "...": "..." },
{ "path": "/cart", "method": "get", "...": "..." }
],
"webhooks": [
{ "name": "stripe-checkout", "path": "/webhooks/stripe", "...": "..." }
]
}Database Schema
sql
-- Products
CREATE TABLE products (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL,
description TEXT,
price DECIMAL(10,2) NOT NULL,
stock INTEGER DEFAULT 0,
low_stock_threshold INTEGER DEFAULT 10,
category_id UUID REFERENCES categories(id),
image_url TEXT,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ DEFAULT now()
);
-- Cart Items
CREATE TABLE cart_items (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL,
product_id UUID REFERENCES products(id),
variant_id UUID,
quantity INTEGER DEFAULT 1,
created_at TIMESTAMPTZ DEFAULT now(),
UNIQUE(user_id, product_id, variant_id)
);
-- Orders
CREATE TABLE orders (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL,
stripe_session_id TEXT,
amount_total INTEGER,
status TEXT DEFAULT 'pending',
created_at TIMESTAMPTZ DEFAULT now()
);
-- Order Items
CREATE TABLE order_items (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
order_id UUID REFERENCES orders(id),
product_id UUID REFERENCES products(id),
quantity INTEGER,
price DECIMAL(10,2)
);
-- Reviews
CREATE TABLE reviews (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
product_id UUID REFERENCES products(id),
user_id UUID NOT NULL,
rating INTEGER CHECK (rating >= 1 AND rating <= 5),
title TEXT,
content TEXT,
is_approved BOOLEAN DEFAULT false,
created_at TIMESTAMPTZ DEFAULT now()
);