Thursday, March 21, 2013

No API? No problem!

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:
  • 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.
All of these capabilities are provided as standard function within IBM API Management and allow for very flexible creation of APIs from a variety of sources and gives you a great degree of flexibility when you don't quite have the API that you need to expose.

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.
We have a requirement from one of our customers to provide an API that combines the product detail with the reviews into a single response from a single request. Out IT department doesn't have the time to create the new service at the moment so we instead will use IBM API Management to perform the task.

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!


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.

Saturday, March 2, 2013

Create a Basic Proxy API

This post looks at the creation of a basic proxy API. It is the simplest kind of API where we simply proxy an existing service. The key reason that we want to do this is that we can use API management to register, track and control apps and app developers and the use of our API resources. A simple proxy API will be the most common use of APIs typically.

The Source REST Service

For the purposes of this test we will select a publicly available service that requires no additional registration or use of application keys. In this case we are going to use one of the public APIs provided by the BBC to get information about various programmes and schedules. The API is documented here:

BBC Programme Developers Page

It provides a set of information about schedules, genres and individual programmes. We will use this to get upcoming episodes of a particular programme.


Schedules

            /:service/programmes/schedules{/:outlet}
            /:service/programmes/schedules{/:outlet}/:year/:month/:day
            /:service/programmes/schedules{/:outlet}/:year/:month/:day/ataglance
            /:service/programmes/schedules{/:outlet}/yesterday
            /:service/programmes/schedules{/:outlet}/today
            /:service/programmes/schedules{/:outlet}/tomorrow
        

Genres

            {/:service}/programmes/genres/:genre1{/:genre2{/:genre3}}/schedules
            {/:service}/programmes/genres/:genre1{/:genre2{/:genre3}}/schedules/:year/:month/:day
            {/:service}/programmes/genres/:genre1{/:genre2{/:genre3}}/schedules/:year/:month/:day/ataglance
            {/:service}/programmes/genres/:genre1{/:genre2{/:genre3}}/schedules/upcoming
        

Programmes

            /programmes/:groupPID/episodes/upcoming
            /programmes/:groupPID/episodes/upcoming/debut
            /programmes/:groupPID/episodes/player


The API follows exactly the same URL model as the BBC website. So, if we want to look at upcoming episodes of Saturday Kitchen we simply need to use a browser to get to the programme's website. The programme's id is contained within the link.


To help our eventual app developers we need to get some sample JSON output from the REST service. To do this we simply use the "upcoming" method. We can paste the following link into a browser.

http://www.bbc.co.uk/programmes/b006v5y2/episodes/upcoming.json

Copy and paste the output message into a text editor as we will need it soon when we create the API.



Create and Test the API

We can now create our API. Log into the Cast Iron Web API Builder at:

https://webapi.castiron.com/webapibuilder

Create a new API called "BBC Programmes API", give it a context of "bbcProgrammes", add a description and click "Create".


Click on the "BBC Programmes API" link to edit the API.


Add a "GET" resource with a URI of: programmes/{programmeId}/episodes/upcoming.json


Click on the link to edit the API resource.


Select the "Proxy" checkbox and enter the following address for the proxy:

http://www.bbc.co.uk/programmes/

Note that API Management will match the URI up to "/programmes/" and append the remainder of the URI from the API resource.


Paste in the sample JSON response that you saved earlier. Note that when you paste in the message the JSON will be formatted assuming the JSON is valid. If it is invalid the JSON will not format nicely and the response body section will be shaded red to indicate the error.

 

The basic API is now complete but we need to do one more thing before we can test. We need to add at least one entitlement to the API. Return to the main API page and click on the "Entitlements" tab.
Add an entitlement called "Basic Entitlement" and give it a description and a number of calls per minute and click "Add".


The API is mow complete and we can test it. Return to the "Resource Definition" tab and activate the resource by clicking on the Activate icon. Click "OK" once the resource activates successfully.

 

Click on the "Test" tab, select the GET resource and the "Test Application". Paste the programme id into the "programmeId" parameter and then click "Test".


After a moment you should see a successful response from the service.

 

That completes the creation of a basic proxy API.

Tuesday, February 5, 2013

Register for a free 90 day trial of IBM API Management

IBM offers a free 90 trial of the Cast Iron Web API Management solution. You can register and try the solution at:

https://webapi.castiron.com/webapibuilder/

Click on the "Try It Free" button, read the Terms of Use and register.


You then have full access to the solution for 90 days and allows up to 1 million API interactions during that time.

You can upgrade to the full version of the solution at any time by selecting the "Upgrade" option from the menu within the Web API Builder.

Sunday, February 3, 2013

Using IBM API Management and IBM Business Process Manager Together

IBM API Management and IBM Business Process Manager

