Integrations
Connecting to third-party APIs, webhooks, message queues, and external services with reliability and security.
Integrations
Modern applications rarely exist in isolation — they integrate with payment processors, email providers, analytics tools, and business platforms. We build reliable, secure, and maintainable integrations that scale.
Integration philosophy
We treat third-party APIs as unreliable — they go down, rate-limit requests, and change without notice. Our integrations are built with retries, circuit breakers, and graceful degradation from day one.
Types of Integrations
1. REST API Integrations
Calling external HTTP APIs (payment, shipping, email, etc.).
Key practices:
- Timeout handling: Set timeouts (e.g., 10s) to avoid hanging requests
- Retry logic: Exponential backoff for transient failures (503, 429)
- Error handling: Parse error responses, log failures
- Rate limiting: Respect API rate limits (check headers:
X-RateLimit-Remaining)
// Example: Stripe Payment Integration
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
apiVersion: '2023-10-16',
timeout: 10000, // 10 seconds
maxNetworkRetries: 3, // Retry failed requests
});
async function createPaymentIntent(amount: number, currency: string) {
try {
const paymentIntent = await stripe.paymentIntents.create({
amount,
currency,
automatic_payment_methods: { enabled: true },
});
return paymentIntent;
} catch (error) {
if (error.type === 'StripeCardError') {
// Card was declined
throw new BadRequestException(error.message);
}
// Log and rethrow
logger.error('Stripe payment failed', error);
throw new ServiceUnavailableException('Payment service unavailable');
}
}2. Webhooks (Receiving Events)
External services send HTTP callbacks when events occur (e.g., Stripe payment succeeded, GitHub PR merged).
Key practices:
- Signature verification: Verify requests are from the claimed sender (HMAC)
- Idempotency: Process duplicate webhooks safely (store event IDs)
- Async processing: Queue webhooks for background processing (don't block the response)
- Retry handling: Return 200 OK to acknowledge receipt; retry logic is on sender's side
// Example: GitHub Webhook Handler
@Post('webhooks/github')
async handleGitHubWebhook(
@Body() payload: any,
@Headers('x-hub-signature-256') signature: string,
) {
// 1. Verify signature
const isValid = this.verifyGitHubSignature(payload, signature);
if (!isValid) {
throw new UnauthorizedException('Invalid signature');
}
// 2. Check for duplicate (idempotency)
const eventId = payload.headers['x-github-delivery'];
const alreadyProcessed = await this.redis.get(`webhook:${eventId}`);
if (alreadyProcessed) {
return { status: 'already_processed' };
}
// 3. Queue for async processing
await this.queue.add('github-webhook', payload);
await this.redis.setex(`webhook:${eventId}`, 86400, 'true'); // 24h TTL
// 4. Respond immediately
return { status: 'received' };
}
private verifyGitHubSignature(payload: any, signature: string): boolean {
const secret = process.env.GITHUB_WEBHOOK_SECRET;
const hmac = crypto.createHmac('sha256', secret);
const expectedSignature = 'sha256=' + hmac.update(JSON.stringify(payload)).digest('hex');
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expectedSignature));
}3. Message Queues
Asynchronous communication between services or background job processing.
Use cases:
- Email sending: Queue emails instead of blocking requests
- Image processing: Resize/optimize images in background
- Data sync: Sync data between systems asynchronously
Technologies:
- RabbitMQ: Feature-rich, supports complex routing
- AWS SQS: Managed, scales automatically
- Redis Pub/Sub: Lightweight, for simple use cases
// Example: BullMQ (Redis-based queue)
import { Queue, Worker } from 'bullmq';
const emailQueue = new Queue('email', {
connection: { host: 'localhost', port: 6379 },
});
// Producer: Add jobs to queue
async function sendWelcomeEmail(userId: string) {
await emailQueue.add('welcome-email', { userId });
}
// Consumer: Process jobs
const worker = new Worker(
'email',
async (job) => {
const { userId } = job.data;
const user = await getUserById(userId);
await emailService.send({
to: user.email,
subject: 'Welcome!',
body: renderWelcomeEmail(user),
});
},
{ connection: { host: 'localhost', port: 6379 } },
);Queue pitfalls
- Poison messages: Jobs that always fail can block the queue → use dead letter queues
- No retries: Configure max retries and backoff strategies
- Lost jobs: Use persistent queues (Redis AOF, RabbitMQ durability)
4. OAuth & SSO Integrations
Letting users sign in with Google, GitHub, Microsoft, etc.
Key practices:
- OAuth 2.0 flow: Authorization code flow for web apps, PKCE for mobile
- Token storage: Store access/refresh tokens securely (encrypted in DB)
- Scope management: Request minimal scopes (e.g.,
email,profile)
// Example: Google OAuth with Passport.js
passport.use(
new GoogleStrategy(
{
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: '/auth/google/callback',
},
async (accessToken, refreshToken, profile, done) => {
// Find or create user
let user = await User.findOne({ googleId: profile.id });
if (!user) {
user = await User.create({
googleId: profile.id,
email: profile.emails[0].value,
name: profile.displayName,
});
}
return done(null, user);
}
)
);Common Integration Patterns
Circuit Breaker
Stop calling failing services to prevent cascading failures.
If 5 requests fail → open circuit → return fallback response → retry after 30s
Exponential Backoff
Retry failed requests with increasing delays.
1st retry: 1s → 2nd: 2s → 3rd: 4s → 4th: 8s (max 5 retries)
API Key Rotation
Rotate API keys/secrets without downtime.
- Generate new key → 2. Deploy with both keys → 3. Switch to new → 4. Remove old
Popular Integrations We Build
| Category | Services |
|---|---|
| Payments | Stripe, PayPal, Square, Adyen |
| SendGrid, Mailgun, AWS SES, Resend | |
| SMS | Twilio, Vonage, AWS SNS |
| Push Notifications | Firebase Cloud Messaging, OneSignal, AWS SNS |
| Analytics | Segment, Mixpanel, Amplitude, Google Analytics |
| Storage | AWS S3, Cloudflare R2, Google Cloud Storage |
| Auth | Auth0, Firebase Auth, Supabase Auth, Clerk |
| Monitoring | Sentry, Datadog, New Relic, LogRocket |
| Business Tools | Slack, Salesforce, HubSpot, Zendesk |
Integration testing
Use test/sandbox modes for third-party services. Mock external APIs in unit tests, but run integration tests against real sandbox environments.
Security Best Practices
Never Hardcode Secrets
Store API keys in environment variables or secret managers (AWS Secrets Manager, HashiCorp Vault).
Verify Webhook Signatures
Always verify HMAC signatures to prevent spoofed webhook requests.
Use HTTPS Everywhere
All external API calls and webhooks must use HTTPS (TLS 1.2+).
Log (But Redact Secrets)
Log API requests/responses for debugging, but redact tokens, passwords, and PII.