# Types

Consumer Types (based on [Guzzle 6](http://docs.guzzlephp.org/en/stable/)) are responsible for grouping events and processing both the outgoing requests and incoming responses. It offers the possibility to send specific headers or to write down individual / specific middleware.

### Register a new Type

{% code title="etc/di.xml" %}

```markup
<!-- Create a new Type based on a Virtual Type class -->
<virtualType name="Basic\Example\Model\Queue\Consumer\Type\AmazonAlexa"
             type="MageHook\Hook\Model\Queue\Consumer\Type\Type"/>

<!-- Register Type class -->
<type name="MageHook\Hook\Model\Queue\ConsumerTypeList">
  <arguments>
    <argument name="types"
              xsi:type="array">
      <item name="amazon_alexa"
            xsi:type="object">Basic\Example\Model\Queue\Consumer\Type\AmazonAlexa</item>
    </argument>
  </arguments>
</type>
```

{% endcode %}

{% code title="etc/webhooks.xml" %}

```markup
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:MageHook_Hook/etc/webhooks.xsd">
  <hook event="test_hook_event"
        title="Test Hook Title"
        purpose="Test Purpose"
        group="Test Group"
        type="amazon_alexa"/>
</config>
```

{% endcode %}

{% hint style="info" %}
The default Type will be used if no type attribute is defined.
{% endhint %}

### Configuration

Optionally you can use adjustable system configuration within a custom Consumer Type. You can find these settings within **Stores > Configuration > Services >MageHook > Consumer Types**.

#### Custom configuration

{% code title="etc/adminhtml/system.xml" %}

```markup
<config>
  <system>
    <section id="hook">
      <group id="consumer_type">
        <group id="type_custom"
               translate="label"
               sortOrder="20"
               showInDefault="1"
               showInWebsite="0"
               showInStore="0">
          <label>Custom Consumer Type system settings</label>

          <field id="timeout"
                 translate="label"
                 type="text"
                 sortOrder="10"
                 showInDefault="1"
                 showInWebsite="0"
                 showInStore="0">
            <label>Timeout</label>
            <tooltip>Describing the number of seconds to wait while trying to connect to a server (example: 3.14). Use 0 to wait indefinitely (the default behavior).</tooltip>
          </field>
        </group>
      </group>
    </section>
  </system>
</config>
```

{% endcode %}

The second Group `id` attribute corresponds together with the `CONFIG_GROUP` constant which can optionally be defined in your custom Consumer Type class.

Simply call the `getSystemConfig()` method in order to use those values within your custom Consumer Type. Please be aware that the 'default' consumer type configuration will always be merged. These can be simply overwritten by using the same field id within your system.xml.

### Type Middleware

Type Middleware gives you the richness to circle around the request and response cycle. It's based on the [Guzzle 6 Middleware](http://docs.guzzlephp.org/en/stable/handlers-and-middleware.html#middleware) layer and can be used real easily.

#### Push a global Middleware

{% code title="etc/di.xml" %}

```markup
<type name="MageHook\Hook\Model\Queue\Consumer\Type\AbstractType">
  <arguments>
    <argument name="config"
              xsi:type="array">
      <item name="middleware"
            xsi:type="array">
        <item name="hook_logger"
              xsi:type="object">Basic\Example\Model\Queue\Consumer\Type\Middleware\Example</item>
      </item>
    </argument>
  </arguments>
</type>
```

{% endcode %}

#### Push a Middleware into a specific Type

{% code title="etc/di.xml" %}

```markup
<type name="Basic\Example\Model\Queue\Consumer\Type\AmazonAlexa">
  <arguments>
    <argument name="config"
              xsi:type="array">
      <item name="middleware"
            xsi:type="array">
        <item name="hook_logger"
              xsi:type="object">Basic\Example\Model\Queue\Consumer\Type\Middleware\Example</item>
      </item>
    </argument>
  </arguments>
</type>
```

{% endcode %}

Middleware will always be pushed on top of the default Stack. You are able to sit in front or after a specific Middleware by using `$stack->before()` or `$stack->after()` within a Plugin on the public abstract `prepareMiddleware()` method.

### Type module development

A basic set of rules are applied in order to keep things readable.

1. Always use a HookType prefix
2. Type modules can possess events
3. Use readable namespaces
