+
+

ラボ 2: Product APIのMySQLデータベース接続

概要

このラボでは、MySQL データベースに接続して生成されたサブフローを実装します。 操作はとてもシンプルなため、すべての操作を実装します。

ステップ 1: プロジェクトにデータベース・コネクタを追加

プロジェクトにデータベースコネクタを追加する必要があります。 そのためには、以下の手順に従ってください。

  1. Mule パレットに移動します。

  2. Add Modules をクリックします。

    module8 lab2 add module
  3. Database を選択します。

  4. 水色のパネルにアイコンをドラッグ&ドロップします。

    module8 lab2 add database module

    パレットに戻ると、データベース・コネクタが表示されます。

    module8 lab2 palette database connector

ステップ 2: プロパティファイルの作成

Muleのベストプラクティスは、接続情報をパラメーター化することです。 データベースコネクタを設定するために、このベストプラクティスを活用します。

  1. src/main/resources に config という名前のフォルダを作成します。

  2. src/main/resources/configに configuration.yaml というファイルを作成します。

    module8 lab2 config file
  3. configuration.yamlファイルに以下のテキストを挿入します。

    mysql:
      host: "services.mythicalcorp.com"
      port: "3306"
      user: "product"
      password: "Mule1379"
      database: "products_test"

    パスワードは、Mule Credential Vaultを使用して暗号化できます。

  4. configuration.yamlファイルを保存します。

  5. api.xml ファイルに戻ります。 Global Elements タブを押します

    module8 lab2 global elements
  6. Create(作成) ボタンを押して、Configuration Properties(構成プロパティ) を検索します。

    module8 lab2 configuration properties
  7. OKを押します。

  8. ファイルのテキストボックスに config/configuration.yaml と入力します。ファイル参照も可能です。

    module8 lab2 configuration properties file

ステップ 3: Get Products フローの実装

このステップでは、get:\productフローを実装します。データベースからproductを取得するには、次の実装が必要です:

  • データベースからレコードを取得します。

  • レコードをjson形式に変換します。

