{{ transformations:IterateWebRequestAction.png}}
====== ITERATE WEB REQUEST ======
Category: Workflow / External\\
\\
=====Description=====
This action sends multiple uniform HTTP requests to a web server. Requests are configured using values from columns of the input dataset. One request is sent for each line of the input dataset. Responses can be automatically appended into one dataset or saved as files into a designated folder. This action requires a configured Web Location connector.
Supports all HTTP methods - GET, POST, PUT, DELETE, HEAD, OPTIONS, CONNECT, TRACE, PATCH.
To simplify development and debugging, the action has a preview pane that shows the first raw HTTP request that would be sent as well as a response preview.
\\
=====Use cases=====
The action is intended for repeating uniform interactions with REST APIs, cloud applications, and websites.
\\
=====Action settings=====
^ Setting ^ Description ^
|Connector/Base URL*|Select or create a Web Location connector, or enter the base URL for the request. Select between "Connector" and\\ "Base URL" using the selector to the //left// of the input field.|
|Request method|Select the request method. Options: //GET//, //HEAD//, //POST//, //PUT//, //DELETE//, //CONNECT//, //OPTIONS//, //TRACE//, and //PATCH//.|
|Path%%**%%|See "Path setting", below.|
|Add URL parameters%%**%%|Check to insert parameters into the URL. See "URL parameters", below, for details.|
|Body%%**%%|See "Request Body settings", below.|
|Headers%%**%%|See "Request Headers settings", below.|
|Response%%**%%|See "Response settings", below.|
* Setting can be specified using a [[:parameters|parameter]].\\
%%**%% Setting can be specified using a [[:parameters|parameter]] or the values in a selected table column.\\
\\
====Path setting====
The URL path is appended to the endpoint URL specified in the Web Location connector. EasyMorph parameters can be inserted into the path using curly braces if needed. Alternatively, the entire path can be specified with a parameter or using the values in a specified column.
**Examples:**
^ Web Location endpoint ^ Web Request path ^ Actual HTTP request URL ^ Notes ^
| %%https://example.com/api/v3%% | products | %%https://example.com/api/v3/products%% | |
| %%https://example.com/api/v3%% | product/123 | %%https://example.com/api/v3/product/123%% | |
| %%https://example.com/api/v3%% | product/{ProductID} | %%https://example.com/api/v3/product/123%% |Assuming {Product ID} = 123 |
\\
====URL parameters====
URL parameters can be specified as name-value pairs. They will be encoded and appended as a URL query. //Value// can be omitted, if needed. In this case, only the name will be appended to the URL query.
**Example:**
^ Web Location endpoint ^ Web Request path ^ Name ^ Value ^ Actual HTTP request URL ^
| %%https://example.com/api/v3%% | orders | year | 2019 | %%https://example.com/api/v3/orders?year=2019%% |
If a Web Location connector has permanent URL parameters specified they will be appended to all requests that are made using the connector. This can be used for scenarios where all requests should have an API key or secret specified.
\\
====Request Body settings====
The request body can be specified in one of the following ways:
__**JSON**__\\
This body type is suitable for sending simple JSONs. The JSON object is constructed from a list of name-value pairs. Both name and value can be specified with a parameter or using values in a specified column. If the value itself is a JSON object/array it's inserted verbatim thus allow object nesting.
When this body type is selected header "Content-Type:application/json" is set automatically.
**Example:**
^ Name ^ Value ^
|Country |CA |
|Province|ON |
|Name |EasyMorph |
|Incorporated |2014 |
|Tags | ["ETL", "analytics", "dataprep", "automation"]|
**Resulting request body (JSON):**
{
"Country":"CA",
"Province":"ON",
"Name":"EasyMorph",
"Incorporated":2014,
"Tags":["ETL", "analytics", "dataprep", "automation"]
}
\\
__**Column**__\\
This body type uses the values in a selected column for the body.
\\
__**Form**__\\
This body type is equivalent to submitting a web form. Name-value pairs are encoded as if it was a web-form.
Header Content-Type is automatically set to "application/x-www-form-urlencoded".
**Example:**
^ Name ^ Value ^
|Country |CA |
|Province|ON |
|Name |EasyMorph |
|Incorporated |2014 |
\\
**Resulting request body:**
Country=CA&Province=ON&Name=EasyMorph&Incorporated=2014
\\
__**File**__\\
The request body is read from the specified file and inserted verbatim. When //Upload file (multi-part upload)// is selected, additional parameters can be defined as well.
\\
====Request Headers settings====
Additional request headers can be specified. Header names and values can be specified either explicitly, using parameters, or using values in a specified column.
Note that header Content-Length is calculated and added to every request automatically.
If a Web Location connector has permanent headers specified they will be added to all requests that are made using the connector. This can be used for scenarios where all requests should have an API key or secret.
\\
====Response settings====
There are 3 modes for how a response would be processed in the Web Request action:
__**Return no data, fail if HTTP error**__\\
In this case, if the response status is not an error (i.e. HTTP status codes 4xx or 5xx) then the response will be ignored. This is basically a "fire-and-forget" mode that is intended for submitting data and updates to remote endpoints.
__**Return response as the action result**__\\
In this mode, the response (error or not) is always received and transformed into a 1-row dataset in EasyMorph. The column names in such a dataset correspond to the response body, response status, and response headers (one column per header).
__**Save response body to file, fail if HTTP error**__\\
In this case, if the response status is not an error (i.e. HTTP status codes 4xx or 5xx) then the response body (only the body!) will be saved verbatim into the specified file (the filename of which can be created automatically, or specified using values in a specified column).
\\
====Options settings====
Check //Send requests in parallel// to enable parallel requests and choose the //Degree of parallelism// (from 2 to 20) from the drop-down. With this option selected, the order in which requests are sent is no longer guaranteed.
\\
=====Remarks=====
The action is very similar to the [[transformations:webrequest|Web Request]] action, except that it's intended for sending multiple requests instead of one, and its properties can be specified using column values besides constants and parameters.
\\
====Cookies====
Currently, there is no way to set HTTP cookies explicitly in the Web Request action. Under the hood, all cookies that come with responses to web requests are automatically stored in a cookie container that exists only during project execution. Cookies from the container are automatically appended to outgoing requests made using the same Web Location connector. If a project workflow includes calls/iterations, the cookie container is passed to called/iterated modules or projects which in turn can add new cookies to it. This can be used for cookie-based web sessions.
When project execution is finished, the cookie container is discarded. No cookies are stored in the project or Web Location connector.
When developing workflows with web requests it may be necessary to re-run parts of workflows. In this case, it is recommended to always start from the Web Request actions that do authentication so that the session cookies can be set under the hood.
Iterate Web Request automatically sends the //User-Agent HTTP header// (e.g. "User-Agent: EasyMorph 5.4") unless disabled in the [[connectors:weblocation|Web Location connector]].
\\
=====Community examples=====
* [[https://community.easymorph.com/t//1865/4|Dynamical genereting of path based on previous step]] ([[https://community.easymorph.com/uploads/short-url/70xVAnShgK4EiXuSa4HgMJtFAM2.morph|Project]]; Module: //Import and send//; Group: //Tab 1//; Table: //Send request//;\\ Action position: //2//)
* [[https://community.easymorph.com/t//2158/5|API pagination how I create loop]] ([[https://community.easymorph.com/uploads/short-url/rQmjCeA2LXPlqzxhL5N9IoCE5CR.morph|Project]]; Module: //responseToCSV//; Group: //Tab 1//; Table: //Fetch data from API//; Action position: //3//)
* [[https://community.easymorph.com/t//2160/1|How to pull data from web APIs with pagination]] ([[https://community.easymorph.com/uploads/short-url/dvCSpcEDXYZ8aB0B2gtnt7qulTF.morph|Project]]; Module: //Query API//; Group: //Group 1//; Table: //Query//; Action position: //2//)
* [[https://community.easymorph.com/t//2641/1|How to publish real-time data to streaming dataset in Power BI]] ([[https://community.easymorph.com/uploads/short-url/22DTxfF295TVGQhGyvWGsHyadRt.morph|Project]]; Module: //Main//; Group: //Tab 1//; Table: //Table 1//; Action position: //6//)
\\
=====See also=====
* [[transformations:webrequest|Web Request]]
* [[connectors:weblocation|Connector "Web Location"]]