IBM Business Process Manager provides a very comprehensive selection of REST interfaces which can be exposed outside of the enterprise boundary using IBM API Management. These REST interfaces can be used to query, start, participate in and modify processes, tasks and other BPM information. In this article I will look at how to take the most basic requirement - starting a business process - and creating an API.

Why Expose BPM as APIs?

IBM API Management provides a facility to expose existing business function within your enterprise to exploit opportunities and grow your business in new markets, channels and developer communities that you might not have previously had access to. It also allows you to manage and monitor that community of developers and the applications that they create.

It may be that some of your business processes are ideal candidates for these developers to use within their applications but where they are not forced to explicitly log into and use the backend BPM servers. In this instance we are showing how an existing business process can be easily turned into an API which would allow a developer a simple way to start a process using their own preferred tools and technologies.

It would also be useful in cases where you might wish to expose the progress of long running business processes to partners, customers and so on so that they can do self service monitoring.

Assumptions

This post assumines that you're familiar with IBM BPM and how to use it, that you've registered for IBM API Management and that you have a BPM server that is accessible from the cloud based API Management servers.

Find a Process and Its Input Message

We need to start by finding the details of the process that we wish to invoke. In particular we need to know the structure of the input message as we will use the BPM REST Tester to find the IDs for the BPD and Process later.

Open your Process Designer and open the business process that you wish to use and find the input variable. You'll need to be able to provide a JSON representation of the message to use with the API.


Discover the REST Interface to a Process

To be able to invoke the BPM process we need to find the BPD and Process ID's. IBM BPM provides a highly useful REST API Tester which can be accessed at:

http://<hostname>:<port>/bpmrest-ui/BPMRestAPITester/index.jsp

This is an invaluable resource for using REST to interact with IBM BPM and all standard interfaces are provided here. In our case we are simply going to find the exposed processes and then the interface to start our process.

Open the "Process API" folder and select "Exposed Processes" and then click the "Execute" button.


This brings back a list of all BPM processes that have been exposed so that they can be invoked externally. You need the "itemID" and "processAppID".


Now select the "Start Process" API in the REST API Tester.



Copy the "itemID" into "BPD ID" and "processAppID" into "Process Application ID". Finally add a JSON representation of the process input message to "Parameters" and click "Execute".


When the call returns you will see detailed information about the call to start the process and the current state of the process. For the next step however you need to copy the request URI into a text editor.


 Define Your API

We now have all the information that we need to create our API using IBM API Management. Log into the IBM API Management WebAPI Builder at:

https://webapi.castiron.com/webapibuilder

Create a new API definition. A single API can have multiple resources, at this point we are simply creating the top level of the API. Add a name of the API, a context path and a description and click "Add".


Click on the newly created API definition to edit the API.

 

Each API requires at least one Entitlement. This specifies a policy for the number of times that a consumer can invoke a given API per minute. It also can use used to require approval before an API can be used and whether an application secret code is required to invoke the API.

Click on the "Entitlements" tab and create a sample entitlement.


Return to the "Resource Definition" tab.

The "Start Process" REST API uses a POST method. The URI for the resource needs to match the parameters for the BPM REST call.

 process?action=start&bpdId=bid&processAppId=pid&params=prms&parts=all

This means you can simplify or change the path of the API from the original URI up until you hit the first parameter. After that you need to keep your URI path the same as in the original service.

Click "Add" to create the new resource.


Click on the link for the new resource to edit it.

 

We can create a simple proxy to invoke the BPM process. Select the "Proxy" checkbox.

Enter the address of the BPM REST URL but only to the point of the first parameter. IBM API Management appends the parameters to this URL when invoking the API resource.

http://<hostname>:<port>/rest/bpm/wle/v1/process

 

Add descriptions for the 5 parameters. 


In the "Request Headers" section add an "Authorization" header as we will need to be able to pass user credentials into BPM to invoke the process. 


Return to the main API page and click the "Activate" icon. 

Test the API

Move to the "Test" tab and select the POST resource from the pulldown and the "Test Application".

  • action: start
  • bpdId: paste in the BPD ID from earlier
  • processAppId: paste in the Process Application ID from earlier.
  • params: paste in the text of the parameters from the output of the REST API tester
  • parts: all
Paste a basic authorisation header into the "Authorisation" header (if you don't know how to create a basic authorisation header there are instructions for one way of doing it at the bottom of this page).

Finally click "Test".


You will see that the process has been successfully invoked.


In the Response Body you can see detailed information about the process invocation and its current state.


Congratulations! You've created an API to invoke an IBM BPM process using IBM API Management!


Generating a Basic Authorisation Header

If you don't already have a to to create a basic authorisation header you can use a tool like "REST Console" in Chrome to create one for you.

Open REST Console, find the "Authorisation" section and click "Basic Auth".



Enter your username and password and click "Set Header".


This then creates a basic authorisation header. This can be copied and pasted (including the word "Basic" at the start) into the IBM API Management tester.