Upyo 0.3.0 リリース:マルチプロバイダー対応と耐障害性の強化

洪 民憙 (Hong Minhee) @hongminhee@hackers.pub

Upyo とは

Upyoは、Node.js、Deno、Bun、エッジ関数など、複数のJavaScriptランタイムで動作する統一的なメールライブラリです。SMTP、Mailgun、SendGrid、Amazon SESなどの様々なメールプロバイダーを同じインターフェースで扱えるため、プロバイダーを変更してもアプリケーションコードの修正が不要です。TypeScriptファーストで設計されており、型安全性とゼロ依存性を特徴としています。名前の由来は韓国語の「郵票(ウピョ)」で、これは「切手」を意味します。切手がどの郵便システムでも郵便を届けられるように、Upyo はどのランタイムでもメールを送信できることを表しています。

今回リリースしたUpyo 0.3.0では、メール配信の信頼性を大幅に向上させる三つの新しいトランスポートを追加しました。

プールトランスポート:複数プロバイダーによる冗長化

新しい@upyo/poolパッケージは、複数のメールプロバイダーを組み合わせて単一のトランスポートとして扱えるプール(pool)トランスポートを提供します。これにより、プロバイダー間でのトラフィック分散や、障害時の自動フェイルオーバーが可能になります。

プールトランスポートは複数のルーティング戦略をサポートしています。ラウンドロビンによる均等な分散や、重み付けによる特定プロバイダーへのトラフィック集中など、用途に応じて最適な戦略を選択できます。優先度ベースのルーティングでは、常に最優先のプロバイダーから試行し、失敗時のみ次のプロバイダーにフォールバックします。さらに複雑なシナリオでは、メッセージの内容や宛先ドメインなどに基づくカスタムルーティングも実装できます。

import { PoolTransport } from "@upyo/pool";
import { SmtpTransport } from "@upyo/smtp";
import { MailgunTransport } from "@upyo/mailgun";
import { SendGridTransport } from "@upyo/sendgrid";

// 各プロバイダーを定義
const primaryProvider = new MailgunTransport({
  apiKey: "your-mailgun-api-key",
  domain: "mg.example.com",
});

const backupProvider = new SendGridTransport({
  apiKey: "your-sendgrid-api-key",
});

const emergencyProvider = new SmtpTransport({
  host: "smtp.example.com",
  port: 587,
  auth: { user: "user@example.com", pass: "password" },
});

// プールトランスポートを作成
const pool = new PoolTransport({
  strategy: "priority",
  transports: [
    { transport: primaryProvider, priority: 100 },
    { transport: backupProvider, priority: 50 },
    { transport: emergencyProvider, priority: 10 },
  ],
  maxRetries: 3,
});

const receipt = await pool.send(message);

このトランスポートは、メール配信の失敗を許容できない高可用性システムで特に有用です。また、大量メールを安価なプロバイダーに、トランザクションメールをプレミアムサービスに振り分けることでコスト最適化も実現できます。プロバイダー移行時には、重み付け分散を使って段階的にトラフィックを移行することも可能です。AsyncDisposableによる適切なリソース管理と、すべての試行プロバイダーからの失敗を集約した包括的なエラーレポートも提供します。

詳細な設定オプションと使用パターンについては、プールトランスポートのドキュメント(英文)をご参照ください。

インストール

npm  add     @upyo/pool
pnpm add     @upyo/pool
yarn add     @upyo/pool
deno add jsr:@upyo/pool
bun  add     @upyo/pool

Resend トランスポート

@upyo/resendパッケージは、開発者体験を重視して設計されたモダンなメールサービスプロバイダーResendのサポートを追加します。Resend は本番環境で必要な機能を犠牲にすることなく、シンプルさを追求しています。

Resendの強みの一つは、インテリジェントなバッチ最適化です。複数のメールを送信する際、トランスポートは自動的にメッセージの特性に基づいて最も効率的な送信方法を選択します。添付ファイルのないメッセージはResendのバッチ API を使用して最適なパフォーマンスで送信され、必要に応じてシームレスに個別リクエストにフォールバックします。この最適化は内部で自動的に行われるため、ユーザーが意識する必要はありません。

