Rubyでマイクロサービスアーキテクチャを設定する方法:ステップバイステップガイド

公開: 2022-03-11

マイクロサービスとは何ですか?

マイクロサービスは、複数の独立したサービスが相互に通信し、独自のプロセスとリソースを持つソフトウェア設計の最新トレンドの1つです。 このアプローチは、一般的なクライアントサーバーアプリケーションの設計とは異なります。 通常のクライアントサーバーアプリケーションは、1つ以上のクライアント、すべてのドメインデータとロジックを含むモノリシックバックエンド、およびクライアントがバックエンドとその機能にアクセスできるようにするAPIで構成されます。

マイクロサービスは、従来のモノリシックバックエンドサーバーに取って代わりつつあります
つぶやき

マイクロサービスアーキテクチャでは、説明されているモノリシックバックエンドは、代わりに一連の分散サービスに置き換えられます。 この設計により、責任の分離が改善され、メンテナンスが容易になり、各サービスのテクノロジーをより柔軟に選択できるようになり、スケーラビリティとフォールトトレランスが容易になります。 同時に、複雑な分散システムには一連の課題があります。 競合状態に対処しなければならない可能性が高く、問題を1つのサービスに簡単に特定するのではなく、多くのサービスに分散させるため、デバッグが困難です。 このようなシステムを構築する際にベストプラクティスに従わない場合、消火方法がわからない火事に囲まれる可能性があります。 1つのサービスの変更がすべてのクライアントに影響し、その結果、すべてのバックエンドのサービススイートに影響する可能性があるため、サービスのペイロードコントラクトには特別な注意を払う必要があります。

これらの考慮事項はすべて重要ですが、すでに考え抜かれていると仮定しましょう。 ここで必要なのは、マイクロサービスのバックエンドを自分で構築する方法を見つけることです。 それでは、そのことに飛び込みましょう。

マイクロサービスアーキテクチャを設定する方法

現在、マイクロサービスをセットアップする方法はたくさんあります。このガイドでは、ブローカーアーキテクチャに焦点を当てます。

ブローカーアーキテクチャ

ブローカーアーキテクチャ(中央にブローカー(B)があり、その周囲に4つのマイクロサービスがある場合)は、それらをN、S、E、Wと呼びます。要求/応答パスは、アーキテクチャの外部の入力から始まり、パスN、B、 E、B、S、B、W、B、E、B、N、最終的に出力として終了する前。

ブローカーアーキテクチャは、サービスを相互に通信させる方法の1つです。
つぶやき

ブローカーアーキテクチャは、サービスを相互に通信させる方法の1つです。 その中で、すべてのサービスがメッセージングサーバー、ブローカーを囲み、すべてがそれに接続されています。 サービスはブローカーにメッセージを送信し、ブローカーはこれらのメッセージを転送するために必要な他のサービスを認識します。 このように、サービスは他のサービスに関する情報を保持する必要はありません。 代わりに、ブローカーがすべてのメッセージングを処理することに依存しており、特定のドメインのみに分離して集中することができます。 ブローカーは、受信者がダウンしているときにメッセージを保存することもできます。これにより、送信者と受信者が同時にアップすることを強制されないため、さらに優れた分離が可能になります。 もちろん、このソリューションには欠点があります。これは、すべての通信がブローカーを経由する必要があるため、ブローカーがすぐにボトルネックになる可能性があり、バックエンドの単一障害点になる可能性もあるためです。 ただし、これらの問題を軽減する方法はいくつかあります。 1つの方法は、ブローカーの複数のインスタンスを並行して実行することです。これにより、システムのフォールトトレランスが向上します。 別の方法は、他のアーキテクチャを使用することです。 代替アーキテクチャは、ブローカーを使用しないか、別のブローカーアーキテクチャを使用するか、HTTPなどの別のメッセージングプロトコルを使用することにより、このガイドで実装するアーキテクチャとは異なります。

サービス間の通信

このガイドでは、ZeroMQを使用して、サービスとブローカー間の通信を処理します。

ZeroMQスタック。上部には、省略記号とZeroMQ記号が付いたブロックがあります。下部のブロックには、上から下に、トランスポート、ネットワーク、データリンク、および物理があります。

