Jenkins – Zephyr Enterprise Integration

Step 1 – Install the Zephyr Enterprise Jenkins Plugin

The first step to exporting data to Zephyr Enterprise is to download and configure the Zephyr Enterprise plugin.

From the Jenkins main page, click “Configure” and then “Manage Plugins.” From the “Manage Plugins” window, search for and install “Zephyr Enterprise.”

jenkinsAddons

Step 2 – Configure the Zephyr Enterprise Jenkins Plugin

Click the “Configure System” option in the “Manage Jenkins” menu.

JenkConfig

Scroll down to “Zephyr Server Configuration” and enter your domain and login credentials.

Screen Shot 2018-05-29 at 10.30.39 AM

Click “Test Configuration.” If the test is successful, your Jenkins is properly configured to communicate with your Zephyr instance.

Step 3 – Generate an API Hook

Next, we need to create an API Fortress Webhook to export the test data to Jenkins. To do so, head to the Settings panel in API Fortress. This view, seen below, can be accessed from anywhere in the application by clicking the Gear icon in the top right corner of the screen. Note: You need Manager access to generate a Webhook. From Settings, click the API Hooks section and generate the hook for your project.

The next step depends on what you’re trying to test. The following steps are going to assume that you wish to run all of the tests in a project. You can also run a single test, or a series of tests with a certain tag. If you would like to learn more about that please contact API Fortress.

To import our data into Jenkins as JUnit, we’ll export it in JUnit format using a query parameter. Since we already have our API hook, we just need to add the parameter to do so.

As it stands, our API hook is as follows:

https://mastiff.apifortress.com/app/api/rest/v3/86f81b19-2d29-4879-91d9-6dbb2271fec0861

The normal command to run all of the tests in the project, per the API Fortress docs is /tests/run-all, so we append this on to the end of the API call. We also need to request JUnit output via query parameters. First, we need to set sync to true, and then we can set format to JUnit. In short, we need to append ?sync=true&format=junit. That gives us the final API call:

https://mastiff.apifortress.com/app/api/rest/v3/86f81b19-2d29-4879-91d9-6dbb2271fec0861/tests/run-all?sync=true&format=junit

Great! If we make this API call via a browser or a tool like Postman, we can see our results in JUnit.

Step 4 – Execute HTTP Call from Jenkins

From the Jenkins dashboard, let’s create a New Item. Next, we’re going to name and create a Freestyle Project. Click the OK button to proceed.

Scroll down the page until you see the “Add Build Step” pulldown menu. Select “HTTP Request.” This option will only be available if you installed the HTTP Request plugin in the previous step. We’re going to paste the API call we created above into the URL line. If we save this configuration, we can run the build and see Jenkins receive our JUnit test results in real time.

Next, we’re going to click the “Advanced” button. Scroll to the bottom of the newly opened view and enter a filename of your choice into the “Output Response to File” line.

Step 5 – Publish JUnit Test Results in Jenkins

Now that we’re receiving JUnit data from API Fortress in Jenkins, we need to publish the data so that we can use it further downstream. Click “Add Post-Build Action” and then “Publish JUnit Data.”

In the new window, enter the same filename that we saved our JUnit data to in the API call in the previous step.

Now, we’ve enabled Jenkins to execute API Fortress tests and receive the test data in JUnit format. Next, we’re going to allow it to pass this data on to Zephyr.

Step 6 – Exporting Data to Zephyr

Click “Add Post-Build Action” and select “Publish Test Results to Zephyr Enterprise.” Since we configured the Zephyr plugin in step 2, Zephyr information should populate automatically from your Zephyr Enterprise instance. Select the project, release and cycle of your choice and save the build.

Screen Shot 2018-05-29 at 10.30.05 AM

Test data will now export to Zephyr every time this project is built.

Screen Shot 2018-05-29 at 10.31.14 AM

 

Key/Value Store

The Key/Value Store

The Key/Value store allows API Fortress users to create temporary key/value pairs that can be accessed across different tests. The Key/Value store is accessed via the Key/Value Store Component.

Screen Shot 2018-05-24 at 1.22.48 PM

An extremely important point to note is that these key/value pairs are temporary. They expire after 24 hours has elapsed since the last update to the value itself. 

The Key/Value Store Component has 4 methods available for use. They are:

  • Set

    • Set will create a new key/value pair in the Key/Value store. The value is entered in the “Object” field.

