# コネクターの構築 - 有用なコーディングパターン

Workato プラットフォームには、既知の制限事項がいくつかあり、現在修正作業が行われています。ここでは、カスタムコネクターの構築中に直面するかもしれない制限事項を簡単に解決する方法について説明します。

# 特殊文字の処理

Workato のデータピルと関係が深い、既知の制限事項が1つあります。入力項目や出力項目を以下の特殊文字を含む名前で定義すると、入力項目はまったく表示されず、出力データピルは正しく表示されません。

-<>!@#$%^&*()=+{}|;‘`~?

たとえば、次のように定義されたスキーマがあったとします。

{
  name: “due-date”
}

このスキーマは文字列入力項目では表示されず、出力ではデータピルではなく長い文字列として表示されます。

破損したデータピル スキーマの名前に特殊文字が含まれているとデータピルは正しく表示されない

正しくは、以下の画像のように表示されるべきです。

適切なデータピル 名前に特殊文字を含めないようにして適切に表示する必要がある

幸いにも回避策が存在しているため、あなたのコネクターにもそれを組み込むよう強くお勧めします(場合によっては、以下のコードをコピーして貼り付けるのも良いでしょう)。ここでは、format_schemaformat_payloadformat_schema という3つのメソッドを作成します。これらのメソッドは、各 execute ブロックの冒頭と末尾に呼び出して利用できます。これまで紹介してきた例の中でも、アクションを定義するときには同様の処理を行ってきました。

# format_schema

サンプルコードスニペット:

format_schema: lambda do |schema|
  if schema.is_a?(Array)
    schema.map do |array_value|
      call('format_schema', array_value)
    end
  elsif schema.is_a?(Hash)
    schema.map do |key,value|
      if %w[name].include?(key.to_s)
        value = call('replace_special_characters',value.to_s)
      elsif %w[properties toggle_field].include?(key.to_s)
        value = call('format_schema', value)
      end
      { key => value }
    end.inject(:merge)
  end
end,

名前にキーが含まれる項目はエラーの原因になるため、不適切なスキーマを受け取って、それに含まれる名前を扱えるものに変換してくれるサービスメソッドが必要となります。上記のメソッドは、与えられたスキーマ内を再帰的に検索し、特殊文字を有効な文字列に置き換えます。以下に入力の例を示します。

[
  {
    control_type: "text",
    label: "Txn date",
    type: "string",
    name: "Txn-Date"
  }
]

この入力は次のように変換されます。

[
  {
    control_type: "text",
    label: "Txn date",
    type: "string",
    name: "Txn__hyp__Date"
  }
]

この処理を行った後もラベルは維持されているので、Workato 内で項目を表示しても、エンドユーザーが違いに気付くことはありません。このサービスメソッドは、静的スキーマと動的スキーマのどちらにおいても呼び出せます。

# format_payload

サンプルコードスニペット:

format_payload: lambda do |payload|
  if payload.is_a?(Array)
    payload.map do |array_value|
      call('format_payload', array_value)
    end
  elsif payload.is_a?(Hash)
    payload.map do |key, value|
      key = call('inject_special_characters',key)
      if value.is_a?(Array) || value.is_a?(Hash)
        value = call('format_payload', value)
      end
      { key => value }
    end.inject(:merge)
  end
end,

このメソッドは、ジョブからの入力が execute ブロックに渡されたときに呼び出されるべきものです。その段階において、このメソッドは入力ハッシュ内を再帰的に検索し、特殊文字が置換されたことを示すマーカーを見つけて、それを元の形に変換します。このメソッドの戻り値は、置換されていた特殊文字すべてが戻された、フォーマット済みのペイロードです。

# format_response

サンプルコードスニペット:

format_response: lambda do |payload|
  if payload.is_a?(Array)
    payload.map do |array_value|
      call('format_response', array_value)
    end
  elsif payload.is_a?(Hash)
    payload.map do |key, value|
      key = call('replace_special_characters',key)
      if value.is_a?(Array) || value.is_a?(Hash)
        value = call('format_response',value)
      end
      { key => value }
    end.inject(:merge)
  end
end,