ZeroMQは、ランダムトランスポートを介してマルチパート非同期メッセージを処理するプロトコル抽象化レイヤーを提供します。 サービスとブローカー間のメッセージングにZeroMQを使用する利点は、このガイドの範囲外であるため、ここでは詳しく説明しませんが、それらについて詳しく知りたい場合は、Quoraの次の記事を確認してください。 サービスを相互に通信させる他の方法を見つけることに興味がある場合は、ブローカーとブローカーレスの記事を見て、他に何ができるかを確認することをお勧めします。

マイクロサービススイートの構築

この記事では、マイクロサービススイートを作成するために必要なすべての手順について説明します。 私たちのシステムはブローカーとサービスで構成されます。 また、小さなクライアントスクリプトを使用してサービススイートへの呼び出しをテストしますが、クライアントコードはどこでも簡単に使用できることに注意してください。

それでは、構築を始めましょう。

入門

まず、ブローカーとサービスを実行するために必要なものがすべて揃っていることを確認しましょう。 まず、Node.js、ZeroMQ、Gitをマシンにダウンロードしてインストールすることから始めます。 OSXを使用している場合は、それぞれに自作パッケージがあり、ほとんどのLinuxディストリビューションにもそれぞれにパッケージがあるので、これで問題はありません。 Windowsユーザーは、上記のダウンロードリンクを使用するだけです。

ブローカーの実行

必要なすべての依存関係をインストールしたら、ブローカーを実行してみましょう。 このガイドでは、ZMQサービス指向スイートの一部であるブローカーのNode.js実装を使用しています。 そのコードとドキュメントはGitHubにあります。 ブローカーを実行するには、最初にブローカーのブートストラップをマシンに複製します。 このリポジトリは、上記のブローカーライブラリを使用するためのブートストラップです。 元のライブラリ自体は実行可能であるため、この手順は必要ありませんが、2つの違いは、ブートストラップリポジトリでデフォルト構成を変更できることです。

したがって、最初に、次のGitコマンドを使用してプロジェクトをマシンにダウンロードします。

 $ git clone [email protected]:dadah/zmq-broker-bootstrap.git

それが終わったら、作成したディレクトリに移動します。

 $ cd zmq-broker-bootstrap

次に、パッケージの依存関係をインストールします。

 $ npm install

これでブローカーの準備が整いました。 ブローカーを実行するには、次のコマンドを実行します。

 $ bin/zss-broker run

各環境の構成ファイルは、 config/ディレクトリーにあります。 これはデフォルトの開発構成です。

 { "broker": { "backend": "tcp://127.0.0.1:7776", "frontend": "tcp://127.0.0.1:7777" }, "log": { "consolePlugin": { "level": "debug" } } }

backendパラメータは、ブローカーのバックエンドとフロントエンドのip:portアドレスを定義します。 バックエンドアドレスは、ブローカーがサービスからの要求を受信して​​サービスに応答する場所であり、フロントエンドアドレスは、ブローカーがサービスクライアントを受信して​​送信する場所です。 log.consolePlugin.levelを変更して、ログレベルを設定することもできます。 可能な値は、 tracedebuginfowarn 、およびerrorであり、これらは、ログ情報ブローカープロセスが出力するログ量を決定します。

サービスの実行

ブローカーを立ち上げたら、最初のRubyマイクロサービスを開発します。 新しいコンソールウィンドウを開くことから始めます。 次に、サービスが保存されるディレクトリを作成してから、そのディレクトリに移動します。 このガイドでは、RubyクライアントとZMQSOASuiteのサービスを使用しています。 利用可能なブートストラップ「Helloworld」サービスがあるので、それを使用して最初のマイクロサービスを実行してみましょう。

サービスディレクトリに移動し、ブートストラップリポジトリのクローンを作成します。

 $ git clone [email protected]:dadah/zmq-service-suite-ruby-bootstrap.git

新しく作成されたディレクトリに移動します。

 $ cd zmq-service-suite-ruby-bootstrap

次に、すべての依存関係をインストールします。

 $ bundle install

サービスを開始するには、次のコマンドを実行します。

 $ bin/zss-service run

