Overview

Skill Level: Any Skill Level

This sample showcases how to build out an API that calls 2 different endpoints from the Pet Store sample on the Swagger.io site: https://petstore.swagger.io/#/store/getInventory

Ingredients

  • Access to API Connect: API Manager.

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.

Step-by-step

  1. 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 ‘/’¬†

    basePath

    3. Disable the security for the API

    security

    4. Create the path: name the path for your client app to invoke, such as /petstoreagg, and add a GET operation.

    path

    5. Navigate to the Properties section and update or add target-url to use http://petstore.swagger.io 

    properties

    6. Save the API.

  2. 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.

    newAPI

    2. Name the API, remove the base path to root ‘/’, and click Next.

    basePath_v2018

    3. Disable the security for the API and click Next.

     securityRemove_v2018

    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.

     createPetStoreAgg

    5. Navigate to the Properties section and update or add target-url to use http://petstore.swagger.io  and save the Property.

     properties_v2018

    6. Save the API.

  3. 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.

     Invoke_Inventory

     

    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.

    invoke_sold

    Note: The original source is as follows: https://petstore.swagger.io/v2/pet/findByStatus?status=sold  

     

     

     

  4. 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.

    map_v2018

    10. Open up the Map Policy and click on the edit for the INPUT section of the Map.

    mapInput_v2018

    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.

     

    mapInputs_v2018

     

    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.

    mapOutput_v2018

    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.¬†

    mapOUTPUT.properties_v2018

    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:

    invoke_v2018

     

     

     

  5. 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: []

     

     

     

Join The Discussion