以下の手順を参考にしてください:

  1. productを取得するフローを探します。

    module8 lab2 delete get products set payload

    もう一度確認: get:\product:api-config flow で作業していることを確認してください。

  2. このフローにDatabase Connectorを追加します。

  3. Database Connector をクリックし、 Transformation の前にSelect アイコンをドラッグ&ドロップします。

    Database Connector を Source セクションではなく、Process セクションにドロップします。
  4. データベース アイコンをダブルクリックすると、構成パネルが表示されます。

  5. 名前を Get Products に変更します。

    module8 lab2 name database component get products
  6. これでプロパティが定義できたので、新しいコネクタ構成を追加してみましょう。

    ドロップしたDatabase Connectorに戻り、クリックしてプロパティを開き、コネクタ構成のmodule8 studio plus buttonボタンをクリックします。

  7. 名前Products_Database_Configuration と入力します。

  8. Connection でMySQL Connectionを選択します。

    database connection(データベース接続)を選択すると、JDBCドライバの追加を求められます。

  9. Configure…​ ボタンを押します。新しいウィンドウが開きます。

  10. Add Maven depenency を選択します。

  11. 以下のデータを入力します:

    • Group id: mysql

    • Artifact id: mysql-connector-java

    • Version: 8.0.20

      module8 lab2 add jdbc dependency
  12. Finish をクリックします。

    Anypoint Studioは、依存関係を自動的にダウンロードします。

  13. データベースの設定では、プロパティに以下の値を指定します:

    • Host: ${mysql.host}

    • Port: ${mysql.port}

    • User: ${mysql.user}

    • Password: ${mysql.password}

    • Database: ${mysql.database}

      module8 lab2 db config 1
      Muleは、余分な設定を必要とせずに、デフォルトでconfiguration.yamlファイルに入れた設定プロパティの${key}だけで設定できます。
  14. Test Connection をクリックして接続性を確認します。

    module8 lab2 db config test connection success
  15. OK をクリックします。

  16. 再び OK をクリックしてMySQLの設定を閉じます。

    データベースの設定が完了したので、クエリを追加します。

    SELECT  p.id, p.name, p.description, p.product_number, p.manufactured, p.colors, p.categories, p.stock, p.safety_stock_level, p.standard_cost, p.list_price, p.size, p.size_unit_measure_code, p.weight, p.weight_unit_measure_code, p.days_to_manufacture, p.images,  p.modified_date, p.created_date
    FROM product p
    LIMIT 10
    "LIMIT 10" パラメータを使用して、最大10項目までしか取得できないようにクエリを制限しています。
    module8 lab2 get products query

    多くのお客様は、お気に入りのクエリツール(SQL Query Analyzer, TOAD, DBVisualizer, …​.)を使用して、必要なクエリを作成し、スタジオのテキストボックスに貼り付けています。

    次に、データベースのレコードをJSON形式に変換する必要があります。

  17. Transform Message アイコンをダブルクリックします。左側にはクエリからのフィールドが、右側にはAPIが返すフィールドが表示されます。フィールド間をドラッグ&ドロップすることで、フィールドをグラフィカルにマッピングすることができます。

    このTransform Messageコンポーネントは、MuleSoftのユニバーサルDataWeave変換言語を使用して、データをどの形式へ変換するかを指定します。 XMLの場合にxpath/XSLTを使用したり、JSONやCSVの場合にコードを書いて変換といったことを行う必要はありません。すべての変換にDataWeaveを使用してください。DataWeaveは、Muleの内部でデータをクエリして変換するためのシンプルで強力なツールです。

    module8 lab2 get products transform illustration
  18. 既存の内容を削除して、以下のDataWeaveによる変換をテキストビューにコピーします。

    %dw 2.0
    output application/json
    ---
    payload map (product, index) -> {
    	id: product.id,
        categories: (product.categories default "") splitBy ",",
        colors: (product.colors default "") splitBy ",",
        createdDate: product.created_date as String {format: "yyyy-MM-dd"},
        modifiedDate: product.modified_date as String {format: "yyyy-MM-dd"},
        safetyStockLevel: product.safety_stock_level as Number,
        stock: product.stock as Number,
        daysToManufacture: product.days_to_manufacture,
        name: product.name,
        description: product.description,
        images: (product.images default "") splitBy ",",
        listPrice: product.list_price,
        manufactured: product.manufactured,
        productNumber: product.product_number,
        size: product.size,
        sizeUnitMeasureCode: product.size_unit_measure_code,
        standardCost: product.standard_cost,
        weightUnitMeasureCode: product.weight_unit_measure_code,
        weight: product.weight
    
    }

    colours、categories、imagesは配列であり、データベース内ではカンマで区切られた文字列として保存されているので、その文字列を", "で区切られた各要素に分割するSplit By関数を使用しています。より複雑なマッピング要件をサポートするために、DataWeave内で利用可能な関数が複数用意されています。詳細については、DataWeave documentation を参照してください。

    module8 lab2 get products transform complete
  19. 以上でこの手順は終了です。Transform Messageのウィンドウに表示されている保存をクリックします。

  20. ここまでで、API の実装をテストする準備が整いました。

    ラボ 1 と同じ手順に従って以下を行ってください。

    • アプリケーションを起動します。

    • ログをチェックして、正常にデプロイされていることを確認します。

    • コンソールまたはPostmanを使用して、Get Productsへアクセスしてテストします。場合によっては、Content-TypeおよびAcceptヘッダーの設定を application/jsonにする必要があるかもしれません。エラーレスポンスを受信した場合は、インストラクターに問い合わせてください。

  21. ここまでの一連の操作でAPIからのレスポンスを受信し、MySQLデータベースからproductを取得することができました。ラボ1でのレスポンス内容と異なることが確認できます。

    module8 lab2 get products postman results

    (結果の例です。結果については異なる場合があります。)

    このフローが動作していることを確認できたので、次の実装に移ります。何か問題があれば、インストラクターに問い合わせてください。

ステップ 4: 特定のproductを取得するフローを実装

このステップでは、get:\product/{id}フローを実装します。