素晴らしい。 最初のサービスが稼働しています。

ブローカーを実行したままにしたコンソールウィンドウに移動すると、次の出力が表示されます。

 2015-12-15 16:45:05 | INFO | BROKER - Async Broker is waiting for messages... 2015-12-15 16:45:14 | DEBUG | BACKEND - received from: hello-word#aaa65374-8585-410a-a41d-c8a5b024553b rid: 76f50741-913a-43b9-94b0-36d8f7bd75b1 2015-12-15 16:45:14 | DEBUG | BACKEND - routing from: hello-word#aaa65374-8585-410a-a41d-c8a5b024553b rid: 76f50741-913a-43b9-94b0-36d8f7bd75b1 to SMI.UP request... 2015-12-15 16:45:14 | INFO | SMI - SMI register for sid: HELLO-WORD instance: hello-word#aaa65374-8585-410a-a41d-c8a5b024553b! 2015-12-15 16:45:14 | DEBUG | BACKEND - reply to: hello-word#aaa65374-8585-410a-a41d-c8a5b024553b rid: 76f50741-913a-43b9-94b0-36d8f7bd75b1 with status: 200 2015-12-15 16:45:15 | DEBUG | BACKEND - received from: hello-word#aaa65374-8585-410a-a41d-c8a5b024553b rid: 3b3a0416-73fa-4fd2-9306-dad18bc0502a 2015-12-15 16:45:15 | DEBUG | BACKEND - routing from: hello-word#aaa65374-8585-410a-a41d-c8a5b024553b rid: 3b3a0416-73fa-4fd2-9306-dad18bc0502a to SMI.HEARTBEAT request... 2015-12-15 16:45:15 | DEBUG | BACKEND - reply to: hello-word#aaa65374-8585-410a-a41d-c8a5b024553b rid: 3b3a0416-73fa-4fd2-9306-dad18bc0502a with status: 200 2015-12-15 16:45:16 | DEBUG | BACKEND - received from: hello-word#aaa65374-8585-410a-a41d-c8a5b024553b rid: b3044c24-c823-4394-8204-1e872f30e909 2015-12-15 16:45:16 | DEBUG | BACKEND - routing from: hello-word#aaa65374-8585-410a-a41d-c8a5b024553b rid: b3044c24-c823-4394-8204-1e872f30e909 to SMI.HEARTBEAT request... 2015-12-15 16:45:16 | DEBUG | BACKEND - reply to: hello-word#aaa65374-8585-410a-a41d-c8a5b024553b rid: b3044c24-c823-4394-8204-1e872f30e909 with status: 200

このログは、ブローカーが新しいサービスの存在を確認し、そこからハートビートメッセージを受信して​​いることを意味します。 毎秒、サービスはハートビートメッセージをブローカーに送信するため、サービスのインスタンスが起動していることがわかります。

サービスからの消費

これでサービスが実行されましたが、どのように使用しますか?

ブートストラップリポジトリには、「HelloWorld」サービスのテストに使用できるダミークライアントがあります。 新しいコンソールウィンドウまたはタブを開いて、サービスディレクトリに移動するだけです。 そこに着いたら、次のコマンドを実行します。

 $ bin/zss-client

次のように表示されます。

 15-49-15 16:49:54 | INFO | ZSS::CLIENT - Request 90a88081-3485-45b6-91b3-b0609d64592a sent to HELLO-WORD:*#HELLO/WORLD with 1.0s timeout 15-49-15 16:49:54 | INFO | ZSS::CLIENT - Received response to 90a88081-3485-45b6-91b3-b0609d64592a with status 200 "Hello World"

サービスが実行されているコンソールウィンドウに移動すると、次のように表示されます。

 Started hello-word daemon... 15-45-15 16:45:14 | INFO | ZSS::SERVICE - Starting SID: 'HELLO-WORD' ID: 'hello-word#aaa65374-8585-410a-a41d-c8a5b024553b' Env: 'development' Broker: 'tcp://127.0.0.1:7776' 15-49-15 16:49:54 | INFO | ZSS::SERVICE - Handle request for HELLO-WORD:*#HELLO/WORLD 15-49-15 16:49:54 | INFO | ZSS::SERVICE - Reply with status: 200

