The Problem of Not Quite Having the API You Need...
Most discussion around APIs tends to focus on the provisioning of proxies for existing services, whether they be internal or cloud or SaaS based, and then managing these APIs. What happens when you have a business requirement for an API but you don't actually have an existing service that you can proxy?
It may be though that you have two or more backend services that you would like to combine into a single API or you might want to combine two or more cloud or SaaS services into a single API or a combination of both.
In the case of internal services it may simply not be expedient to create a brand new service to combine the various internal services and so need an alternative method to create this composite API.
In the case of combining multiple cloud or SaaS services into a single API it doesn't make a whole lot of sense to create a composite service on premise simply to serve this to a cloud based API Management solution. Much better to keep all that in the cloud.
Using the Assembly Capability in IBM API Management
IBM API Management provides both a proxy capability and the ability to create composite APIs using Assemblies. Assemblies provide a number of capabilities beyond the standard proxy:
Create the API and GET Resource
First we need to create the API itself. Log into Cast Iron Web API Management Web API Builder and add a new API, calling it "Get Products and Reviews" with a context of "products". Click "Create".
We will use a single GET resource to call both backend services. On the "Resource Definition" tab add a new GET resource, name it "productAndReviews/{productId}" where the "productId" will be the parameter that we pass into the API. Finally, click "Add" to create the API resource.

Click on the "productAndReviews/{productId}" link to edit this new resource.
Create the Assembly to Aggregate the Backend Services
Now we can move onto creating the actual Assembly. This is done by clicking on the "Implement Resource" tab.
The Assembly editor gives us a great degree of flexibility when it comes to creating APIs. Many of the features were listed earlier in this article. In this case we are going to call two existing services and aggregate their responses into a single response for the API.
The Get Product Service
To add the first service click on the large "plus" icon in the Assembly editor.
This brings up a palette of available targets including databases, salesforce.com and HTTP. In this case both of our backend services are provided by REST/JSON services so select a "GET Operation".
Our first task is to invoke the service to get product details. Change the name of the GET operation to "getProduct" both in the "HTTP GET operation" and in the name of the connection.
Also paste in the URL of the service, which in this case is:
https://rapid.web.castiron.com/catalogue/getProduct/{productID}?appId=5620f855-0104-44ee-8fdc-e33591e8b575
Finally click the "Connect" button. A connection will be made to the service to confirm that it is correct. Assuming this works you will automatically be forwarded to the "Define" tab where we configure the service specific information.
From the resulting popup select Request > Parameters > productId. This is the input parameter for the API resource that we are editing.
Enter the following application Id: 5620f855-0104-44ee-8fdc-e33591e8b575 and click "OK".
We have now configured the product part of the API resource and can now move onto the reviews part.
The Get Product Reviews Service
Click on the "plus" icon again and add another HTTP GET operation.
Change the name of the GET operation to "getProducReviewst" both in the "HTTP GET operation" and in the name of the connection.
Also paste in the URL of the service, which in this case is:
https://rapid.web.castiron.com/catalogue/getProdReviews/{productID}?appId=5620f855-0104-44ee-8fdc-e33591e8b575
Finally click "Connect" to confirm that the backend service is reachable.
Again we need to map the input parameters for this service. Switch to the "Configure" tab.
As before click on "Select Available Value" for for the "productID" parameter and select Request > Parameters > productId from the popup.
To map the "appId" parameter click on the icon at the end of the parameter's row, enter 5620f855-0104-44ee-8fdc-e33591e8b575 and click "OK".
Map the Services Output Messages to the API Output Message
We have now completed the configuration required to call the two backend services. Now all that remains is to map the responses from the two backend services to the API resource response message. Click on "Response" to edit the required map.
This displays the mapping editor. On the left side you have all of the fields from the output messages of the two backend services that we have configured. On the right side we have the fields from the sample output message of our API resource.