Screen Shot 2018-05-24 at 10.50.19 AM

  • Load

    • Load will recall a value from the Key/Value store when provided with a key.

Screen Shot 2018-05-24 at 10.50.36 AM

  • Push

    • Push will add a value to the end of an existent value of the datatype “Array” in the Key/Value store. If no such key exists, it will create a new array containing the passed in value.  The passed in value is entered in the “Object” field.

Screen Shot 2018-05-24 at 10.51.09 AM

  • Pop

    • Pop will remove a value from the end of an existent value of the datatype “Array” in the Key/Value store.

Screen Shot 2018-05-24 at 10.50.52 AM

 

Basic Workflow

Let’s take a look at how this workflow works in a practical setting. The first example will be a simple set and retrieve of a value in the Key/Value Store.

First, we’ll make a GET request to an endpoint.

Screen Shot 2018-05-24 at 1.21.40 PM

Next, we’ll add a K/V Store component.

component

This first K/V Store component (we’re going to incorporate several) is going to set the Key/Value pair in the Store, so we’re going to use “Set.

Screen Shot 2018-05-24 at 1.46.41 PM

In this case we’re setting the Key “prods” equal to “products[0].name”, which in this case evaluates to “Baseball Cap.”

Next, we’re going to retrieve this Key/Value pair from the store with the “Load” method. In the K/V Store “Load” component, we’re going to assign the retrieved value to the variable “kvprods.”

Screen Shot 2018-05-24 at 1.47.22 PM

Finally, we’ll add in a “Comment” component to ensure that the data was recovered successfully.

Screen Shot 2018-05-24 at 1.48.01 PM

When we run the test, we’re presented with the following result:

Screen Shot 2018-05-24 at 1.48.28 PM

Success!

Push/Pop Workflow

Next, we’re going to take a look at how “Push” and “Pop” work. “Push” and “Pop” are both array methods and behave as they normally do outside of this context. “Push” will append a value to the end of an array. “Pop” will remove the last value in an array.

First, we’re going to use “Push.” It should be noted that “Pop” works similarly but with the opposite result. “Popalso assigns the removed value to a variable which can be used in the context of the test, but can no longer be accessed from the Key/Value Store. We’ll discuss this further when we take a look at “Pop.”

First, we’re going to send a GET request and assign a key in the Key/Value Store to a value from the response body. In this case, we’re going to use “Color,” which is an array.

Screen Shot 2018-05-24 at 1.49.16 PM

Next, we’re going to “Load” and “Comment” this key. We’re doing that so we can actually see the change on the test report at the end of this workflow.

The next step is to “Push” the new data on to the end of the existing array.

Screen Shot 2018-05-24 at 2.43.53 PM

In this case, we’re pushing the integer 999 onto the prods array.

Finally, we’re going to “Load” the modified data into the test from the K/V Store.

Screen Shot 2018-05-24 at 1.51.48 PM

When we run the test, we’re presented with the following test report.

Screen Shot 2018-05-24 at 1.51.59 PM

The comments show us clearly that we have pushed the number 999 onto the array stored in the key prods. 

Now, we’ve added something to the array. Let’s remove it with “Pop!”

The first step is to introduce a “Pop” K/V Store component.

Screen Shot 2018-05-24 at 2.31.17 PM

We provide the “Pop” component with the name of the key from the Key/Value Store, and the name of the variable we’d like to assign the popped value to. Remember, “Pop” removes the last value in an array and returns the value itself. In this case, we’re going to assign it to a variable called “Popped.”

Next, we’re going to recall the modified key from the Key/Value Store. Then, we’re going to Comment both the recalled Key/Value Store value AND the previously popped value.

Screen Shot 2018-05-24 at 2.28.58 PM

In the Test Report, we can clearly see the full workflow. First, we assigned an array to the Key/Value Store with “Set.” Then, we added to that array with “Push.” Finally, we removed the added value with “Pop.” Each time we made a change, we used “Load” to retrieve an updated value from the Key/Value Store.

Screen Shot 2018-05-24 at 2.29.09 PM

The last two comments show the final state of the array in the Key/Value Store and the popped value itself. The popped value will only be available within the scope of this test run. The array in the Key/Value Store will remain retrievable and until 24 hours after it’s most recent modification.

Note: “Load” does not reset the timer. Only “Set,” “Push,” and “Pop” reset the timer. 

Footprint

Consider a scenario where a route has a parameter in it. Let’s take a look at an example:

http://www.whereever.com/<id>/details

Each individual rest run for this route will produce a new line in the metrics view:
http://www.whereever.com/1/details
http://www.whereever.com/2/details
http://www.whereever.com/3/details
http://www.whereever.com/4/details

This sort of reporting will quickly turn our dashboard into a disorganized mess. To produce a single endpoint for reporting from each one of these calls, you can use what we call a ‘footprint.’

How is this accomplished? In the test, you need to add a Config component to the I/O component as seen below:

configFootprint

The Config component has two fields:
Name: the name you want to assign. In this case, you MUST to enter ‘footprint’
Value: The value for the configuration component. To set up a footprint, you must enter the same URL that’s in the I/O Component. Any parameterized portion of the URL must be wrapped in square brackets.

Based upon our example, the value in this case would be:

http://www.wherever.com/whatever/[id]/details

In the project dashboard, after every run of the test instead of
http://www.whereever.com/whatever/1/details
http://www.whereever.com/whatever/2/details
http://www.whereever.com/whatever/3/details
http://www.whereever.com/whatever/4/details

you will find only one endpoint, displayed as:
http://www.whereever.com/whatever/[id]/details

For each endpoint you can use more square brackets, one for each variable that could assume multiple values. For example: http://www.whereever.com/[whatever]/[id]/details/[colors]/whatever

When you write the value of the config, for the ‘static’ part of the endpoint you can also call a variable as in any I/O operation.

Example: ${protocol}/${domain}/[whatever]/[id]/details/[colors]/whatever

is valid syntax.

 

 

Dynamic dates

Have you ever needed to pass a future date as part of the request inside of a test? Perhaps as a check-in or check-out date? You could enter it as static value, but that means you would have to periodically update the date as time went on. Creating a dynamic date in API Fortress is a simple solution for this sort of situation.

Here’s the procedure:

  1. First, open the Composer and add a Set (variable)
    setVar
  2. Then, enter the variable name and leave the mode as String
    varComp
  3. Lastly, enter the following string in the Value field:${D.format(D.plusDays(D.nowMillis(),35), ‘yyyy-MM-dd’)}

valueField
Let’s analyse what this string means:

D.nowMillis(): returns the current Unix epoch in milliseconds
D.plusDays(): returns the provided milliseconds, plus the provided number of days (in our example, we have added 35 days to today date)
D.format(): creates a timestamp with the given format, using the current timezone (in our example yyyy-MM-dd)

As result, you will have something like 2018-05-15

You can obtain a past date, starting from todays date with the following string:
${D.format(D.minusDays(D.nowMillis(),35), ‘yyyy-MM-dd’)}

You can also create a date based on a specified timezone:
${D.format(D.plusDays(D.nowMillis(),35), ‘yyyy-MM-dd’,’America/New_York’)}
The above string create the same date as our first example using New York (EST) as the timezone.

For more details about you can check our reference page

 

How to create a dynamic header

Most APIs have only one response format, either JSON or XML. But what should we do in the case of an API endpoint that can return either JSON OR XML? We could write two different tests, with one supporting each response type, but we’d be repeating a good amount of code in both tests. API Fortress allows you to test both, using the same I/O component and assertion components for almost all test cases. In a few cases, we’ll need to add a bit of extra logic to allow the platform to distinguish between the two formats.

Let’s consider the scenario where you need to pass in the Header the Accept value that is ‘application/json’ if you are testing the JSON and ‘application/xml’ if you are testing the XML. Usually in this case, you should make two different calls, as shown in the image below, in order to be able to pass the different values in the header:

Let’s consider an example. The API call in question requires an “Accept” header. This “Accept” header needs a value of “application/json” if you are testing the JSON case and “application/xml” if you are testing the XML case. Below, we can see the solution to this problem that requires setting up two separate calls. It’s not particularly adherent to the DRY rule of programming. (Don’t repeat yourself!)

