The sample will be using the following policies, which are within the assemble panel in the APIC Manager.
- 2 x Invoke Policies.
- 1 Map Policy.
NOTE: this documentation is based on v5, but similar concepts can be applied to v2018 and v10.x.
API Path and Design in APIC v5
The following configuration are configurations for this API to function at a basic level without security.
This section walks through inputting the APIC API values for the client end.
1. Create a new API.
2. Ensure that base path is root ‘/’
3. Disable the security for the API
4. Create the path: name the path for your client app to invoke, such as /petstoreagg, and add a GET operation.
5. Navigate to the Properties section and update or add target-url to use http://petstore.swagger.io
6. Save the API.
API Path and Design in APIC v2018
This section walks through inputting the APIC API values for the client end as shown similar above, but for screenshots for v2018.
1. Create a new API.
2. Name the API, remove the base path to root ‘/’, and click Next.
3. Disable the security for the API and click Next.
4. Click Edit API. Navigate to the path section and add a path. Name the path for your client app to invoke, such as /petstoreagg, and add a GET operation.
5. Navigate to the Properties section and update or add target-url to use http://petstore.swagger.io and save the Property.
6. Save the API.
Assemble: Invoke Policies
This section will build out theinvoke policies, which would call 1. the Pet Store Inventory API to retrieve the inventory of the Pet Store, and 2. the Pet Store sold API.
The purpose is to invoke 2 different APIs and aggregating the responses.
Note: The procedure to create these policies will be the same in v2018.x.x.x.
7. Navigate to the Assemble tab on the APIC manager and update the Invoke to call the first Pet Store Inventory by entering $(target-url)/v2/store/inventory in the URL field, and set the Response object variable to vInventory. You may title the Invoke policy as Invoke: Inventory or something that highlights the function of this policy.
Note: The original source is as follows: https://petstore.swagger.io/v2/store/inventory
The response from the Inventory call looks like the following
{“00″:1,”placed”:7,”unavailable”:5,”availavvvvvble”:1,”happy”:1,”available”:68328,”[Tnn96]”:1,”zzzzz”:1,”none”:1,”whathwat”:4,”Just Born”:1,”Unavailable”:10,”status1″:1,”avaliable”:2,”xyz”:1,”lala”:1,”UNAVAILABLE”:1,”Available”:2,”‘; INSERT INTO Users(username, password, priv) VALUES (‘BobbyTables’, ‘kl20da$$’,’admin’);”:1,”1; select 1,2,3″:1,”laboris”:1,”scary”:4,”welcome”:2,”\\”); DROP TABLE users; –“:1,”availablennnnn”:5,”Dead”:1,”test”:3,”Nonavailable”:1,”ugly”:1,”raer”:2,”applicable”:1,”smrt”:1,”‘;UPDATE user SET type = ‘admin’ WHERE id = 23;–“:1,”kkkkkkk”:1,”gone”:2,”exit”:1,”1″:1,”2″:1,”ochko”:1,”avadsggfilable”:1,”I dont know”:2,”invalid”:1,”cancelled”:2,”nh”:3,”;”:3,”x-pending”:1,”flowStatus”:1,”adorable”:2,”aaa”:1,”not available anymore”:1,”allo”:1,”string”:358,”pending”:425,”available;pending;sold”:2,”asdfasdfasd”:1,”asdasd”:3,”dead”:2,”fghfgh”:1,”sold’ + (SELECT 0 FROM (SELECT SLEEP(28))qsqli_2222) + ‘”:1,”sd”:1,”not-available”:1,”notavailable”:4,”freaky”:12,”danilo”:1,”sold2″:1,”1111″:1,”not available”:8,”Inactive”:1,”tefolla”:1,”ok”:1,”playful”:1,”sold”:503,”slobodan”:1,”装逼中”:1,”available1″:2,”x-available”:9,”manco”:1,”status2″:1,”jack”:1,”example status”:4,”Broken”:1,”availa1111ble”:2,”101″:1,”sasaad”:1,”amet”:1,”2352464364576″:2,”0.9″:1,”x-sold”:2,”consectetur”:1}
8. Drag and drop another Invoke Policy into the processing line of the API (next to the Invoke: Inventory policy) and enter $(target-url)/v2/pet/findByStatus?status=sold for the URL, and vSold for the Response object variable. You could update the title as Invoke: Sold or something that highlights the function of this Invoke Policy.
Note: The original source is as follows: https://petstore.swagger.io/v2/pet/findByStatus?status=sold
Assemble: Map Policy
The 2 invoke policies will have stored the response for (1) the inventory and (2) the sold items from the Pet Store.
Now, you may use those in the mapping policy to produce an output desired.
For this example, the response payload we’ll be looking for will be (1) the number of sold from the inventory, and (2) the IDs of sold items.
9. Drag and drop a Map Policy to the far right after the 2 Invoke policies from the previous steps.
10. Open up the Map Policy and click on the edit for the INPUT section of the Map.
11. In the INPUT, you will use the response variables set from the Invoke policies previously.
Click on the +input to add the first input to be the Inventory reponse from the Pet Store sample.
12. In the Context variable, input vInventory.body.
Note: The response message body will return within a {body} element in the context variable, therefore the dot notation for body is used.
13. Ensure to detail the rest of the input:
Content Type is set to application/json
Name: Inventory
Definition: Object
Note: the object will change to an “Inline schema” later when we update the property.
14. Follow the same method as above to add the vSold response payload:
Context Variable: vSold.body.id
Note: the .id is used here because we would just like to take the ID of all sold items from the response.
Click Done when complete.
15. Back in the main Map Policy section, add sold as a property within the Inventory json body (as shown in the digram below) to get the sold element from the response.
Note: Using the “add property” function is an easy way to shape the format of the payload you are either defining, or attempting to output.
By adding the “sold” property within the Inventory element as show in the screenshot below, is the same as setting the context variable vInventory.body.sold, which is dot notation traverses the json response payload from the invoke response, to output the sold element.
15. After the INPUT configuration, configure the OUTPUT by clicking on the edit icon on the right of the OUTPUT section of the Map Policy.
As shown in the diagram below, use the message.body Context variable, which outputs the message body from the previous process with the following properties:
Name: Results
Content type: application/json
Definition: object
Note: The Object definition will change to Inline schema once the properties are modified in the main Map Policy screen.
Click Done once complete.
16. Back in the Map policy main panel, add 2 property values (1) TotalSold and (2) ID.
Note: Again, using the “add property” function is an easy way to shape the format of the payload you are either defining, or attempting to output as noted in the previous INPUT instructions.
For this example, the output would look like the following with the properties TotalSold and ID added:
{
"TotalSold": 506,
"IDs": [
362,
1122338409073
]}
Once complete, publish the API into a Product and test:
Artifacts
Here are the API exports:
v2018: https://ibm.box.com/s/9gyavjz9nytbuzmd74bbvyvbj7vih8mw
v5: https://ibm.box.com/s/c1nt38kuumh3kvjvb1g2shh9jf137yht
If for any reason the links stop working, here are the yaml exports.
v2018:
swagger: '2.0'
info:
title: PetStoreAgg
x-ibm-name: petstoreagg
version: 1.0.0
schemes:
- https
basePath: /
securityDefinitions:
clientIdHeader:
type: apiKey
in: header
name: X-IBM-Client-Id
x-ibm-configuration:
cors:
enabled: true
gateway: datapower-api-gateway
type: rest
phase: realized
enforced: true
testable: true
assembly:
execute:
- invoke:
title: 'invoke:Inventory'
version: 2.0.0
verb: keep
target-url: $(target-url)/v2/store/inventory
header-control:
type: blacklist
values: [] parameter-control:
type: blacklist
values: [] output: vInventory
- invoke:
version: 2.0.0
title: 'invoke:vSold'
header-control:
type: blacklist
values: [] parameter-control:
type: whitelist
values: [] timeout: 60
verb: keep
cache-response: protocol
cache-ttl: 900
stop-on-error: [] target-url: $(target-url)/v2/pet/findByStatus?status=sold
output: vSold
- map:
version: 2.0.0
title: map
inputs:
Inventory:
schema:
type: object
properties:
sold:
type: string
name: sold
variable: vInventory.body
content: application/json
Sold:
schema:
type: object
variable: vSold.body.id
content: application/json
outputs:
Results:
schema:
type: object
properties:
TotalSold:
type: string
name: TotalSold
IDs:
type: string
name: IDs
variable: message.body
content: application/json
actions:
- set: Results.TotalSold
from: Inventory.sold
- set: Results.IDs
from: Sold
properties:
target-url:
value: 'https://petstore.swagger.io'
description: The URL of the target service
encoded: false
application-authentication:
certificate: false
catalogs: {}
paths:
/petstoreagg:
get:
responses:
'200':
description: ok
schema:
type: string
consumes: [] produces: [] parameters: []
v5:
swagger: '2.0'
info:
x-ibm-name: pet-store-aggregated
title: Pet Store Aggregated
version: 1.0.0
schemes:
- https
host: $(catalog.host)
basePath: /
consumes:
- application/json
produces:
- application/json
securityDefinitions:
clientIdHeader:
type: apiKey
in: header
name: X-IBM-Client-Id
security:
- {}
x-ibm-configuration:
testable: true
enforced: true
cors:
enabled: true
assembly:
execute:
- invoke:
target-url: $(target-url)/v2/store/inventory
title: 'Invoke: Inventory'
output: vInventory
- invoke:
target-url: $(target-url)/v2/pet/findByStatus?status=sold
title: 'Invoke: Sold'
output: vSold
- map:
title: map
inputs:
Inventory:
schema:
type: object
properties:
sold:
type: string
name: sold
variable: vInventory.body
content: application/json
Sold:
schema:
type: object
variable: vSold.body.id
content: application/json
outputs:
Results:
schema:
type: object
properties:
TotalSold:
type: string
name: TotalSold
ID:
type: string
name: ID
variable: message.body
content: application/json
actions:
- set: Results.TotalSold
from: Inventory.sold
- set: Results.ID
from: Sold
version: 1.0.0
phase: realized
properties:
target-url:
value: 'https://petstore.swagger.io'
description: ''
encoded: false
paths:
/petstoreagg:
get:
responses:
'200':
description: 200 OK
security:
- {}
definitions: {}
tags: []