データベースからproductを取得するには、次のようにします:

  • データベースからレコードを取得します。

  • レコードが見つかったかどうかを確認します。

  • 見つかった場合は、そのレコードをjson形式に変換します。

  • 見つからなかった場合は、"Not found" というレスポンスを作成します。

以下の手順を参考にしてください:

  1. get:\product/{id}フローからすべてのTransform Messageを削除します。これを行うには、アイコンを右クリックしてDeleteを選択するだけです。または、アイコンを選択してDeleteキーを押します。

  2. SelectコンポーネントをDatabase Connectorからドラッグ&ドロップします。

  3. アイコンをダブルクリックして設定タブを開きます。

  4. 以下のパラメータを入力して完了です:

    • Display Name: Get Product By ID

    • Connector configuration: Products_Database_Configuration を選択します。

    • SQL Query Text:

      SELECT p.id, p.name, p.description, p.product_number, p.manufactured, p.colors, p.categories, p.stock, p.safety_stock_level, p.standard_cost, p.list_price, p.size, p.size_unit_measure_code, p.weight, p.weight_unit_measure_code, p.days_to_manufacture, p.images,  p.modified_date, p.created_date
      FROM product p
      WHERE p.id = :id
  5. 入力パラメータを追加してみましょう。 fx ボタンをクリックしてから、Transformationアイコンをクリックします。

    module8 lab2 press transform button

    新しいウィンドウが表示されます。

  6. 検索ボックスでidを検索します。Attributes → uriParams → id と辿るとみつけることができます。

  7. InputエリアからOutputエリアへidフィールドをドラッグ&ドロップします。

    module8 lab2 select transform
  8. module8 lab2 done button ボタンを押します。

    ここではパラメータを使用したクエリを記述しています。クエリ内で変数を使用するように記述し、もう1つのテキストボックスでパラメータを定義します。

    module8 lab2 select by id configuration

    productが見つかったかどうかを検証します。商品が存在しない場合は例外処理を発生させるように実装します。 そのためには Validations Module を追加する必要があります。

  9. Mule Paletteに移動し、Validation Moduleを追加します。

  10. Validationコネクタを選択し、is not empty collection をドラッグ&ドロップします。

    フローは以下のようになるはずです:

    module8 lab2 add validator

    このバリデータコンポーネントは VALIDATION:EMPTY_COLLECTION型 の例外処理を起こします。 上位のフローはこの例外をキャッチし、404(Not Found)レスポンスを返答します。

  11. これを実現するには、 api-main フローで定義されているエラー処理に進みます。

  12. On Error Propagate type: APIKIT:NOT_FOUND のコンポーネントを見つけてください。

    module8 lab2 error handling
  13. アイコンをクリックします。

    設定プロパティが表示されます。

  14. Type テキストボックスをクリックします。

    module8 lab2 click type

    チェックボックスのリストが開き、キャッチできる可能性のあるすべてのエラーが表示されます。

  15. VALIDATION:EMPTY_COLLECTION を選択します。

    module8 lab2 validation empty collection

    エラーが表示されていない場合は、APIKIT:NOT_FOUND テキストの後にカンマで区切って、エラー名を手動で入力してください。最終的な文字列は APIKIT:NOT_FOUND,VALIDATION:EMPTY_COLLECTION である必要があります。

  16. パネルの右上にある保存アイコンを押します。

    次に先ほどのGetメソッドに戻り、フローの最後にTransform Messageコンポーネントを追加します。

    このスクリプトをDataWeaveトランスフォームのテキストビューにコピーします:

    %dw 2.0
    output application/json
    var product = payload[0]
    ---
    {
    	id: product.id,
    	name: product.name,
    	description: product.description,
    	manufactured: product.manufactured,
    	productNumber: product.product_number,
    	colors: (product.colors default "") splitBy "," ,
    	categories:(product.categories default "") splitBy "," ,
    	safetyStockLevel: product.safety_stock_level,
    	standardCost: (product.standard_cost default "0.0") as String {format: "##.##"} as Number,
    	listPrice: (product.list_price default "0.0") as String {format: "##.##"} as Number,
    	stock: product.stock,
    	safetyStockLevel: product.safety_stock_level,
    	daysToManufacture: product.days_to_manufacture,
    	size: product.size,
    	sizeUnitMeasureCode: product.size_unit_measure_code,
    	weight: product.weight,
    	weightUnitMeasureCode: product.weight_unit_measure_code,
    	daysToManufacture: product.days_to_manufacture,
    	images: (product.images default "") splitBy ",",
    	modifiedDate: (product.modified_date default "") as Date {format: "yyyy-MM-dd"},
    	createdDate: (product.created_date default "") as Date {format: "yyyy-MM-dd"}
    }
  17. Transform Message は、DBのレコードをレスポンス用に定義されたJSON形式に変換します。データベースのSelectは行のリストを返すので、1レコード分の内容を扱うようにするために、最初のレコードを選択します。

    module8 lab2 get product transform config
  18. 先ほどと同様にAPIを実行しDBにはいっているIDと、そうでないIDを使って "product/{id}"をGETで呼び出してみてください。

  19. テスト終了後、コンソールビューMuleランタイムを停止します。

    最終的にはこのようなフローになるはずです。

    module8 lab2 get by id final flow