良い。 「HelloWorld」マイクロサービスを起動して利用しました。 しかし、これは私たちがやろうとしていることではありません。 サービスを構築したいと考えています。 それでは、それに取り掛かりましょう。

サービスの構築

まず、「HelloWorld」サービスを停止しましょう。 サービスのコンソールウィンドウに移動し、 Ctrl+Cを押してサービスを停止します。 次に、「HelloWorld」サービスを「Person」サービスに変える必要があります。

コード構造

プロジェクトのコードツリーを見てみましょう。 次のようになります。

この例のzmq-service-suite-ruby-bootstrapプロジェクトのファイル/フォルダー階層。以下で詳細に説明しますが、言及されている最後の3つの.rbファイルは、実際にはlib自体ではなく、lib/repositoriesの下にあることに注意してください。

  • binディレクトリは、サービスを起動するスクリプトを保存する場所です。
  • configディレクトリには、すべての構成ファイルが格納されます。
    • boot.rbファイルは、すべてのサービス依存関係を追加できる場所です。 それを開くと、すでにそこにリストされている多くの依存関係があることに気付くでしょう。 これ以上追加する必要がある場合は、ここで追加する必要があります。
    • application.ymlファイルには、すべてのアプリケーション設定が保存されます。 このファイルについては後で見ていきます。
    • config/initializersディレクトリで、初期化スクリプトを追加できます。 たとえば、ここでActiveRecordまたはRedis接続の設定を追加できます。 このディレクトリに追加したスクリプトは、サービスの起動時に実行されます。
  • db/migrateディレクトリに、ActiveRecordまたはSequelの移行がある場合はそれを保存できます。 そうでない場合は、このディレクトリを完全に削除できます。
  • libディレクトリは、メインアプリケーションコードが存在する場所です。
    • settings.rbファイルは単にapplication.ymlファイルをロードし、サービスのスコープ全体で利用できるようにするため、どこからでも構成にアクセスできます。 たとえば、 Settings.broker.backendは、上記のYMLファイルで定義したブローカーバックエンドアドレスを返します。
    • ファイルservice_register.rbは、サービスとサービスルートを登録する場所です。 後で説明します。
    • hello_world_service.rbファイルは、「HelloWorld」サービスのエンドポイントを定義します。
    • lib/daosディレクトリは、ActiveRecordを使用している場合は、ActiveModelオブジェクト、またはSequelモデルなどの最終的に作成される可能性のあるその他のデータアクセスオブジェクトを格納する場所です。
    • lib/dtosディレクトリには、データ転送オブジェクトが格納されます。 これらのオブジェクトは、最終的にサービスのクライアントに返送されるオブジェクトです。
    • lib/repositoriesディレクトリにはリポジトリが保存されます。 リポジトリは、サービスがデータにアクセスできるようにするオブジェクトであり、DAOを処理できる唯一のオブジェクトです。 したがって、サービスが「Hello World」インスタンスのグループを必要とする場合、リポジトリにそれらを要求します。 次に、リポジトリは適切なDAOを使用して、データベースから関連データをフェッチします。 次に、データは適切な「HelloWorld」DTOまたは「HelloWorld」DTOコレクションにマッピングされ、サービスに返されます。
    • lib/repositories/mappersディレクトリは、マッパーを保存する場所です。 マッパーは、DAOをDTOに、またはその逆に変換するオブジェクトです。

configディレクトリのapplication.ymlファイルは次のようになります。

 defaults: &defaults broker: backend: tcp://127.0.0.1:7776 frontend: tcp://127.0.0.1:7777 logging: console: level: info development: <<: *defaults test: <<: *defaults production: <<: *defaults

この設定は、ブローカーのバックエンドとフロントエンドのアドレス、およびログレベルを設定するだけです。

これまでのところ、これらすべてが混乱しているように思われる場合でも、先に進むにつれて明らかになるので心配しないでください。

「人」サービス