Switch to the "Test" tab and select "GET productAndReviews{productId}" and the "Test Application" from the pulldowns.
Enter 4900133522843 as the "productId".
Click the "Test" button.
Assuming everything has been configured correctly you will see a valid response showing the combined product detail and reviews in a single response message!
Summary and Discussion
In this example we have shown the flexibility of using IBM API Management to go beyond simple proxying of backend services and instead create a new API aggregating two services.
This facility to call multiple services provides a highly flexible mechanism for integrating a number of disparate services from within and outside of the enterprise. It is also changeable over time. Services can be modified, removed, added and the order in which they are invoked can be changed as well. The mapping facility also allows us to use the output messages of previously invoked services in calling later services.
Another possibility is to use other APIs that you have created as source "services" in an Assembly, allowing you to combine your existing APIs with other services and APIs to create new and innovative APIs without necessarily needing to go back and change the existing APIs, which may affect existing consumers of those APIs.
The Assembly mechanism in IBM API Management provides a very high level of flexibility that allows the API author to create innovative APIs from existing services and APIs without needing to rely on other integration technologies and means they can define new APIs quickly to respond to business and customer needs.
Most discussion around APIs tends to focus on the provisioning of proxies for existing services, whether they be internal or cloud or SaaS based, and then managing these APIs. What happens when you have a business requirement for an API but you don't actually have an existing service that you can proxy?
It may be though that you have two or more backend services that you would like to combine into a single API or you might want to combine two or more cloud or SaaS services into a single API or a combination of both.
In the case of internal services it may simply not be expedient to create a brand new service to combine the various internal services and so need an alternative method to create this composite API.
In the case of combining multiple cloud or SaaS services into a single API it doesn't make a whole lot of sense to create a composite service on premise simply to serve this to a cloud based API Management solution. Much better to keep all that in the cloud.
Using the Assembly Capability in IBM API Management
IBM API Management provides both a proxy capability and the ability to create composite APIs using Assemblies. Assemblies provide a number of capabilities beyond the standard proxy:
- Combine multiple services into a single API.
- Map an existing service to a different message structure. This may be desirable when the existing service is complex and we'd like to simplify it without having to create a brand new service to proxy. Secondly we can always extend it later.
- Perform more complex mapping and format translation to make the API more useful to consumers.
- Call into SaaS offerings like Salesforce.
- Connect directly to internal resources like databases.
- Convert an XML based service into an API using JSON and vice versa.
Create an API Combining Two Existing Services
In this example we will create an example composite API using IBM API Management Assemblies.
We currently have two services:
- Get product details.
- Get product reviews.
Create the API and GET Resource
First we need to create the API itself. Log into Cast Iron Web API Management Web API Builder and add a new API, calling it "Get Products and Reviews" with a context of "products". Click "Create".
Click on the "Get Products and Reviews" link to edit the API. This will allow us to create the GET resource that we will use to build the API assembly.
We will use a single GET resource to call both backend services. On the "Resource Definition" tab add a new GET resource, name it "productAndReviews/{productId}" where the "productId" will be the parameter that we pass into the API. Finally, click "Add" to create the API resource.

