Core Concepts
Understanding the core concepts of the Asterisms JS SDK Backend will help you build robust and scalable applications.
SDK Architecture
The Asterisms JS SDK Backend follows a service-oriented architecture where each service provides specific functionality:
interface AsterismsBackendSDK {
authorization(): AuthorizationService;
storage(): StorageService;
notifications(): NotificationSendingService;
registration(): RegistrationService;
discovery(): DiscoveryService;
information(): InformationService;
logging(): AsterismsLogger;
boot(): Promise<void>;
isBooted(): boolean;
}
Service Lifecycle
1. Initialization
The SDK is initialized with configuration properties:
import { createFetchAdapter } from '@asterisms/common-core';
const sdk = getAsterismsBackendSDK({
bundleId: 'com.example.app',
domain: 'asterisms.example.com',
subdomain: 'app',
httpServiceAdapterFactory: createFetchAdapter(fetch),
registrationData: {
bundleId: 'com.example.app',
capabilities: ['FRONTEND_WEBSITE'],
description: 'My Application',
name: 'My App',
subdomain: 'app',
title: 'My App'
}
});
2. Booting
The SDK must be booted before use:
During boot, the SDK:
- Establishes connections to core services
- Validates configuration
- Registers the application with the ecosystem
- Initializes internal services
3. Service Access
Once booted, services are available through the SDK:
const auth = sdk.authorization();
const storage = sdk.storage();
const notifications = sdk.notifications();
Key Concepts
Bundle ID
A Bundle ID is a unique identifier for your application within the Asterisms ecosystem:
// Good: Reverse domain notation
bundleId: 'com.company.product.service';
// Good: Organization-based
bundleId: 'io.asterisms.workspace';
// Avoid: Generic names
bundleId: 'myapp';
Registration Data
Registration data describes your application to the ecosystem:
interface RegistrationData {
bundleId: string;
capabilities: string[];
description: string;
name: string;
subdomain: string;
title: string;
icon?: string;
group?: string;
}
Key fields:
bundleId: Unique application identifier
capabilities: What your app can do (e.g., 'FRONTEND_WEBSITE', 'BACKEND_SERVICE')
subdomain: URL subdomain for your service
name: Internal name for your service
title: Display name for users
Capabilities
Capabilities define what your application can do:
const capabilities = [
'FRONTEND_WEBSITE', // Web frontend
'BACKEND_SERVICE', // Backend API service
'WEBHOOKS', // Webhook handling
'SCHEDULED_TASKS', // Background tasks
'DATA_PROCESSING' // Data processing
];
HTTP Service Adapter
The SDK uses adapters to handle HTTP requests:
import { createFetchAdapter } from '@asterisms/common-core';
const httpFactory = createFetchAdapter(fetch);
This abstraction allows the SDK to work in different environments (Node.js, browsers, edge functions).
Service Overview
Authorization Service
Handles user authentication and authorization:
const auth = sdk.authorization();
// Resolve authenticated actor from token
const actor = await auth.resolveAuthenticatedActor('Bearer token');
// Verify token
const verification = await auth.verifyToken('Bearer token');
if (verification.valid) {
console.log('User claims:', verification.claims);
}
// Generate IPC token for service-to-service communication
const ipcToken = await auth.generateIpcToken('https://platform.example.com');
Storage Service
Provides secure data storage:
const storage = sdk.storage();
// Upload a file
const file = new File(['Hello World'], 'hello.txt', { type: 'text/plain' });
const uploadResult = await storage.upload(file, {
prefix: 'documents',
bucketId: 'user-data'
});
// List files
const files = await storage.list({ bucketId: 'user-data' });
// Get file data
const fileData = await storage.getData(uploadResult.externalId);
// Download file
const fileResponse = await storage.download(uploadResult.externalId);
// Delete file
await storage.delete(uploadResult.externalId);
Notification Service
Sends notifications to users and workspaces:
const notifications = sdk.notifications();
// Send notification to a specific account
await notifications.sendToAccount('user-account-id', {
sender: 'MyApp',
message: {
subject: 'New Message',
text: 'You have a new message',
html: '<p>You have a new message</p>',
urgency: 'NONE'
},
account: null,
directive: 'PREFERRED',
delivery: { schedule: 'IMMEDIATE', delay: '0' },
subscriptionKey: null
});
// Send notification to a workspace
await notifications.sendToWorkspace('workspace-id', {
sender: 'MyApp',
message: {
subject: 'Workspace Update',
text: 'Your workspace has been updated',
urgency: 'NONE'
},
account: null,
directive: 'PREFERRED',
delivery: { schedule: 'IMMEDIATE', delay: '0' },
subscriptionKey: null
});
Registration Service
Manages app registration and metadata:
const registration = sdk.registration();
// Register application (usually done during boot)
const registrationData = {
product: {
bundleId: 'com.example.app',
capabilities: ['BACKEND_SERVICE'],
description: 'My Application',
name: 'My App',
subdomain: 'app',
title: 'My App'
}
};
const response = await registration.register(registrationData);
console.log('Registration response:', response);
Discovery Service
Discovers other services in the ecosystem:
const discovery = sdk.discovery();
// Load all services
const services = await discovery.load();
console.log('Available services:', services);
// Get specific service
const platformService = await discovery.getService('io.asterisms.platform');
console.log('Platform service URL:', platformService.url);
// Reload services (clears cache)
const refreshedServices = await discovery.reload();
Information Service
Provides system and app information:
const info = sdk.information();
// Get current product info
const product = info.currentProduct();
console.log('Product:', product.name, product.version);
// Get root domain
const domain = info.rootDomain();
console.log('Domain:', domain);
SvelteKit Integration
The SDK provides special SvelteKit integration:
import { createSvelteKitBackendSDK } from '@asterisms/sdk-backend';
import { createFetchAdapter } from '@asterisms/common-core';
const provider = createSvelteKitBackendSDK({
env: process.env,
building,
httpFactory: createFetchAdapter(fetch),
registrationData: {
// registration data
}
});
This returns an AsterismsSDKProvider with:
sdk: The SDK instance
bootSDK(): Boots the SDK if not building
apiRouter: Express-compatible router for API endpoints
Error Handling
The SDK uses structured error handling:
import { AsterismsSDKError } from '@asterisms/sdk-backend';
try {
await sdk.boot();
} catch (error) {
if (error instanceof AsterismsSDKError) {
console.error('SDK Error:', error.message);
console.error('Error Code:', error.code);
} else {
console.error('Unknown error:', error);
}
}
Configuration Best Practices
Environment Variables
Use environment variables for configuration:
ASTERISMS_DOMAIN=asterisms.example.com
ASTERISMS_BUNDLE_ID=com.example.app
ASTERISMS_SUBDOMAIN=app
ASTERISMS_NAME=My App
ASTERISMS_TITLE=My App
ASTERISMS_DESCRIPTION=My Asterisms Application
Security
Always use HTTPS in production:
const sdk = getAsterismsBackendSDK({
// ... other config
secure: true,
proxyTerminatedSSL: true // If behind a proxy
});
Logging
Configure logging for debugging:
const logger = sdk.logging();
logger.setLevel('debug');
Performance Considerations
Singleton Pattern
The SDK uses a singleton pattern - only one instance per application:
// This returns the same instance
const sdk1 = getAsterismsBackendSDK(props);
const sdk2 = getAsterismsBackendSDK(props);
console.log(sdk1 === sdk2); // true
Service Caching
Services are cached after first access:
// First call creates the service
const auth1 = sdk.authorization();
// Second call returns cached service
const auth2 = sdk.authorization();
console.log(auth1 === auth2); // true
Boot Once
Only boot the SDK once per application lifecycle:
let booted = false;
async function ensureBooted() {
if (!booted && !sdk.isBooted()) {
await sdk.boot();
booted = true;
}
}
Next Steps