Object Definitions and structuring input and output fields

Object Definitions are an important component of the SDK. It allows you to define your schema for objects to be used in the actions and triggers. While we have gone through examples on how to do this directly from inside your input_fields: and output_fields: blocks, object_definitions allow you to declare it once and reuse it multiple times in various areas of your connector code.

Object definitions are a key indicator of well written code. It makes your custom connector more maintainable and easier to read.

After that, we will dive deeper into the details of how you can clearly define your input and output fields. This will have important effects on what end users see when building recipes using your connector.

Static object definitions

The most basic way to build an object definition is to define the field name and type

Sample code snippet

{
  title: 'My close.io connector',

  connection: {
    # Some code here
  },
  test: {
    # Some code here
  },
  actions: {

    get_lead_by_id: {
      input_fields: lambda do
        [
          { name: "lead_id", optional: false }
        ]
      end,

      execute: lambda do |connection, input|
        get("https://app.close.io/api/v1/lead/#{input["lead_id"]}/")
      end,

      output_fields: lambda do |object_definitions|
        object_definitions["lead"]
      end
    }

  },

  triggers: {
    # Some code here
  },

  object_definitions: {
    lead: {
      fields: lambda do
        [
          { name: "name", type: :boolean },
          { name: "email" },
          { name: "number"}
        ]
      end
    }
  }

  picklists: {
    # Some code here
  },
  methods: {
    # Some code here
  },
}

In this example, the object leads is being defined in the fields lambda function. This can then be easily referenced in the action above. Defined as an array of objects. Each field object corresponds to a field in the lead object.

Dynamic object definitions

Object definitions can also be used to dynamically generate input and output schemas. This is often done by a HTTP requests to metadata endpoints which return data about what fields to expect. Below we go through a simple example of using a GET request to a metadata endpoint to know what fields to expect in a form.

Sample code snippet

object_definitions: {
  form: {
    fields: lambda do |connection|
      get("https://api.unbounce.com/pages/#{connection['page_id']}/form_fields")["formFields"].
        map { |field| { name: field["id"] } }
    end
  }
}

Remember that the ultimate output of the lambda function would still have to be in the format that Workato expects. This often means using ruby methods like map to transform the response from an HTTP call.

Testing

Testing and debugging your object definitions can be done in the same way that you would for your actions or triggers. Make sure that your object definition is being used in a specific action and test that action in the code editor. HTTP calls from the object definition should be recorded in the Network tab and any puts functions in your object definition block should be displayed in the Console tab as well.

Structuring input and output fields

Up until now, our sample code snippets have largely only included the basic parameters such as name when defining input and output fields. Workato allows you to define a much larger set of variables that affect the way your fields are displayed to end users.

Key Definition
name The name of this field. For example id or created_at
label An optional key. All fields will have default labels based on the field name. Use this to change the default value of the field label.
hint An optional key. This allows you to add some hints below the input field to guide the user. Links to documentation can be given using HTML syntax.
type The data type of this field. Default value is "string". Should be given the symbol notation (prepend colon).
  • "string"
  • "integer"
  • "number"
  • "date_time"
  • "date"
  • "timestamp"
  • "boolean"
  • "object" Must be accompanied with properties:
  • array Must be accompanied with properties:
control_type This field relates only to input fields and it dictates the input field type to expose in a recipe. Refer to the list of Control types supported.
If this is declared for output fields, whether as an object definition or if it is hardcoded, it would be ignored.
pick_list If control_type is :select or :multiselect, this property is required. See more in Pick List chapter.
properties When defining nested objects, use the properties key to define the fields in the object. Remember to define the type as :array or :object
sticky Use this property to make the optional field visible on the Input section. For example: Since is optional field but to be displayed always under Input fields. Use sticky: true.
render_input An optional key. This must be accompanied with `parse_output`. Since our payloads are normally JSON objects, they are normally represented as strings. This field helps to convert them to other data types such like integers.
  • "integer_conversion" - converts input into data type integer
  • "render_iso8601_timestamp" - converts input into date string that confirms to ISO8601
  • "boolean_conversion" - converts input into data type boolean
parse_output An optional key. This must be accompanied with `render_output`. Since our payloads are normally JSON objects, they are normally represented as strings. This field helps to convert them to other data types such like integers.
  • "integer_conversion" - converts output into data type integer/number
  • "date_time_conversion" - converts input into a format that matches Javascript's Date objects toJson method
  • "boolean_conversion" - converts input into data type boolean
change_on_blur An optional boolean key. When true, config fields and dependent fields only evaluate the value when the user blurs out of the field instead of after every keystroke. This parameter often doesn't need to be configured.
support_pills An optional boolean key. When true, this field doesn't allow datapills to be mapped to it. This parameter often doesn't need to be configured.
custom An optional boolean key. When true, a special marker is introduced to indicate to the user that this field is custom. Normally used when dynamically generating object definitions which may contain custom fields.