import { ResendTransport } from "@upyo/resend";

const transport = new ResendTransport({
  apiKey: "re_1234567890abcdef_1234567890abcdef1234567890",
});

const receipt = await transport.send(message);

Resendはネットワークの問題やアプリケーションの再試行時の重複送信を防ぐための組み込みべき等性も提供します。トランスポートは自動的にべき等性キーを生成しますが、必要に応じてカスタムキーを提供することも可能です。指数バックオフを使用した包括的なリトライロジックと組み合わせることで、一時的なサービス中断時でも確実な配信を保証します。メッセージタグのサポートにより、Resendの分析ダッシュボードでさまざまな種類の通信のパフォーマンスを整理・追跡できます。

Resendトランスポートガイド(英文)では、設定と高度な機能に関する包括的なドキュメントを提供しています。

インストール

npm  add     @upyo/resend
pnpm add     @upyo/resend
yarn add     @upyo/resend
deno add jsr:@upyo/resend
bun  add     @upyo/resend

Plunk トランスポート

@upyo/plunkパッケージは、クラウドホスティングとセルフホスティングの両方のデプロイメントオプションを提供するメールサービスPlunkのサポートを追加します。この柔軟性により、Plunkは特定のインフラストラクチャ要件を持つ組織にとって魅力的な選択肢となっています。

多くのチームにとって、コンプライアンスやデータ主権の理由から、メールインフラをセルフホストできることは重要です。Plunkのセルフホストオプションはdriaug/plunkイメージを使用したDockerコンテナとして動作し、シンプルでモダンな API を維持しながら、メールインフラを完全に制御できます。同じコードベースがクラウドとセルフホストの両方のインスタンスでシームレスに動作し、ベースURLの設定を変えるだけで切り替えられます。

import { PlunkTransport } from "@upyo/plunk";

// クラウドホスティング
const cloudTransport = new PlunkTransport({
  apiKey: "sk_1234567890abcdef1234567890abcdef1234567890abcdef",
});

// セルフホスティング
const selfHostedTransport = new PlunkTransport({
  apiKey: "your-self-hosted-api-key",
  baseUrl: "https://mail.yourcompany.com/api",
});

Plunk トランスポートには、指数バックオフを使用したリトライロジック、包括的なエラーハンドリング、添付ファイルのサポート(Plunk APIの制限により1メッセージあたり最大5個)など、本番環境で求められる主要な機能が含まれています。タグによるメッセージの整理はさまざまな種類のメールを追跡するのに役立ち、優先度レベルは緊急メッセージが適切に処理されることを保証します。トランスポートはAbortSignalによるリクエストのキャンセルもサポートしており、アプリケーションがタイムアウトやユーザーによるキャンセルを適切に処理できます。

完全なドキュメントとデプロイメントガイドはPlunkトランスポートドキュメント(英文)で利用可能です。

インストール

npm  add     @upyo/plunk
pnpm add     @upyo/plunk
yarn add     @upyo/plunk
deno add jsr:@upyo/plunk
bun  add     @upyo/plunk

移行ガイド

すべての新しいトランスポートはUpyoの一貫したAPI設計を維持しているため、既存のトランスポートのドロップイン置換として使用できます。同じメッセージ作成と送信のコードがどのトランスポートでも動作します:

import { createMessage } from "@upyo/core";

const message = createMessage({
  from: "sender@example.com",
  to: "recipient@example.com",
  subject: "Hello from Upyo!",
  content: { text: "どのトランスポートでも動作します!" },
});

const receipt = await transport.send(message);

今後の展開

私たちは、ライブラリのシンプルさ、型安全性、クロスランタイム互換性に焦点を当てながら、Upyoのトランスポートオプションの拡張に引き続き取り組んでいます。皆様のフィードバックとコントリビューションがプロジェクトの方向性を形作っています。


完全な変更履歴と技術的な詳細については、CHANGES.md(英文)をご覧ください。

ご質問や問題がある場合は、GitHubリポジトリをご参照ください。

3

No comments

If you have a fediverse account, you can comment on this article from your own instance. Search https://hackers.pub/ap/articles/01995113-910d-7f58-bd0e-688defa9aa68 on your instance and reply to it.