それでは、「Person」サービスを続けましょう。 データベース接続を構成することから始めましょう。 ファイルconfig/initializers/active_record.rbを開き、そこにある唯一の行のコメントを解除します。 次に、次のエントリをapplication.ymlの開発構成に追加して、次のようにします。

 defaults: &defaults broker: backend: tcp://127.0.0.1:7776 frontend: tcp://127.0.0.1:7777 logging: console: level: info database: adapter: postgresql database: zss-tutorial-development

データベース構成を追加したので、データベースを作成する必要があります。 現時点では、デフォルトのPostgreSQLデータベースを使用していない限り、これを自動的に実行する方法はありません。使用している場合は、次のコマンドを実行するだけです。

 $ rake db:create

別のデータベースが必要な場合は、適切なgemをgemfileに追加してから、プロジェクトをバンドルインストールする必要があります。

次は移行です。 そのためには、 000_creates_persons.rbというファイルdb/migrateを作成するだけです。

 $ touch db/migrate/000_creates_persons_table.rb

通常のRails移行の場合と同じように、ファイルを開いて移行を作成します。

 class CreatesPersons < ActiveRecord::Migration def change create_table :persons do |t| t.name t.timestamps end end end

次に、それを実行します:

 $ rake db:migrate == 0 CreatesPersons: migrating ================================================ -- create_table(:persons) DEPRECATION WARNING: `#timestamp` was called without specifying an option for `null`. In Rails 5, this behavior will change to `null: false`. You should manually specify `null: true` to prevent the behavior of your existing migrations from changing. (called from block in change at /Users/francisco/Code/microservices-tutorial/db/migrate/000_creates_persons.rb:6) -> 0.0012s == 0 CreatesPersons: migrated (0.0013s) =======================================

テーブルが作成されたので、そのモデルを作成しましょう。 ファイルlib/daos/person.rb作成します:

 $ touch lib/daos/person.rb

次のように編集します。

 module DAO class Person < ActiveRecord::Base end end

あなたのモデルがあります。 次に、「個人」のDTOモデルを作成して、クライアントに返すことができるようにする必要があります。 ファイルlib/dtos/person.rb作成します:

 $ touch lib/dtos/person.rb

次のように編集します。

 module DTO class Person < Base attr_reader :id, :name end end

次に、「Person」DAOを「Person」DTOに変換するマッパーを作成する必要があります。 ファイルlib/repositories/mappers/person.rbを作成し、次のように編集します。

 module Mapper class Person < Mapper::Base def self.to_dao dto_instance DAO::Person.new id: dto_instance.id, name: dto_instance.name end def self.to_dto dao_instance DTO::Person.new id: dao_instance.id, name: dao_instance.name end end end

ここで、 Mapper::Baseでは、 self.to_daoself.to_dtoを実装する必要があります。 そうしたくない場合は、代わりにself.mapを実装し、受け取る属性がDAOかDTOかに応じて、 to_daoまたはto_dtoを呼び出すMapper::Base.mapをオーバーライドできます。

これで、データベースにアクセスするためのDAO、データベースをクライアントに送信するためのDTO、および一方を他方に変換するためのマッパーができました。 これで、リポジトリ内でこれら3つのクラスを使用して、データベースから人を取得し、対応するDTOのコレクションを返すことができるロジックを作成できます。

それでは、リポジトリを作成しましょう。 ファイルlib/repositories/person.rbを作成します:

 $ touch lib/dtos/person.rb

次のように編集します。

 module Repository class Person < Repository::Base def get DAO::Person.all.map do |person| Mapper::Person.map(person) end end end end

このリポジトリには、データベースからすべての人物を取得し、それらを人物DTOのコレクションにマップするインスタンスメソッドgetのみがあります。これは非常に簡単です。 これをすべてまとめましょう。 残っているのは、このリポジトリを呼び出すサービスとエンドポイントを作成することだけです。 そのために、ファイルlib/person_service.rbを作成しましょう。

 $ touch lib/person_service.rb

次のように編集します。

 class PersonService < BaseService attr_reader :person_repo def initialize @person_repo = Repository::Person.new end def get payload, headers persons = person_repo.get() if persons.empty? raise ZSS::Error.new(404, "No people here") else persons.map &:serialize end end end