Control types

Control types are a way for you to declare how input fields are displayed to users of your connector.

Control type Description
text Simple text input field with formula mode option.
text control type
text-area Long text input field with formula mode option.
text-area control type
plain-text Simple text input field without formula mode option.
plain-text control type
plain-text-area Long text input field with formula mode option. This input field can be expanded using the adjust icon.
plain-text-area control type
number Simple number field with icon to indicate either an integer or float value. This control type has formula mode option.
number control type
url Text field with icon to indicate a URL value. This control type has formula mode option.
url control type
select Control type to provide a predefined list of values to choose from. Make sure to include the pick_list property.
select control type
checkbox Simple Yes/No select interface. This control type adds an implicit toggle to text mode (for dynamic mapping and formula mode option).
checkbox control type
multiselect Control type similar to select with additional ability to select multiple values. This control type must be accompanied with pick_list and delimiter properties.
multiselect control type
date Control type indicating date value. This control type has formula mode option. date control type
date_time Control type indicating date with time value. This control type has formula mode option. date_time control type
phone Control type indicating phone value. This control type has formula mode option.
phone control type
email Control type indicating email value. This control type has formula mode option.
email control type
subdomain Control type to indicate a subdomain of a particular site. Typically used in connection fields. Make sure to include the url property.
subdomain control type
static-list Control type for arrays where the size of the array is statically determined by the recipe designer. Remember to define item_label, add_item_label, empty_list_title and empty_list_text.
static-list control type

Variations

Nested objects

Often, data returned from API request is not a simple one-level JSON. More often than not, the returned JSON object is much more complex, with multiple levels of nesting. This section aims to illustrate how to define nested fields.

Sample code snippet

{
  "id": "00ub0oNGTSWTBKOLGLNR",
  "status": "STAGED",
  "created": "2013-07-02T21:36:25.344Z",
  "activated": null,
  "lastLogin": "2013-07-02T21:36:25.344Z",
  "profile": {
    "firstName": "Isaac",
    "lastName": "Brock",
    "email": "isaac.brock@example.com",
    "login": "isaac.brock@example.com",
    "mobilePhone": "555-415-1337"
  },
  "credentials": {
    "provider": {
      "type": "OKTA",
      "name": "OKTA"
    }
  },
  "_links": {
    "activate": {
      "href": "https://your-domain.okta.com/api/v1/users/00ub0oNGTSWTBKOLGLNR/lifecycle/activate"
    }
  }
}

Nested object field profile can be defined type: :object with fields nested inside using properties. Properties should be an array of fields objects (just like fields within the user object).

object_definitions: {
  user: {
    fields: lambda do
      [
        {
          name: "id"
        },
        {
          name: "status"
        },
        {
          name: "created",
          type: :timestamp
        },
        {
          name: "activated",
          type: :timestamp
        },
        {
          name: "lastLogin",
          type: :timestamp
        },
        {
          name: "profile",
          type: :object,
          properties: [
            {
              name: "firstName"
            },
            {
              name: "lastName"
            },
            {
              name: "email",
              control_type: :email
            },
            {
              name: "login",
              control_type: :email
            },
            {
              name: "mobilePhone",
              control_type: :phone
            }
          ]
        }
      ]
    end
  }
}

Nested Arrays

The other common type of nested field is array of objects. This type of field contains a list of repeated objects of the same fields. The defining such fields will be very similar to defining objects. Take the following sample user object from Asana for instance.

Sample code snippet

{
  "data": {
    "id": 12149914544379,
    "email": "eeshan@workato.com",
    "name": "Ee Shan",
    "workspaces": [
      {
        "id": 1041269201604,
        "name": "Workato"
      },
      {
        "id": 498346130780,
        "name": "Product Documentation"
      }
    ]
  }
}

The workspaces array should be given type: :array as well as of: :object. This tells the object_definitions framework that the field contains an array of objects. Similar to nested objects, you will need to define properties, which is an array of fields corresponding to the fields of each object in the workspaces array.

object_definitions: {
  user: {
    fields: lambda do
      [
        {
          name: 'id',
          type: :integer
        },
        { name: 'name' },
        {
          name: 'email',
          control_type: :phone
        },
        {
          name: 'workspaces',
          type: :array,
          of: :object,
          properties: [
            {
              name: 'id',
              label: 'Workspace ID',
              type: :integer
            },
            { name: 'name' }
          ]
        }
      ]
    end
  }
}

Next section

The next section goes through some additional concepts related to object definitions which we call picklists. Pick lists allow you to declare dropdowns for your users instead of have to enter text. Go to our picklist documentation or check our our best practices for some tips on how to use object definitions.

results matching ""

    No results matching ""