Click on the "productAndReviews/{productId}" link to edit this new resource.
If we were simply doing a proxy API then we would select the "Proxy" checkbox but in this case we need to call multiple backend services and so a proxy is not appropriate. We will instead use the Assembly capability to create the API resource.
First we need to paste in a sample response message. This works as documentation for developers but also provides the mapping target inside the Assembly. We can paste in the following response JSON message into the "Response Body":
{
"product": {
"basePrice": 27.89,
"description": "A delicious biscuity aroma complemented with subtle wood and barrel ageing before bottling",
"imageURL": "http://images.gigamarkets.com/images/fullsize/4900133522843.jpg",
"measure": "750ml",
"name": "Bison Grove Blancs de Noirs NV",
"catID": "1077",
"productCategory": "Wines and Spirits",
"productID": "4900133522843",
"thumbnailURL": "http://images.gigamarkets.com/images/thumbnail/4900133522843.jpg"
},
"reviews": [
{
"productID": "4900133522843",
"review": "A fantastic wine. Goes surprisingly well with beef.",
"reviewDate": "2013-01-09T11:39:38Z",
"starRating": 5,
"username": "pavsmith",
"reviewID": "1358070591609"
},
{
"productID": "4900133522843",
"review": "Great value. Shows you that you can actually make wine out of Pinot Noir.",
"reviewDate": "2012-12-24T13:45:33Z",
"starRating": 4,
"username": "leandag",
"reviewID": "1358070591621"
}
]
}
Create the Assembly to Aggregate the Backend Services
Now we can move onto creating the actual Assembly. This is done by clicking on the "Implement Resource" tab.
The Assembly editor gives us a great degree of flexibility when it comes to creating APIs. Many of the features were listed earlier in this article. In this case we are going to call two existing services and aggregate their responses into a single response for the API.
The Get Product Service
To add the first service click on the large "plus" icon in the Assembly editor.
This brings up a palette of available targets including databases, salesforce.com and HTTP. In this case both of our backend services are provided by REST/JSON services so select a "GET Operation".
Our first task is to invoke the service to get product details. Change the name of the GET operation to "getProduct" both in the "HTTP GET operation" and in the name of the connection.
Also paste in the URL of the service, which in this case is:
https://rapid.web.castiron.com/catalogue/getProduct/{productID}?appId=5620f855-0104-44ee-8fdc-e33591e8b575
Finally click the "Connect" button. A connection will be made to the service to confirm that it is correct. Assuming this works you will automatically be forwarded to the "Define" tab where we configure the service specific information.
Give a useful description to both the "productID" and "appId" and then paste in a sample response message from the backend service into the "Response Body" section. Again this is partially for documentation purposes but it also provides the mapping source for when we aggregate the service responses later.
{
"basePrice": 34.12,
"catID": "1077",
"description": "A classic year with rich fruit underpinned by strong tannins and structure. Will last for decades!",
"imageURL": "http://images.gigamarkets.com/images/fullsize/4900133555764.jpg",
"measure": "750ml",
"name": "Big Penguins Reserve Shriaz 2007",
"productCategory": "Wines and Spirits",
"productID": "4900133555764",
"thumbnailURL": "http://images.gigamarkets.com/images/thumbnail/4900133555764.jpg"
}
We can now map the input parameters for this backend service. Click on the "Configure" tab. This allows us to define the content of the parameters required to call the service. In this case we need to provide a "productID" and an "appId". The product Id we will get from the input message for the API and the application Id is a hardcoded value.
To map the product Id click on "Select Available Value" next to "productID".
From the resulting popup select Request > Parameters > productId. This is the input parameter for the API resource that we are editing.
To enter the hardcoded application Id click on the icon at the far end of the "appId" row.
Enter the following application Id: 5620f855-0104-44ee-8fdc-e33591e8b575 and click "OK".
The icon will change to green to indicate that a value has been provided for that parameter.
We have now configured the product part of the API resource and can now move onto the reviews part.
The Get Product Reviews Service
Click on the "plus" icon again and add another HTTP GET operation.
Change the name of the GET operation to "getProducReviewst" both in the "HTTP GET operation" and in the name of the connection.
Also paste in the URL of the service, which in this case is:
https://rapid.web.castiron.com/catalogue/getProdReviews/{productID}?appId=5620f855-0104-44ee-8fdc-e33591e8b575
Finally click "Connect" to confirm that the backend service is reachable.
Again assuming the service is configured correctly you will automatically be moved to the "Define" tab. Add useful descriptions to the two parameters and paste a sample response into the "Response Body".
{
"reviews": [
{
"productID": "4900133522843",
"review": "A fantastic wine. Goes surprisingly well with beef.",
"reviewDate": "2013-01-09T11:39:38Z",
"starRating": 5,
"username": "pavsmith",
"reviewID": "1358070591609"
},
{
"productID": "4900133522843",
"review": "Great value. Shows you that you can actually make wine out of Pinot Noir.",
"reviewDate": "2012-12-24T13:45:33Z",
"starRating": 4,
"username": "leandag",
"reviewID": "1358070591621"
}
]
}
Again we need to map the input parameters for this service. Switch to the "Configure" tab.
As before click on "Select Available Value" for for the "productID" parameter and select Request > Parameters > productId from the popup.
To map the "appId" parameter click on the icon at the end of the parameter's row, enter 5620f855-0104-44ee-8fdc-e33591e8b575 and click "OK".
Map the Services Output Messages to the API Output Message
We have now completed the configuration required to call the two backend services. Now all that remains is to map the responses from the two backend services to the API resource response message. Click on "Response" to edit the required map.
Again we could use the same mapping facility of selecting available values that we used to map the input parameters above, but in this case we will be mapping a lot more fields and so we will switch to the drag and drop editor. Click on "Map Values".
This displays the mapping editor. On the left side you have all of the fields from the output messages of the two backend services that we have configured. On the right side we have the fields from the sample output message of our API resource.
Mapping is a simple act of dragging and dropping the relevant fields from the input to the output. In this case we are simply mapping fields directly and require no transformation. If you click on the "plus" icon on any of the wires you will see all of the potential transformation options that are available to you.
Once you have finished mapping all of the fields you have completed the configuration of our assembly!
Create an API Entitlement
The last thing we need to do before testing our new API is to define an Entitlement for the API. Click on the "Entitlements" tab.
Add a new entitlement called "Basic" with a maximum of 50 calls/minute, leaving all other options as default and click "Add".
Test the API
The API is now ready for testing. We now have to start the API resource. Return to the "Resource Definition" tab and click the "activate" icon next to your API resource and wait for the resource to activate.

Switch to the "Test" tab and select "GET productAndReviews{productId}" and the "Test Application" from the pulldowns.
Enter 4900133522843 as the "productId".
Click the "Test" button.
Assuming everything has been configured correctly you will see a valid response showing the combined product detail and reviews in a single response message!
In this example we have shown the flexibility of using IBM API Management to go beyond simple proxying of backend services and instead create a new API aggregating two services.
This facility to call multiple services provides a highly flexible mechanism for integrating a number of disparate services from within and outside of the enterprise. It is also changeable over time. Services can be modified, removed, added and the order in which they are invoked can be changed as well. The mapping facility also allows us to use the output messages of previously invoked services in calling later services.
Another possibility is to use other APIs that you have created as source "services" in an Assembly, allowing you to combine your existing APIs with other services and APIs to create new and innovative APIs without necessarily needing to go back and change the existing APIs, which may affect existing consumers of those APIs.
The Assembly mechanism in IBM API Management provides a very high level of flexibility that allows the API author to create innovative APIs from existing services and APIs without needing to rely on other integration technologies and means they can define new APIs quickly to respond to business and customer needs.






