レスポンスを処理する際も、それを Workato の有効なスキーマに一致させる必要があります。そのため、ネットワークトラフィックからのレスポンスに含まれるキーは変換し、特殊文字を置き換える必要があります。この処理は、HTTP コールからレスポンスを受け取った直後に実行する必要があります。

# replace_special_characters および inject_special_characters

サンプルコードスニペット:

replace_special_characters: lambda do |input|
  input.gsub(/[-<>!@#$%^&*()+={}:;'"`~,.?|]/,
  '-' => '__hyp__',
  '<' => '__lt__',
  '>' => '__gt__',
  '!' => '__excl__',
  '@' => '__at__',
  '#' => '__hashtag__',
  '$' => '__dollar__',
  '%' => '__percent__',
  '^' => '__pwr__',
  '&' => '__amper__',
  '*' => '__star__',
  '(' => '__lbracket__',
  ')' => '__rbracket__',
  '+' => '__plus__',
  '=' => '__eq__',
  '{' => '__rcrbrack__',
  '}' => '__lcrbrack__',
  ';' => '__semicol__',
  '\'' => '__apost__',
  '`' => '__bckquot__',
  '~' => '__tilde__',
  ',' => '__comma__',
  '.' => '__period__',
  '?' => '__qmark__',
  '|' => '__pipe__',
  ':' => '__colon__',
  '\"' => '__quote__'
)
end,

inject_special_characters: lambda do |input|
  input.gsub(/(__hyp__|__lt__|__gt__|__excl__|__at__|__hashtag__|__dollar__|\__percent__|__pwr__|__amper__|__star__|__lbracket__|__rbracket__|__plus__|__eq__|__rcrbrack__|__lcrbrack__|__semicol__|__apost__|__bckquot__|__tilde__|__comma__|__period__|__qmark__|__pipe__|__colon__|__quote__|__slash__|__bslash__)/,
  '__hyp__' => '-',
  '__lt__' => '<',
  '__gt__' => '>',
  '__excl__' => '!',
  '__at__' => '@',
  '__hashtag__' => '#',
  '__dollar__' => '$',
  '__percent__' => '%',
  '__pwr__' => '^',
  '__amper__' => '&',
  '__star__' => '*',
  '__lbracket__' => '(',
  '__rbracket__' => ')',
  '__plus__' => '+',
  '__eq__' => '=',
  '__rcrbrack__' => '{',
  '__lcrbrack__' => '}',
  '__semicol__' => ';',
  '__apost__' => '\'',
  '__bckquot__' => '`',
  '__tilde__' => '~',
  '__comma__' => ',',
  '__period__' => '.',
  '__qmark__' => '?',
  '__pipe__' => '|',
  '__colon__' => ':',
  '__quote__' => '"'
)
end

# まとめ

コネクターにオブジェクトベースのアクションやトリガーを用意することは、強く推奨されます。それらはユーザーエクスペリエンスを向上させるだけでなく、適切に構築されていれば、コネクターの拡張がはるかに容易になります。 以下に、これまで取り上げた主なコンセプトをまとめます。

  1. サービスメソッドで各オブジェクトの基本スキーマを定義しましょう。アクションの種類に基づいてスキーマを調整できるようにする入力引数も忘れずに含めてください。
  2. object_definitions を利用して、選択されたオブジェクトに基づいた適切な入力/出力項目スキーマを取得しましょう。
  3. アクションやトリガーを定義するときは、すべてのブロックを宣言するようにし、特に description ブロックを忘れないようにしましょう。これにより、ユーザーの使い勝手が大幅に向上します。
  4. 一般的な処理は execute ブロックに含めてください。しかし、個別的な処理には専用のオブジェクト-実行メソッド (create_invoice_execute など) を利用しましょう。 たとえば、execute ブロックで format_paylodformat_response を利用し、その後で create_#{object}_execute メソッドを利用します。

# 使いやすさのルール

優れたコネクターは、アーキテクチャだけでなく、ルックアンドフィールも優れています。この後は、コネクターを使いやすくする方法について詳しく説明します。


Last updated: 2023/8/31 1:07:14