このフローが動作していることが確認できたので、次の実装に移りましょう。何か問題があれば、インストラクターに問い合わせてください。

ステップ 5: Create Product フローを実装

このステップでは、post:\productフローを実装します。データベースにproductを作成するには、以下を行う必要があります:

  • DBにproductを挿入する。

  • productとIDを応答として返します。

以下の手順で説明していきます:

  1. post:\product:application\json:api-config flowからTransform Messageコンポーネントを削除します。これを行うには、その上で右クリックして「Delete」を選択するか、選択して「Delete」キーを押します。

  2. パレットを使って、必要なコンポーネントをドラッグ&ドロップして、次ようなフローを作成します:

    module8 lab2 post product initial
  3. Insertコンポーネントを設定することから始めます。以下のようにパラメータを設定して、商品をデータベースに保存します:

    • Display Name: Insert Product

    • Connector configuration: Products_Database_Configuration

    • SQL Query Text:

      INSERT INTO product(name, description, product_number, manufactured, colors, categories, stock, safety_stock_level, standard_cost, list_price, size, size_unit_measure_code, weight, weight_unit_measure_code, days_to_manufacture, images, modified_date, created_date)
      VALUES(:name, :description, :productNumber, :manufactured, :colors,  :categories, :stock, :safetyStockLevel, :standardCost, :listPrice, :size, :sizeUnitMeasureCode, :weight, :weightUnitMeasureCode, :daysToManufacture, :images,CURDATE(), CURDATE() );
  4. module8 lab2 transform button ボタンをクリックして、DataWeaveパネルを開きます。

  5. 以下の内容を記述してTransform Messageを完成させます:

    %dw 2.0
    output application/json
    fun getManufacturedCode(value) = if (value == true) 1 else 0
    ---
    {
            categories: (payload.categories default []) joinBy ",",
            colors: (payload.colors  default []) joinBy ",",
            daysToManufacture: payload.daysToManufacture,
            description: payload.description,
            images: (payload.images  default []) joinBy ",",
            listPrice: payload.listPrice,
            manufactured: getManufacturedCode(payload.manufactured),
            name: payload.name,
            productNumber: payload.productNumber,
            safetyStockLevel: payload.safetyStockLevel,
            size: payload.size,
            sizeUnitMeasureCode: payload.sizeUnitMeasureCode,
            standardCost: payload.standardCost,
            stock: payload.stock,
            weight: payload.weight,
            weightUnitMeasureCode: payload.weightUnitMeasureCode
    }
    module8 lab2 post product database config

    DataWeaveでは関数を宣言して if else 構文が使えることを確認してください。 ここでは、生成された値をbooleanからintegerに変換しています。

    この操作は新しいproductを作成するので、新しく生成されたIDを取得する必要があります。これをどのように実装するかは、データベースエンジンのドライバーによって異なります。

  6. MySQLの場合は、"Insert Product" ブロックの "Advanced "に進みます。

  7. Auto Generated Keys セクションを見つけます。

  8. Auto Generated KeysTrue に設定します。

  9. Auto Generated Keys column namesで「Edit inline」を選択します。

    1. 下の表に値 id を追加します。

      このような構成になります:

      module8 lab2 post product database config 2

      元のペイロードを失いたくないので、生成されたキーを変数に保存します。

  10. Advancedの中で、Output値が表示されるまで下にスクロールします。

  11. 以下の値を入力してください:

    • Target Variable: generated_key

    • Target Value: #[payload.generatedKeys.GENERATED_KEY]

      module8 lab2 advance panel
  12. 次に、レスポンスのTransform Messageを設定します。 このステップでは、元のリクエストペイロードとデータベースから返されたIDをマージする必要があります。以下に示したスクリプトを使うことで実現することができます。 元のリクエストのペイロードを取得し、「id」というフィールドを追加しています。

    module8 lab2 transform message
  13. 次の変換を追加します:

    %dw 2.0
    output application/json
    ---
    payload ++
    id: vars.generated_key
    module8 lab2 transform message detail
  14. 最後に、カスタムビジネスイベントを構成しましょう。Custom Business Eventを追加およびパラメータの設定を行い、作成したproductの情報を今後のビジネス分析のために記録します:

module8 lab2 custom business event
module8 lab2 custom business event design
  1. Display Name: New Product Created Event

  2. Event Name: New Product Created Event

  3. Key Performance Indicators テーブルで、これら2つの属性を追加します。:

    Name Expression / Value

    Product ID

    #[payload.id]

    Product Name

    #[payload.name]

    module8 lab2 post product event config
    1. 先ほどの手順でAPIを実行し、"products"をPOSTで呼び出して動作していることを確認してみてください。

      product ID は一意でなければならないので、ランダムな値に変更する必要があります。この変更を行うにあたって問題がある場合は、直接データベースに問い合わせて値を提供するようにインストラクターに依頼してください

      テスト終了後、コンソールビューからMuleランタイムを停止します。

      このフローが動作していることが確認できたので、次の実装に移りましょう。何か問題があれば、先に進む前にインストラクターへご連絡ください。

ステップ 6: Update Product フローを実装

このステップでは、put:\product{id}フローを実装します。データベース内のproductを更新するには、データベースへUPDATEをコールするだけです。

以下の手順で進めていきます:

  1. put:\product{id}フローからコンポーネントを削除します。これを行うには、それぞれを右クリックしてDeleteを選択するか、コンポーネントを選択してDeleteキーを押します。

  2. パレットから必要なコンポーネントをドラッグ&ドロップして、以下のようなフローを作成します:

    module8 lab2 put product initial
  3. 以下のパラメータでデータベースを構成します:

    • Display Name: Update Product

    • Connector configuration: Products_Database_Configuration

    • SQL Query Text:

      update product
      set name = :name, description = :description, product_number = :productNumber, manufactured = :manufactured, colors = :colors,
      categories= :categories, stock = :stock, safety_stock_level = :safetyStockLevel, standard_cost = :standardCost, list_price = :listPrice, size = :size,
      size_unit_measure_code = :sizeUnitMeasureCode, weight = :weight, weight_unit_measure_code = :weightUnitMeasureCode, days_to_manufacture = :daysToManufacture,
      images = :images,  modified_date = CURDATE()
      where id = :id
  4. module8 lab2 fx button ボタンをクリックし、さらに module8 lab2 transform button ボタンをクリックして DataWeave パネルを開きます。

  5. 以下のスクリプトを記述し、完成させます。

    %dw 2.0
    output application/java
    fun getManufacturedCode(value) = if (value == true) 1 else 0
    ---
    {
            id: attributes.uriParams.id,
            categories: (payload.categories default []) joinBy ",",
            colors: (payload.colors default []) joinBy ",",
            daysToManufacture: payload.daysToManufacture,
            description: payload.description,
            images: (payload.images default []) joinBy ",",
            listPrice: payload.listPrice,
            manufactured: getManufacturedCode(payload.manufactured),
            name: payload.name,
            productNumber: payload.productNumber,
            safetyStockLevel: payload.safetyStockLevel,
            size: payload.size,
            sizeUnitMeasureCode: payload.sizeUnitMeasureCode,
            standardCost: payload.standardCost,
            stock: payload.stock,
            weight: payload.weight,
            weightUnitMeasureCode: payload.weightUnitMeasureCode
    }

    前のステップで行ったように、更新されたレコードの数を記録します。

  6. loggerコンポーネントを開いて下さい。

  7. module8 lab2 fx button を押して、DataWeave式を追加していきます。

  8. 次の DataWeave 式を追加します:

    "Number of affected rows: " ++ ((payload.affectedRows default -1 )as String)
    module8 lab2 logger update config

    前のステップと同様にテストを実行し、終了後、コンソールビューを使用してMuleランタイムを停止します。

    このフローが動作していることが確認できたので、次の実装に移りましょう。何か問題があれば、インストラクターに問い合わせてください。