「Person」サービスは、初期化子でリポジトリを初期化します。 「Person」サービスのすべてのパブリックインスタンスメソッドには、必要がない場合は省略できるペイロードとヘッダーがあります。 どちらもHashie::Mashインスタンスであり、エンドポイントに送信された変数を属性またはヘッダーとして保存します。各応答には、クライアントが送信されたリクエストの結果を確認するために使用できるステータスコードがあるため、応答はHTTP応答を模倣します。サービス、およびサービスの応答ペイロード。 応答コードは、HTTPサーバーに期待するものと同じです。 たとえば、リクエストが成功すると、応答ペイロードとともに200ステータスコードが返されます。 サービスエラーが発生した場合、ステータスコードは500になり、サーバーに送信されたパラメータに問題がある場合、ステータスコードは400になります。サービスは、ペイロードとともにほとんどのHTTPステータスコードで応答できます。 したがって、たとえば、特定のエンドポイントへのアクセスが許可されていないときにサービスがクライアントに通知する場合は、403コードで応答することでこれを行うことができます。 上記のサービスコードを振り返ると、応答コードの別の例を見ることができます。 getエンドポイントでは、利用可能なリソースがない場合にHTTPサーバーが404を返すのと同じように、人が見つからない場合にオプションの「Nopeoplehere」メッセージとともにステータスコード404を返します。 リポジトリが実際にユーザーを返す場合、サービスはDTOをシリアル化し、クライアントに返します。 各DTOには、DTO定義でattr_readerまたはattr_readerとして定義されたキーと対応する値を持つJSONオブジェクトを返すデフォルトのattr_accessibleがあります。 もちろん、DTOクラスでserializeメソッドを定義することにより、シリアライザーをオーバーライドできます。

サービスが定義されたので、それを登録する必要があります。 これが最後のステップです。 ファイルlib/service_register.rbを開き、「HelloWorld」のすべての出現箇所を「Person」に置き換えて、ファイルが最終的に次のようになるようにします。

 module ZSS class ServiceRegister def self.get_service config = Hashie::Mash.new( backend: Settings.broker.backend ) service = ZSS::Service.new(:person, config) personInstance = PersonService.new service.add_route(personInstance, :get) return service end end end

お気づきかもしれませんが、 add_route呼び出しに小さな変更があります。 文字列「HELLO/WORLD」を削除しました。 これは、サービス動詞がそれを実装するメソッドと一致しない場合にのみ文字列が必要になるためです。 この場合、GET動詞を使用してpersonサービスを呼び出す場合、呼び出されるメソッドはgetであるため、文字列を省略できます。

ServiceRegisterクラスは、メソッドself.get_serviceを定義する必要がある場所です。 このメソッドは、サービスを初期化し、ブローカーのバックエンドに接続します。 次に、そのサービスのルートを1つ以上のサービス定義のメソッドと照合します。 たとえば、次の場合、サービスを作成してブローカーにバインドします。

 config = Hashie::Mash.new( backend: Settings.broker.backend ) service = ZSS::Service.new(:person, config)

次に、サービスハンドラーをインスタンス化します。

 personInstance = PersonService.new

次に、サービスハンドラーがサービスにバインドされます。

 service.add_route(personInstance, :get)

最後に、サービスインスタンスを返す必要があります。

 return service

これで、「Person」サービスを開始する前の最後のステップは1つだけです。 そのための実行可能スクリプトを作成する必要があります。 「HelloService」用にすでに1つあります。 したがって、ファイルbin/zss-serviceを開き、「hello-word」を「person」に置き換えて、ファイルを保存します。 コンソールに戻り、以下を実行します。

 $ bin/zss-service run Starting person: PID: ./log LOGS: ./log Started person daemon... 15-29-15 19:29:54 | INFO | ZSS::SERVICE - Starting SID: 'PERSON' ID: 'person#d3ca7e1f-e229-4502-ac2d-0c01d8c285f8' Env: 'development' Broker: 'tcp://127.0.0.1:7776'

