Web アプリケーションが大きくなると、システムの開発と保守も複雑になります。この問題を解決する一般的な方法は、マイクロサービス アーキテクチャを使用することです。マイクロサービス アーキテクチャでは、開発者がシステムを、個別に管理および拡張できる、適切に管理された小さなコンポーネントに分割します。
これを効果的に行うには、多くの場合、マイクロサービス フレームワークを使用すると便利です。ただし、マイクロサービスをネイティブにサポートする適切なフレームワークを選択するのは難しい場合があります。この記事では、Encore.ts と Nest.js を 2 つの関連する代替手段として取り上げます。これらは両方ともマイクロサービス アーキテクチャと TypeScript をネイティブにサポートしているためです。
Encore.ts は、高いパフォーマンス、型安全性、可観測性の機能で際立った新しいオープンソース フレームワークです。一方、Nest.js は、マイクロサービス アプリケーションを構築するための TypeScript フレームワークをリードします。それぞれのフレームワークには強力な利点があるため、アーキテクチャ、パフォーマンス、スケーラビリティの観点から各フレームワークを検証し、どれが最適であるかを判断する方法を説明します。
始める前に、以下の画像のベンチマーク データを見てみましょう:
ベンチマーク データは、Encore.ts が検証なしで 1 秒あたり 121,005 リクエスト、スキーマ検証ありでは 107,018 リクエストを処理できることを示しています。これは従来のフレームワークよりも大幅に高速です。たとえば、Zod を使用した Express.js は、検証なしでは 1 秒あたり約 15,707 リクエストのみヒットしますが、検証ありでは 11,878 リクエストに達します。したがって、Encore.ts は、Nestjs が構築されている Express よりも約 9 倍高速です。
プロジェクトを開始するときは、強力なだけでなく、開発者にとって使いやすいフレームワークが必要です。 Typescript のサポートが組み込まれているマイクロサービス フレームワークに関しては、Encore.ts と NestJS が際立っていますが、それぞれ独自の異なる方法で動作します。
Encore.ts は、インフラストラクチャ自動化が組み込まれたバックエンド開発用に設計されたオープンソースのクラウドネイティブ フレームワークです。宣言型インフラストラクチャ ライブラリを使用してモジュール型分散システムを構築できます。
Encore.ts は、napi を介して Node.js と統合された Rust ランタイム上で動作し、TypeScript でロジックを記述しながら、I/O とマルチスレッドの処理において優れたパフォーマンスを実現します。
Encore.ts でサービスを定義する方法の簡単な例を次に示します。
import { Service } from "encore.dev/service"; export default new Service("hello");
この Hello サービスが作成されると、Encore.ts は自動的にディレクトリ全体をサービスの一部として扱います。追加の構成は必要ありません。
一方、NestJS には独自のスタイルがあります。これは、アプリの構築方法を完全に制御できる柔軟な TypeScript フレームワークであり、自分の方法で自由に構築できます。
NestJS はインフラストラクチャの自動化を処理しませんが、ほぼすべてのサードパーティ ライブラリと簡単に統合できるため、さまざまなプロジェクトに多くの可能性が開かれます。
ここでは、NestJS で同様のサービスを定義する方法を示します。
import { Service } from "encore.dev/service"; export default new Service("hello");
NestJS はより高い柔軟性を提供しますが、Encore.ts にある組み込みの自動化はありません。
フレームワークのアーキテクチャは、アプリケーションがどのように構築され、長期にわたって維持されるかを決定します。 Encore.ts と NestJS はどちらも堅牢ですが、中心となる哲学が異なります。
Encore.ts は独自の意見があり、*クラウドファーストであるため、多くのマイクロサービスを備えた大規模なタイプセーフ *分散システムに最適です。その際立った機能の 1 つは、Pub/Sub のネイティブ サポートであり、イベント駆動型アーキテクチャをシームレスに実現します。
Pub/Sub を使用して Encore.ts でイベント駆動型サービスを定義する方法は次のとおりです。
import { Controller, Get } from '@nestjs/common'; @Controller('hello') export class HelloWorldController { @Get() sayHello(): string { return 'Hello, World!'; } }
NestJS は、マイクロサービスとイベント駆動型アーキテクチャをサポートできますが、よりモジュール型のアプローチを提供します。そのコアは MVC パターンに従っており、開発者は構成をより詳細に制御することで、自分の方法でシステムを構築できます。
たとえば、よりモジュール化されたアプローチを使用して NestJS でサービスとイベントを定義する方法は次のとおりです。
import { Topic, Subscription } from "encore.dev/pubsub"; // Define the event type for order creation export interface OrderCreatedEvent { orderId: string; } // Create a topic for order creation events export const orders = new Topic<OrderCreatedEvent>("orders", { deliveryGuarantee: "at-least-once", }); // Create a subscription to listen for the order creation event export const _ = new Subscription(orders, "process-order", { handler: async (event: OrderCreatedEvent) => { console.log('Order created:', event.orderId); }, });
設計上、NestJS はコンポーネントがどのように相互作用するかを詳細に制御できますが、欠点ははるかに定型的なものであり、インフラストラクチャ構成も自分で管理する必要があります。
分散システムの開発では、フレームワークによって提供される機能によって開発が容易になることがよくありますが、過度に複雑になるリスクがあります。
Encore.ts の際立った機能は、ローカル開発とクラウド環境の両方でインフラストラクチャのプロビジョニングを自動化する方法を提供することです。これには、データベース、Pub/Sub、cron ジョブなどが含まれます。 Encore.ts は、API ドキュメント、アーキテクチャ図、分散トレースを自動生成するローカル開発ダッシュボードも提供します。また、REST API の OpenAPI 仕様サポートを含むフロントエンド クライアントも生成され、開発者にとって大幅な時間を節約できます。
Encore.ts で REST API を定義する例を次に示します。これにより、OpenAPI ドキュメントも自動的に生成されます。
import { Service } from "encore.dev/service"; export default new Service("hello");
Encore.ts を使用すると、サービスを定義すると、追加のセットアップを行わなくても、ドキュメントと図が自動的に利用可能になります。
NestJS はその柔軟性により人気があります。初日から REST、GraphQL、WebSocket を簡単にサポートしていますが、その人気の背後にある主な点は、サードパーティのライブラリと簡単に接続できることです。
たとえば、GraphQL サポートを追加する場合は、簡単なプロセスです。
import { Controller, Get } from '@nestjs/common'; @Controller('hello') export class HelloWorldController { @Get() sayHello(): string { return 'Hello, World!'; } }
NestJS を使用すると、コア機能に基づいて簡単に構築できますが、Encore.ts と同じレベルの自動化されたインフラストラクチャと機能は提供されません。
分散システム、特に大規模なシステムを構築する場合、パフォーマンスは非常に重要です。
Encore.ts は、I/O 操作とマルチスレッドを効率的に処理する Rust ランタイムを使用して高パフォーマンスを実現するように構築されています。 Rust の速度とメモリの安全性により、Encore.ts は純粋な Node.js ベースのフレームワークに比べて大きな利点をもたらします。スケーラビリティの点では、Encore.ts はクラウドネイティブであり、導入戦略に応じてサーバーレス アーキテクチャまたは Kubernetes を使用して自動スケーリングできます。
一方、NestJS は、パフォーマンスとスケーラビリティの処理方法においてより伝統的です。 NestJS は純粋に TypeScript と JavaScript ベースであるため、セットアップ中に適用するパフォーマンスの最適化に依存します。 NestJS アプリのスケーリングには通常、Kubernetes、Docker、または AWS Lambda などのサーバーレス プラットフォームを手動で構成することが含まれます。
NestJS は拡張方法に柔軟性を提供しますが、構成には Encore.ts の組み込み自動化よりも多くの手動作業が必要です。
下の画像のベンチマーク データから、encore.ts と Nest.js のパフォーマンスの違いを理解してみましょう:
ベンチマーク データから、encore.ts は開始時間がわずか 8.3 ミリ秒で、パフォーマンスの面で際立っています。一方、NestJS は約 143.7 ミリ秒かかり、従来のフレームワークよりもほぼ 9 倍高速です。
アプリケーションをどのようにデプロイするかは、特にクラウド環境について考える場合、どのプロジェクトでも重要な考慮事項です。
Encore.ts は、オープンソース ツールまたは Encore クラウド プラットフォームを通じて導入するための簡単なパスを提供します。オープンソース バージョンを使用すると、アンコール ビルドを使用してプロジェクトをビルドし、Docker イメージを作成できます。これは、Docker がサポートされているどこにでもデプロイできます。
import { Topic, Subscription } from "encore.dev/pubsub"; // Define the event type for order creation export interface OrderCreatedEvent { orderId: string; } // Create a topic for order creation events export const orders = new Topic<OrderCreatedEvent>("orders", { deliveryGuarantee: "at-least-once", }); // Create a subscription to listen for the order creation event export const _ = new Subscription(orders, "process-order", { handler: async (event: OrderCreatedEvent) => { console.log('Order created:', event.orderId); }, });
これにより、どこにでもデプロイできる Docker イメージが作成されます。
また、Encore Cloud Platform の使用を選択した場合は、CI/CD パイプライン全体が自動化され、サーバーレスまたは Kubernetes オプションを使用して AWS または GCP 上の独自のクラウドに直接デプロイされます。
対照的に、NestJS の展開には手動セットアップが必要です。通常、開発者は Docker を使用して NestJS アプリケーションをコンテナ化し、選択したクラウド プロバイダーにデプロイします。これにより、展開戦略を制御できるようになりますが、より多くの構成が必要になります。単純なアプリケーションであっても、多くの手順を実行する必要があります。
import { Service } from "encore.dev/service"; export default new Service("hello");
import { Controller, Get } from '@nestjs/common'; @Controller('hello') export class HelloWorldController { @Get() sayHello(): string { return 'Hello, World!'; } }
import { Topic, Subscription } from "encore.dev/pubsub"; // Define the event type for order creation export interface OrderCreatedEvent { orderId: string; } // Create a topic for order creation events export const orders = new Topic<OrderCreatedEvent>("orders", { deliveryGuarantee: "at-least-once", }); // Create a subscription to listen for the order creation event export const _ = new Subscription(orders, "process-order", { handler: async (event: OrderCreatedEvent) => { console.log('Order created:', event.orderId); }, });
アプリケーションが大きくなり、複数のステージング環境やテスト環境の必要性が高まるほど、この手動構成アプローチは負担が大きくなり、メンテナンスに費やす時間は増加し続けます。
Encore.ts と NestJS のどちらかを選択する場合は、プロジェクトの特定のニーズに基づいて決定する必要があります。
Encore.ts は、組み込みの自動化の恩恵を受けるクラウドファーストのアプリケーションや大規模な分散システムに最適です。 Rust を利用したランタイムとインフラストラクチャ管理により、イベント駆動型のアーキテクチャ、マイクロサービス、高パフォーマンスのアプリケーションに最適です。 Encore の急速に成長するコミュニティは、信頼できるサポート源であり、サードパーティ ツールを統合する方法を見つけることができます。
一方、NestJS は、柔軟性とカスタマイズが必要な場合に威力を発揮します。これは、あらゆる側面をきめ細かく制御する必要があり、手動構成に時間を費やすことが許容されるエンタープライズ アプリに最適です。 NestJS の比較的広範なエコシステムとコミュニティ サポートにより、リソースやサードパーティ ツールを簡単に見つけることができます。
Encore.ts と NestJS のどちらを選択するかは、プロジェクト固有のニーズによって決まります。
自動化機能が組み込まれた、シンプルで高性能なクラウドネイティブのフレームワークをお探しの場合は、Encore.ts が最適です。インフラストラクチャを自動的に管理することで分散システムの開発を合理化し、Rust を活用したそのパフォーマンスは比類のないものです。
ただし、あらゆる点を制御できる非常に柔軟なモジュール式フレームワークが必要な場合は、おそらく NestJS が最適です。その拡張性と大規模なエコシステムにより、カスタム エンタープライズ ソリューションにとって確実な選択肢となります。
どちらのフレームワークもそれ自体が強力であり、最適な選択は、パフォーマンスとシンプルさを重視するか、完全な柔軟性と制御を重視するかによって異なります。
プロジェクトにとってパフォーマンスとシンプルさが重要な場合は、Encore.ts を試してみることをお勧めします。また、すべてオープンソースなので、コードをチェックアウトして GitHub に貢献できます。
以上がNestJS と Encore.ts: TypeScript マイクロサービスに適切なフレームワークの選択の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。