ステップ 7: Delete Productフローを実装

このステップでは、delete:\product{id}フローを実装します。データベース内のproductを削除するには、データベースに対してDELETEをコールするだけです。

以下の手順に従って進行します:

  1. delete:\product{id}フローからすべてのコンポーネントを削除します。これを行うには、各コンポーネントを右クリックしてDeleteを選択するか、コンポーネントを選択してDeleteキーを押します。

  2. パレットを使って、必要なコンポーネントをドラッグ&ドロップして、このようなフローを作成します:

    module8 lab2 delete product initial
  3. データベースコンポーネントを次のように構成します:

    • Display Name: Delete Product

    • Connector configuration: Products_Database_Configuration

    • SQL Query Text:

      delete from product where id=:id
    • Input Parameters:

      {
        id:attributes.uriParams.id
      }

      削除されたレコードの数を確認するためにloggerを追加します。

  4. loggerコンポーネントに注目

  5. module8 lab2 fx button を押して、DataWeave式を追加します。

  6. 次のDataWeave式を追加します:

    "Number of records deleted: " ++ (payload as String)
    module8 lab2 logger config

    204を返しているので、メッセージのペイロードはありません。

    これで、前のステップと同じようにAPIを実行して、存在しているid(前のステップで作成したものなど)で "products/{id}"に対してDELETEを呼び出して、動作しているかどうかを確認することができます。

    時間に余裕があれば、GET /products/{id}フローのように実装を拡張して、レコードが存在しない場合にNOT FOUND応答を返すようにすることもできます。

    テストが終わったら、コンソールビューを使用してMuleランタイムを停止します。

    何か問題があれば、先に進む前にインストラクターへご連絡ください。

    これで実装が動作するようになったので、次のラボではエンドツーエンドでのテストを行い、ユニットテストを追加していきます。

まとめ

以下の手順を完了しました:

このモジュールでは、MySQLデータベースに対してシステムAPIを実装しました。 また、AnypointStudioに組み込まれているローカルのMuleランタイムでAPIを実行してテストしました。

演習の中でDataWeaveの使用法を紹介しました。DataWeaveは、データベースのレコードをjson形式に変換する強力なツールです。また、Database Connectorを使用して、データベースへのアクセスがどれだけ簡単にできるかを確認しました。

ここで注意しなければならないのは、APIの実装が実際のMuleアプリケーションであるということです。統合アプリケーションを構築したり、APIを公開したりするのに、追加の知識は必要ないので、Mule開発者は統合とAPIの両方に簡単に取り組むことができます。

詳細については、 Dataweave のドキュメントを参照してください。

詳細については、 Database Connecter のドキュメントを参照してください。

詳細については、 Configuration Properties のドキュメントを参照してください。

詳細については、 Secure Configuration Properties のドキュメントを参照してください。

ラボ 3 に進んでください。

Submit your feedback!
Share your thoughts to help us build the best workshop experience for you!
Take our latest survey!