both_calls
API Fortress allows you to solve this issue by making only one call.

    1. Let’s start adding the different formats as variables, as seen below.inputSets
    2. Now, we can remove one call and add the format variable in the “Mode” input.
      varFormat
    3. The header is still static at this point. We need to turn it into a dynamic one which changes to suit the data type of the API we are testing. We add a variable component above the I/O operation that will return the appropriate value.setDynamVar
    4. if (format == 'xml')
      return "application/xml";
      else return "application/json";
      To explain: the ‘acceptHeader’ variable will have ‘application/xml’ as value if format is ‘xml’ and ‘application/json’ otherwise (since we have only two different formats, it will be ‘application/json’ only for JSON format
    5. Now, we can finally remove the ‘static’ header and add the ‘dynamic’ header by changing the Header value to ‘${acceptHeader}’dynamicHeader
      Now, the test will be executed two times; once for ‘XML’ and once for ‘JSON’, ensuring that the header will have the correct value.

Jenkins – Export JUnit Data / Test Results

Step 1 – Install Jenkins HTTP Plugin

Log in to your Jenkins account. First, click “Manage Jenkins,” then click “Manage Plugins.”

We’re going to need the HTTP Request plugin. To find the plugins, click the “Available” tab in the Plugins menu and use the filter in the top right corner to search for it.

Step 2 – Generate an API Hook

The first step to integrating API Fortress into your CI/CD process is to grab the generated API hook for the project in question. To do so, head to the Settings panel in API Fortress. This view, seen below, can be accessed from anywhere in the application by clicking the Gear icon in the top right corner of the screen. Please note you need Manager access to generate a webhook. From Settings, click the API Hooks section and generate the hook for your project.

The next step depends on what you’re trying to test. The following steps are going to assume that you wish to run all of the tests in a project. You can also run a single test, or a series of tests with a certain tag. If you would like to learn more about that please contact API Fortress.

To import our data into Jenkins as JUnit, we’ll export it in JUnit format using a query parameter. Since we already have our API hook, we just need to add the parameter to do so.

As it stands, our API hook is as follows:

https://mastiff.apifortress.com/app/api/rest/v3/86f81b19-2d29-4879-91d9-6dbb2271fec0861

The normal command to run all of the tests in the project, per the API Fortress docs is /tests/run-all, so we append this on to the end of the API call. We also need to request JUnit output via query parameters. First, we need to set sync to true, and then we can set format to JUnit. In short, we need to append ?sync=true&format=junit. That gives us the final API call:

https://mastiff.apifortress.com/app/api/rest/v3/86f81b19-2d29-4879-91d9-6dbb2271fec0861/tests/run-all?sync=true&format=junit

Great! If we make this API call via a browser or a tool like Postman, we can see our results in JUnit. We’re almost there.

Step 3 – Execute HTTP Call from Jenkins

From the Jenkins dashboard, let’s create a New Item. Next, we’re going to name and create a Freestyle Project. Click the OK button to proceed.

Scroll down the page until you see the “Add Build Step” pulldown menu. Select “HTTP Request.” This option will only be available if you installed the HTTP Request plugin in the previous step. We’re going to paste the API call we created above into the URL line. If we save this configuration, we can run the build and see Jenkins receive our JUnit test results in real time. These test results can then be passed along to platforms like qTest or Zephyr in a CI/CD pipeline.

Jenkins – QA Symphony qTest Integration

The following procedure will allow you to integrate API Fortress test results into your qTest instance. By passing JUnit test data through Jenkins and into qTest, your API Fortress test results can be visible in the same space as the rest of your tests.

Install Jenkins Plugins (qTest)

Log in to your Jenkins account. In order for the qTest integration to work, we need to extend Jenkins with a couple of plugins. First, click “Manage Jenkins,” then click “Manage Plugins.”

We’re going to need both the qTest plugin, and the HTTP Request plugin. To find the plugins, click the “Available” tab in the Plugins menu and use the filter in the top right corner to search for them. Install both.

Step 3 – Integrate API Fortress into your CI/CD Process

The first step to integrating API Fortress into your CI/CD process is to grab the generated API hook for the project in question. To do so, head to the Settings panel in API Fortress. This view, seen below, can be accessed from anywhere in the application by clicking the Gear icon in the top right corner of the screen. Please note you need Manager access to generate a webhook. From Settings, click the API Hooks section and generate the hook for your project.

The next step depends on what you’re trying to test. The following steps are going to assume that you wish to run all of the tests in a project. You can also run a single test, or a series of tests with a certain tag. If you would like to learn more about that please contact API Fortress.

To import our data into qTest via Jenkins, we’ll export it in JUnit format using a query parameter. Since we already have our API hook, we just need to add the parameter to do so.

As it stands, our API hook is as follows:

https://mastiff.apifortress.com/app/api/rest/v3/86f81b19-2d29-4879-91d9-6dbb2271fec0861

The normal command to run all of the tests in the project, per the API Fortress docs is /tests/run-all, so we append this on to the end of the API call. We also need to request JUnit outputt via query parameters. First, we need to set sync to true, and then we can set format to JUnit. In short, we need to append ?sync=true&format=junit. That gives us the final API call:

https://mastiff.apifortress.com/app/api/rest/v3/86f81b19-2d29-4879-91d9-6dbb2271fec0861/tests/run-all?sync=true&format=junit

Great! If we make this API call via a browser or a tool like Postman, we can see our results in JUnit. We’re almost there.

Step 4 – Add API Fortress Step to qTest

From the Jenkins dashboard, let’s create a New Item. Next, we’re going to name and create a Freestyle Project. Click the OK button to proceed.

Scroll down the page until you see the “Add Build Step” pulldown menu. Select “HTTP Request.” This option will only be available if you installed the HTTP Request plugin in the previous step. We’re going to paste the API call we created above into the URL line.

Next, we’re going to click the “Advanced” button. Scroll to the bottom of the newly opened view and enter a filename of your choice into the “Output Response to File” line.

Now that we’ve told Jenkins to output the JUnit response to a file, we need to make that file accessible to downstream after-build steps. Click “Add post-build action” and select “Publish JUnit Results.”

In the new window, enter the same filename that we saved our JUnit data to in the API call in the previous step.

Now, we’ve enabled Jenkins to execute API Fortress tests and receive the test data in JUnit format. Next, we’re going to allow it to pass this data on to qTest.

Click on the “Add Post-Build Action” pulldown below the build step we just created and select “Submit JUnit Test Results to qTest.”

 

Enter the URL of your qTest instance and your qTest – Jenkins API Key. Click the “Retrieve Data” button to populate the next few menus. Select a project, release, and environment (optional) where you want to push the test results. Choose the final options with regards to how you wish the data to be stored in qTest, and click save.

From now on, every time you click “Build Now” with this test, the results will be exported to the qTest Project of your choice automatically.

Introduction to Integration Testing

A core feature of API Fortress Is the ability to perform integration testing.
See our video example here.

(You can follow along with the example in the demonstration by viewing it in the API Fortress platform here: Quick Integration Demo)

Integration testing is core to creating a strong API testing strategy. Microservices are built to work together, and an integration test allows you to create end-to-end tests that resemble common user flows. Only testing individual endpoints is a good start, but will miss a huge amount of problems that occur when all the services need to work together.
Let’s consider an example. Company A has an authentication server. This server, when given the proper user credentials, returns an authentication token. This token is required for all other calls throughout the platform’s API environment. Without this first API call, none of our other API calls can work. The proper tool for this job is an integration test.

Getting Our Token

 First, we need to make our POST call to the authorization server.

Screen Shot 2018-04-12 at 12.20.27 PM

 In this case, the request body is the username and password. In return for proper credentials, the authentication server is going to return a user token.
Next, we need to use this token to make further calls to the application.

Setting a Variable

First, we need to assign the token to a variable. Variables are used to store data temporarily for test. You can use the Vault for more permanent variables (more information here). We do this so we don’t have to manually invoke or set it every time it is needed.
We add a “Set” component, and enter the information as seen in the image below.
Screen Shot 2018-04-12 at 12.31.27 PM
We’re calling the variable “access_token” and assigning the value to ${payload.Token}.
The response body from the original post call was saved to a variable called “payload.” The key to access the token is named “Token,” so we find it by calling “payload.Token”. We wrap this all in ${} so that API Fortress knows to interpret what’s between the brackets instead of using it literally.

Making Follow-up Calls

We’re nearly there. We made our authentication POST call, we then saved the token to a dynamic variable named “access_token.” Now it is time for the third, and for this example, final step.

This API has a cart function that requires a user token in order to add items to a cart, or to view the items currently in the cart. We are going to use the access token we were granted by the authentication server to add some items to a cart.

Screen Shot 2018-04-12 at 12.38.22 PM

We will use a PUT request to the cart endpoint to update the cart. We’re setting the “usertoken” header to ${access_token} (same notation as before). The request body is a JSON object that the server will recognize as items and quantities. That part isn’t important for the purposes of this demonstration.

Why?

As we said in the start, it is imperative to not just exercise endpoints, but validate that an entire series of microservices are working. It’s best to do that by writing tests that emulate common and uncommon user flows. A critical part of that work involves creating reusable variables to allow the test to work at any time, with any data.

By making a request for a fresh token at the beginning of the sequence, and then assigning it to a variable, we know that any time we run this test we’re doing so with a valid access token and that our access token is automatically being passed to all follow-up calls.

We can keep using the same access token over and over, as seen below.

Screen Shot 2018-04-12 at 12.39.20 PM

That is simple integration test. Please feel free to reach out to us should you have any questions, or take a look at the Examples project which contains other examples.

GitHub and large data sets

Set up GitHub

  • 1When creating the token make sure you’re selecting the public_repo subcategory or the repo category based on which type of repository that will host your input data.2
    Keep in mind that GitHub will show you the token only once, so make sure you’re copying and pasting it somewhere safe and accessible.
  • Create a repository that will host your input data if one doesn’t exist already.
  • Commit and push a data source file. It can be a CSV, JSON or XML file. We will use a CSV file for the purposes of this example.3

    Create a simple test

  • Create a test
  • Introduce the GitHub component and configure it accordingly4
  • Account is your GitHub username
  • Repository is the name of the repository that your data file is pushed to.
  • Branch is the repository branch that the desired version of the data file is in.
  • Token is the token described above, generated in the GitHub platform.
  • Variable is the variable that the payload will be stored under.
  • Path is the name of the file in the repository.
  • Mode is the filetype of the file in the repository.
  • The system will retrieve the document, parse it as a CSV file and assign it to the inputData variable
  • (optional) Verify that everything is set up correctly by adding a comment printing the parsed data as in:5
  • (Optional) Run the test:6
    NOTE: API Fortress will parse a CSV file as an array (rows) of arrays (columns), so access to the data is positional. 
  • Now, let’s iterate over a subset of this input set. Introduce a selection strategy if necessary:
    7This will iterate over a subset of 5 randomly selected items. Other strategies are described in Appendix A
  • (Optional) Within each iteration, we suggest that you introduce a comment that will help you identify which item you’re looking at for debugging purposes.8 9
  • Use the data to perform your HTTP call:10
  • Introduce some assertions for testing purposes11
  • And run it12

Appendix A: selection strategies

Simple selectors

  • None. If the number of iterations is greater than 100, the system will randomly select 100 elements, unless you override the maximum iterator size.
    • Pick(n). Ask the system to randomly select a n-sized sample of elements.
      Example: inputData.pick(5)

 

  • Slice. If you’re interested in using a specific slice of data from the inputData, you can slice it according to your needs.
    Example: inputData[10..20] (will select items from index 10 to index 20)

 

Advanced Slicing

Assume you have a 1000 lines CSV file and you need to use them all. While this is technically possible (by overriding the maximum number of iterations) the usefulness of the test may vary on:

  1. How long the HTTP request takes
  2. How complex the test is going to be
  3. The number of errors the test may trigger

Moreover, the readability of the resulting document may degrade when trying to debug an issue.

Here’s a slicing technique we suggest to ease these points.

  • Introduce the following 2 variables in the global parameters:

    13
  • Use the following expression in your each statement:
    inputData[offset.toInteger()..offset.toInteger()+limit.toInteger()]
    Which reads: slice inputData from the offset index to the offset+limit index

    Note: the toInteger() command is required as variables are always strings and we need to work with numbers.

    By doing so we are setting a baseline: as a default test input data from index 0 to index 99.
  • Introduce as many environments as the slices count, overriding the offset variable15
    Now you can run the test on specific 100 elements slices, by selecting the environment.16 1718
  • Finally, you can schedule your slices accordingly:19

Following redirects

By default, API Fortress handles redirects as per RFC standard. So if you are performing a GET and the response wants to redirect you somewhere else, you don’t need to do anything since the redirect will be followed automatically.

Now, since the RFC says that a redirected I/O call should perform the same operation as the original call, and given that, say, re-posting, is a security threat, API Fortress will not automatically follow redirects for any other I/O operation.

Boring, you may say, but following the exact RFC specifications is how you make sure that any client will not be caught off guard!

This specific scenario can be handled applying the following steps:

Make the I/O operation (let’s consider a POST as an example)

  1. step1
    The response header contains the ‘Location’ field. Let’s make sure it’s there, by performing the call in our console tool.step2highlighted
  2. Craft a GET to the ‘Location’ retrieved in the response header of the previous call (i.e. ${payload_response.headers[‘location’]})

    Post307

And you’re done.