Backend
This guide details the server-side structure and functionality of the Shopify Vue App template.
Directory Structure
server/
├── database/ # Database configuration and setup
│ └── database.js # Database initialization and connection handling
├── middlewares/ # Express middleware functions
│ └── user-middleware.js # User registration and session handling
├── models/ # Data models for database entities
│ └── sqlite/ # SQLite-specific model implementations
│ ├── user.js # User data management
│ └── webhooks.js # Webhook event tracking
├── routes/ # API endpoint definitions
│ └── products.js # Product management endpoints
├── services/ # Business logic and external services
│ └── shopify/ # Shopify-specific service implementations
├── utils/ # Helper functions and utilities
│ └── webhook-utils.js # Webhook validation and processing
├── webhooks/ # Webhook handlers and processors
│ └── webhooks.js # GDPR and app event handlers
├── index.js # Application entry point
└── shopify.js # Shopify app configuration
Core Components
1. Database Management (/database
)
The database layer provides:
js
// database/database.js
export function initDatabase() {
// Auto-creates SQLite database if not exists
// Initializes database connection
// Sets up User and Webhook tables
}
Supported Databases:
- SQLite (default for development)
- MySQL (production ready)
- PostgreSQL (production ready)
Example MySQL Configuration:
js
import { MySQLSessionStorage } from '@shopify/shopify-app-session-storage-mysql'
sessionStorage: MySQLSessionStorage.withCredentials(
process.env.DATABASE_HOST,
process.env.DATABASE_SESSION,
process.env.DATABASE_USER,
process.env.DATABASE_PASSWORD,
{ connectionPoolLimit: 100 }
)
2. Models (/models
)
User Model
Handles shop and user data:
js
// models/sqlite/user.js
export const User = {
create: async ({ shop }) => {}, // Create new user/shop
read: async (shop) => {}, // Get user/shop data
update: async (id, data) => {}, // Update user/shop info
delete: async (shop) => {} // Remove user/shop
}
Webhook Model
Manages webhook events:
js
// models/sqlite/webhooks.js
export const Webhook = {
create: async ({ webhook_id, topic, shop }) => {}, // Log new webhook
read: async (webhookId) => {}, // Get webhook details
update: async (webhookId, updates) => {} // Update webhook status
}
3. Middleware (/middlewares
)
User Registration
js
// middlewares/user-middleware.js
export async function registerUser(req, res, next) {
// Creates user record after app installation
// Links shop to user account
// Handles authentication flow
}
4. Routes (/routes
)
Product Routes
js
// routes/products.js
router.get('/count', async (req, res) => {
// Get product count using GraphQL
})
router.get('/create', async (req, res) => {
// Create sample products
})
5. Webhook System (/webhooks
)
Handles mandatory GDPR webhooks and app events:
js
// webhooks/webhooks.js
export default {
// Customer Data Request
CUSTOMERS_DATA_REQUEST: {
callback: async (topic, shop, body) => {
// Handle customer data requests
}
},
// Customer Data Deletion
CUSTOMERS_REDACT: {
callback: async (topic, shop, body) => {
// Handle customer data deletion
}
},
// Shop Data Deletion
SHOP_REDACT: {
callback: async (topic, shop, body) => {
// Handle shop data deletion
}
},
// App Uninstallation
APP_UNINSTALLED: {
callback: async (topic, shop, body) => {
// Clean up shop data
// Remove user records
}
}
}
6. Utils (/utils
)
Webhook Processing
js
// utils/webhook-utils.js
export function validateWebhookRequest(req, res, next) {
// Verify webhook HMAC
// Ensure request is from Shopify
// Process webhook payload
}
7. Services (/services
)
Product Management
js
// services/shopify/product-creator.js
export default async function productCreator(session) {
// Create sample products
// Handle GraphQL mutations
// Manage product data
}
Security Features
- Webhook Validation
- HMAC verification for all webhooks
- Timing-safe request validation
- Duplicate webhook prevention
- Authentication
- OAuth 2.0 flow with Shopify
- Session token validation
- Secure cookie handling
- Database Security
- Parameterized queries
- SQL injection prevention
- Data encryption support
Error Handling
- API Errors
js
try {
const response = await client.request(query)
} catch (error) {
if (error instanceof GraphqlQueryError) {
// Handle GraphQL specific errors
}
// Handle general errors
}
- Webhook Errors
js
export async function processWebhook(topic, shop, body, webhookId) {
try {
// Process webhook
} catch (error) {
// Log error
// Prevent duplicate processing
} finally {
// Mark webhook as processed
}
}
Best Practices
- Database Operations
- Use model abstraction
- Implement CRUD operations
- Handle foreign key relationships
- Maintain data integrity
- API Design
- RESTful principles
- Proper status codes
- Error response format
- Rate limiting
- Security
- Input validation
- Output sanitization
- Secure headers
- CORS configuration
- Performance
- Connection pooling
- Query optimization
- Caching strategies
- Asynchronous processing
Environment Configuration
Required environment variables:
bash
SHOPIFY_API_KEY= # Your app's API key
SHOPIFY_API_SECRET= # Your app's API secret
SCOPES= # Required app scopes
HOST= # App's host URL
DATABASE_URL= # Production database URL
Deployment Considerations
- Database Migration
- Backup strategy
- Schema updates
- Data preservation
- Rollback plans
- Environment Setup
- Production vs development
- Secure key management
- Database configuration
- Logging setup
- Monitoring
- Error tracking
- Performance metrics
- Webhook reliability
- Database health