Requests with a list
This tutorial will use a very simple API to demonstrate how you can deal with repeating (group) elements in requests.
The scenario's presented meet different, sometimes weird, requirements, so each solution starts with explaining some specific requirements.
All the samples here are working with this same OpenApi specification.
Scenario A
Requirements
For each requested contact, the response has an entry in the list of contacts. To test exception handling, an HTTP 502 will be returned when contactId = 'X'
is amongst the requested contacts.
To make it easy for testers to 'track' usage of the mocked-data in the system-under-test, whenever possible, the contactId is included in response-fields.
Steps
- Open apiUi and paste this link as OpenApi specification.
Since our requirements will be completely met by scripting, there is no need to specify correlation-elements and there is also no need to enter data. - Open the script-editor by clicking on the script-button for the only operation that apiUi currently shows.
- Enter below code and you are ready
Rpy.listofcontacts.rspns200 := nil;
with Req.listofcontacts.listof.contact do
{
for each ._ req do
{
if req. = 'X' then
{
Rpy.listofcontacts.undefined.responseCode := '502';
Exit ();
}
with Rpy.listofcontacts.rspns200.body.ListOfcontacts.contact do
{
with new ._ rpy do
{
rpy.contactId := req.;
rpy.contactType := 'customer';
rpy.name := 'Name' + rpy.contactId;
rpy.phonenumber := '+3112345678';
rpy.emailaddress := rpy.contactId + '@emailaddress.com';
rpy.created := '2001-01-02T03:04:05.678Z';
}
}
}
}
The script starts with initializing the response to make sure no data from the editor is used unintentionally.
Tip: On writing code, use the editors context-menu to help you select field names.
Sample request/response
Success Request
POST /sample/openapi/listofcontacts/2 HTTP/1.0
Content-Type: application/json
Accept: application/json
{ "contact":
[ "A"
, "B"
]
}
Success Response
HTTP/1.1 200 OK
Content-Type: application/json
{ "ListOfcontacts":
{ "contact":
[
{ "contactId": "A"
, "contactType": "customer"
, "name": "NameA"
, "phonenumber": "+3112345678"
, "emailaddress": "A@emailaddress.com"
, "created": "2001-01-02T03:04:05.678Z"
}
,
{ "contactId": "B"
, "contactType": "customer"
, "name": "NameB"
, "phonenumber": "+3112345678"
, "emailaddress": "B@emailaddress.com"
, "created": "2001-01-02T03:04:05.678Z"
}
]
}
}
Failure Request
POST /sample/openapi/listofcontacts/2 HTTP/1.0
Content-Type: application/json
Accept: application/json
{ "contact":
[ "A"
, "B"
, "X"
]
}
Failure Response
HTTP/1.1 502 Bad Gateway
Bad Gateway
Scenario B
In this ficticious scenario we will work with six contacts as shown below. A request for the ListOfContacts can contain at most six contactId's in any order. The response should contain the requested contacts in the order as shown below.
contactId | contactType | name | emailaddress | created |
---|---|---|---|---|
A | prospect | Jan | Jan@emailaddress.com | 2001-04-14T20:08:30.731 |
B | customer | Kees | Kees@emailaddress.com | 2001-04-15T20:08:30.731 |
C | suspect | Koos | Koos@emailaddress.com | 2001-04-16T20:08:30.731 |
D | suspect | Piet | Piet@emailaddress.com | 2001-04-17T20:08:30.731 |
E | supplier | Bart | Bart@emailaddress.com | 2001-04-18T20:08:30.731 |
F | supplier | Ties | Ties@emailaddress.com | 2001-04-19T20:08:30.731 |
Steps
- Open apiUi and paste this link as OpenApi specification.
- Copy/paste data from here
- follow above link and copy entire json-data
- in apiUi right-click on element
listofcontacts.rspns200.body.ListOfcontacts
and choose Paste from clipboard - click on the grid symbol at element
listofcontacts.rspns200.body.ListOfcontacts.contact
to see the data you just pasted in a table.
- Open the script-editor by clicking on the script-button for the only operation that apiUi currently shows.
- Enter below code and you are ready
with Rpy.listofcontacts.rspns200.body.ListOfcontacts.contact rpylist do
{
with Req.listofcontacts.listof.contact reqlist do
{
for each rpylist._ rpy do
{
string ws.requested := 'false';
for each reqlist._ req do
{
if req. = rpy.contactId then
ws.requested := 'true';
}
if ws.requested = 'false' then
rpy. := nil;
}
}
}
This script loops through the response list and just removes entries from that list that are not amongst the requested contatctId's. Determining if a contactId is requested is done in a sub-loop.
Sample request/response
Request
POST /sample/openapi/listofcontacts/2 HTTP/1.0
Connection: keep-alive
Content-Type: application/json; charset=utf-8
Accept: application/json
{ "contact":
[ "D"
, "B"
]
}
Response
HTTP/1.1 200 OK
Content-Type: application/json
{ "ListOfcontacts":
{ "contact":
[
{ "contactId": "B"
, "contactType": "customer"
, "name": "Kees"
, "emailaddress": "Kees@emailaddress.com"
, "created": "2001-04-15T20:08:30.731"
}
,
{ "contactId": "D"
, "contactType": "suspect"
, "name": "Piet"
, "emailaddress": "Piet@emailaddress.com"
, "created": "2001-04-17T20:08:30.731"
}
]
}
}
Scenario C
Same as with Scenario B with the only difference that the contacts in the response have to be in the same order as the requested contacts.
No need to worry about duplicates in the list of contacts nor not-existing contacts.
Steps
- Open apiUi and paste this link as OpenApi specification.
- Copy/paste data from here
- follow above link and copy entire json-data
- in apiUi right-click on element
listofcontacts.rspns200.body.ListOfcontacts
and choose Paste from clipboard - click on the grid symbol at element
listofcontacts.rspns200.body.ListOfcontacts.contact
to see the data you just pasted in a table.
- Open the script-editor by clicking on the script-button for the only operation that apiUi currently shows.
- Enter below code and you are ready
with Rpy.listofcontacts.rspns200.body.ListOfcontacts.contact rpylist do
{
with Req.listofcontacts.listof.contact reqlist do
{
integer ws.nrpy := Occurrences (rpylist._);
integer ws.n;
for each reqlist._ req do
{
ws.n := 0;
for each rpylist._ rpy do
{
if (rpy.contactId = req.)
and (ws.n < ws.nrpy) then
with new rpylist._ nwrpy do
{
nwrpy.contactId := rpy.contactId;
if Assigned (rpy.contactType) then nwrpy.contactType := rpy.contactType;
if Assigned (rpy.name) then nwrpy.name := rpy.name;
if Assigned (rpy.phonenumber) then nwrpy.phonenumber := rpy.phonenumber;
if Assigned (rpy.emailaddress) then nwrpy.emailaddress := rpy.emailaddress;
if Assigned (rpy.created) then nwrpy.created := rpy.created;
}
ws.n := ws.n + 1;
}
}
ws.n := 0;
for each rpylist._ do
{
if (ws.n < ws.nrpy) then
. := nil;
ws.n := ws.n + 1;
}
}
}
In this script, first for each entry in the request a corresponding entry is added to the original response-list of contacts. After this is done the original contacts are removed from the response-list.
As a result, the response-list contains contacts in the same order as the requested contact list.
Sample request/response
Request
POST /sample/openapi/listofcontacts/2 HTTP/1.0
Connection: keep-alive
Content-Type: application/json; charset=utf-8
Accept: application/json
{ "contact":
[ "B"
, "A"
, "D"
, "B"
]
}
Response
HTTP/1.1 200 OK
Content-Type: application/json
{ "ListOfcontacts":
{ "contact":
[
{ "contactId": "B"
, "contactType": "customer"
, "name": "Kees"
, "emailaddress": "Kees@emailaddress.com"
, "created": "2001-04-15T20:08:30.731"
}
,
{ "contactId": "A"
, "contactType": "prospect"
, "name": "Jan"
, "emailaddress": "Jan@emailaddress.com"
, "created": "2001-04-14T20:08:30.731"
}
,
{ "contactId": "D"
, "contactType": "suspect"
, "name": "Piet"
, "emailaddress": "Piet@emailaddress.com"
, "created": "2001-04-17T20:08:30.731"
}
,
{ "contactId": "B"
, "contactType": "customer"
, "name": "Kees"
, "emailaddress": "Kees@emailaddress.com"
, "created": "2001-04-15T20:08:30.731"
}
]
}
}