Receber por email
← Voltar para o catálogo

node-backend

Build Node.js backends for Shopify apps — Remix server, @shopify/shopify-app-remix, session storage, OAuth handling, API proxy, webhook processing, and deployment. Use when building the server-side component of Shopify apps.

34estrelas
Atualizado há 5 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add OrcaQubits/agentic-commerce-skills-plugins

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/node-backend-mrj68r8l/svg)](https://www.skillteca.com.br/skills/node-backend-mrj68r8l)

Alerta por categoria

Receba novas skills de Design e Frontend toda segunda

1 email curto, só com as skills novas de Design e Frontend. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Node.js Backend for Shopify Apps

Before writing code

Fetch live docs:

  1. Web-search site:shopify.dev app remix server for Remix app server patterns
  2. Web-search site:github.com shopify shopify-app-js for Shopify Node.js libraries
  3. Web-search site:shopify.dev session storage for session management options

App Server Architecture

Typical Stack

Shopify Admin (iframe)
    ↓ App Bridge session token
Remix Server (@shopify/shopify-app-remix)
    ↓ GraphQL Admin API calls
Shopify APIs
    ↓ Webhooks
Your Webhook Handler

Key Packages

| Package | Purpose | |---------|---------| | @shopify/shopify-app-remix | Remix integration (auth, session, billing, webhooks) | | @shopify/shopify-api | Low-level Shopify API client | | @shopify/app-bridge-react | App Bridge React components | | @shopify/polaris | Admin UI components |

Project Structure

shopify-app/
├── app/
│   ├── routes/
│   │   ├── app._index.tsx        # App dashboard
│   │   ├── app.products.tsx      # Products page
│   │   ├── auth.$.tsx            # OAuth callback handler
│   │   └── webhooks.tsx          # Webhook endpoint
│   ├── shopify.server.ts         # Shopify API client initialization
│   ├── db.server.ts              # Database connection
│   └── root.tsx                  # Root layout
├── prisma/
│   └── schema.prisma             # Database schema (session storage)
├── extensions/                   # App extensions (Functions, checkout UI)
├── shopify.app.toml              # App configuration
├── .env
└── package.json

Shopify App Remix Setup

Server Initialization

// app/shopify.server.ts
import "@shopify/shopify-app-remix/adapters/node";
import { AppDistribution, shopifyApp } from "@shopify/shopify-app-remix/server";
import { PrismaSessionStorage } from "@shopify/shopify-app-session-storage-prisma";
import { prisma } from "./db.server";

const shopify = shopifyApp({
  apiKey: process.env.SHOPIFY_API_KEY!,
  apiSecretKey: process.env.SHOPIFY_API_SECRET!,
  appUrl: process.env.SHOPIFY_APP_URL!,
  scopes: process.env.SCOPES?.split(","),
  authPathPrefix: "/auth",
  sessionStorage: new PrismaSessionStorage(prisma),
  distribution: AppDistribution.AppStore,
  webhooks: {
    APP_UNINSTALLED: {
      deliveryMethod: "http",
      callbackUrl: "/webhooks",
    },
  },
  hooks: {
    afterAuth: async ({ session }) => {
      // Register webhooks after successful auth
      shopify.registerWebhooks({ session });
    },
  },
});

export default shopify;
export const apiVersion = shopify.apiVersion;
export const addDocumentResponseHeaders = shopify.addDocumentResponseHeaders;
export const authenticate = shopify.authenticate;
export const registerWebhooks = shopify.registerWebhooks;

Authentication in Loaders

// app/routes/app._index.tsx
import { json, type LoaderFunctionArgs } from "@remix-run/node";
import { authenticate } from "../shopify.server";

export async function loader({ request }: LoaderFunctionArgs) {
  const { admin } = await authenticate.admin(request);

  const response = await admin.graphql(`
    query {
      products(first: 10) {
        edges {
          node {
            id
            title
          }
        }
      }
    }
  `);

  const { data } = await response.json();
  return json({ products: data.products.edges });
}

Webhook Handler

// app/routes/webhooks.tsx
import type { ActionFunctionArgs } from "@remix-run/node";
import { authenticate } from "../shopify.server";

export async function action({ request }: ActionFunctionArgs) {
  const { topic, shop, payload } = await authenticate.webhook(request);

  switch (topic) {
    case "APP_UNINSTALLED":
      // Clean up shop data
      await deleteShopData(shop);
      break;
    case "CUSTOMERS_DATA_REQUEST":
      // Handle GDPR data request
      break;
    case "CUSTOMERS_REDACT":
      // Delete customer data
      break;
    case "SHOP_REDACT":
      // Delete all shop data
      break;
  }

  return new Response();
}

Session Storage Options

| Storage | Package | Use Case | |---------|---------|----------| | Prisma | @shopify/shopify-app-session-storage-prisma | Production (SQL databases) | | SQLite | @shopify/shopify-app-session-storage-sqlite | Development, small apps | | Redis | @shopify/shopify-app-session-storage-redis | High-traffic apps | | Memory | @shopify/shopify-app-session-storage-memory | Testing only | | DynamoDB | @shopify/shopify-app-session-storage-dynamodb | AWS deployments |

GraphQL Admin Client

The authenticated admin client handles:

  • Automatic token management
  • Rate limiting (retries on 429)
  • API versioning
  • Type-safe queries (with codegen)
// Make a GraphQL call
const response = await admin.graphql(`
  mutation ProductCreate($input: ProductInput!) {
    productCreate(input: $input) {
      product { id title }
      userErrors { field message }
    }
  }
`, {
  variables: {
    input: { title: "New Product" },
  },
});

REST Client (Legacy)

For endpoints not yet available in GraphQL:

const response = await admin.rest.get({
  path: 'themes',
});

Note: REST is deprecated. Use GraphQL whenever possible.

Deployment

Shopify-Hosted (Spin)

For apps using shopify app deploy:

  • Automatic hosting
  • Managed infrastructure
  • Environment variables in Shopify admin

Self-Hosted Options

| Platform | Setup | |----------|-------| | Vercel | vercel deploy | | Fly.io | fly deploy | | Railway | railway deploy | | Render | Git push | | AWS (ECS/Lambda) | SAM/CDK |

Environment Variables

SHOPIFY_API_KEY=your-api-key
SHOPIFY_API_SECRET=your-api-secret
SHOPIFY_APP_URL=https://your-app.example.com
SCOPES=read_products,write_products,read_orders
DATABASE_URL=file:./dev.db

Best Practices

  • Use @shopify/shopify-app-remix — do not build auth/session from scratch
  • Use Prisma for session storage in production (not SQLite or memory)
  • Authenticate every request with authenticate.admin(request)
  • Register webhooks in afterAuth hook — they need valid access tokens
  • Implement all GDPR webhooks in the webhook handler
  • Use GraphQL over REST for all API calls
  • Handle userErrors in GraphQL mutations — 200 status does not mean success
  • Store environment variables securely — never commit .env
  • Use shopify app dev for local development (handles tunneling and auth)

Fetch the Shopify Remix app documentation and @shopify/shopify-app-remix package docs for exact initialization, authentication, and deployment patterns before implementing.

Compartilhar X LinkedIn