それでおしまい。 「個人」サービスを初めて開始しました。 それでは、テストしてみましょう。 bin/zss-clientファイルを開き、 sid変数を「person」に変更し、クライアント呼び出しをhello_world()からget()に変更します。 それが完了したら、新しいウィンドウでクライアントを実行します。

 $ bin/zss-client /Users/francisco/.rvm/gems/ruby-2.1.2/gems/zss-0.3.4/lib/zss/client.rb:41:in `new': No people here (ZSS::Error) from /Users/francisco/.rvm/gems/ruby-2.1.2/gems/zss-0.3.4/lib/zss/client.rb:41:in `call' from /Users/francisco/.rvm/gems/ruby-2.1.2/gems/zss-0.3.4/lib/zss/client.rb:55:in `method_missing' from bin/zss-client:12:in `<main>'

ご覧のとおり、 ZSS::Errorをキャッチしました。 これは、サービスで人が見つからず、サービスのデータベースにまだ人がいない場合にエラーが発生するためです。

次に、このエラーを処理しましょう。 zss-clientを開き、次のように編集します。

 begin client = ZSS::Client.new(sid, config) p client.get() rescue ZSS::Client => e if e.code == 404 p e.message else raise e end end

現在、エラーコードが404の場合はエラーメッセージを出力し、別の場合はエラーを発生させます。 クライアントを再度実行して、実際の動作を見てみましょう。

 $ bin/zss-client "No people here"

優れた。 ここで、テーブルに何人かの人を追加して、サービスによってクライアントに返されるかどうかを確認しましょう。 これを行うには、サービスコンソールを開くだけです。

 $ rake service:console

一部の人を追加します。

 $ rake service:console [1] pry(main)> DAO::Person.create name: 'John' => #<DAO::Person:0x007fe51bbe9d00 id: 1, name: "John", created_at: 2015-12-16 13:22:37 UTC, updated_at: 2015-12-16 13:22:37 UTC> [2] pry(main)> DAO::Person.create name: 'Mary' => #<DAO::Person:0x007fe51c1dafe8 id: 2, name: "Mary", created_at: 2015-12-16 13:22:42 UTC, updated_at: 2015-12-16 13:22:42 UTC> [3] pry(main)> DAO::Person.create name: 'Francis' => #<DAO::Person:0x007fe51bc11698 id: 3, name: "Francis", created_at: 2015-12-16 13:22:53 UTC, updated_at: 2015-12-16 13:22:53 UTC> [4] pry(main)> exit

ここで、クライアントを再度実行します。

 $ bin/zss-client [{"id"=>1, "name"=>"John"}, {"id"=>2, "name"=>"Mary"}, {"id"=>3, "name"=>"Francis"}]

そこにあります。

最終的な考慮事項

このガイドで提供されているコードを見ると、リポジトリやDTOの作成など、不要な手順がたくさんあると思うかもしれませんが、それは正しいことです。 「Person」サービスを機能させるために必要なのは、サービスクラスとDAOだけで、これらはサービスクラスから直接呼び出すことができます。 それでも、サービスロジックをデータストレージ操作から分離しておくことができるため、この記事で説明されているパターンに従うことをお勧めします。 サービスはそのロジックのみに焦点を当てる必要があり、リポジトリはデータストレージとのすべての相互作用を処理する必要があります。 DTOはサービスのペイロードとシリアル化を決定し、DAOはストレージからのデータの取得のみに関係します。 このガイドで説明されている規則と手法は、リポジトリパターンと呼ばれ、下の画像で確認できます。

リポジトリパターン。左端のボックスは「クライアントビジネスロジック」で、中央のボックスに永続化してクエリを実行します。中央のボックスは、「データマッパー」、「リポジトリ」、「クエリオブジェクト」で構成されますが、点線で区切られています。永続化とクエリはどちらも、「ビジネスエンティティ」というラベルの付いた外部ボックスからの接続によってサイド結合されます。最後に、右端のボックス「データソース」には、「データマッパー」を指す矢印と、「クエリオブジェクト」を示す双方向の矢印があります。

最後に、これが有用であると感じた人に、何らかの方法で拡張および拡張して、SOAサービススイートに貢献するよう依頼したいと思います。 すべてのフォークとプルリクエストは大歓迎です。

これがマイクロサービスの開始に役立つことを願っています。 サービスコードを確認したい場合は、完全なバージョンがGitHubで入手できます。