- IBM Business Process Manager
- IBM Operational Decision Manager (Rules)
- IBM API Connect
- IBM WebSphere Liberty Profile (Collectives)
- IBM DataPower Gateway
leverages Representational State Transfer (REST) APIs, so I've got no excuse but to L-E-A-R-N.
Whilst working through the DataPower tutorial here: -
I needed to get a handle on how to drive REST, both in the context of the IDG administration tools, which have a pretty RESTful set of APIs: -
I thus enabled the REST Management service: -
configure; rest-mgmt; admin-state enabled; exit; exit;
Whilst the tutorial recommends the use of the HTTPie tool, I prefer to use curl which is baked into macOS, and doesn't require tools such as brew or port.
So here's my crib of some of the IDG REST APIs, via curl : -
Summary of the Management APIs
Summary of the Status Indicators
List available domains
Check the CPU usage
As you can imagine, this is a TINY example of the power of the REST APIs.
Then I moved onto the next phase of the tutorial, where we are creating a Multi-Protocol Gateway to "proxy" REST calls through the IDG to IBM Bluemix, using a sample service for Pokemon.
The service is available on Bluemix here: -
and, when poked with a browser, which issues a GET request, simply returns a list of Pokemons in JSON format.
Initially, I tickled the same URL using a REST client plugin called Restlet which sits nicely inside Google Chrome.
Hitting the same URL with a GET request gives me the same list of Pokemon, albeit in a nice UI: -
As part of the tutorial, I needed to add a new Pokemon to the list, using the POST method.
Whilst I could use Restlet for this, I wanted to use curl, so I tested the GET request: -
curl --request GET --url https://pokemons.mybluemix.net/api/pokemons
[{"data":{"moves":"fast"},"height":"34","name":"charmeleon","weight":432,"id":"2"},{"data":{"moves":"very fast"},"height":"90","name":"venusaur","weight":80,"id":"3"},{"data":{"moves":"slow"},"height":"70","name":"ivysaur","weight":200,"id":"1"},{"data":{"moves":"fast"},"height":"50","name":"bulbasuar","weight":100,"id":"4"},{"data":{"moves":"slow"},"height":"70","name":"charmander","weight":122,"id":"9ed78062996515b4db7e1b78d73208b0"}]
I then added a new Pokemon: -
curl --request POST --url https://pokemons.mybluemix.net/api/pokemons --header 'accept: application/json' --header 'content-type: application/json' --data '{"data":{"moves":"slow"},"height":"70","name":"ivysaur","weight":200,"id":"6"}'
{"data":{"moves":"slow"},"height":"70","name":"ivysaur","weight":200,"id":"6"}
and retrieved the updated list: -
[{"data":{"moves":"fast"},"height":"34","name":"charmeleon","weight":432,"id":"2"},{"data":{"moves":"very fast"},"height":"90","name":"venusaur","weight":80,"id":"3"},{"data":{"moves":"slow"},"height":"70","name":"ivysaur","weight":200,"id":"1"},{"data":{"moves":"fast"},"height":"50","name":"bulbasuar","weight":100,"id":"4"},{"data":{"moves":"slow"},"height":"70","name":"ivysaur","weight":200,"id":"6"},{"data":{"moves":"slow"},"height":"70","name":"charmander","weight":122,"id":"9ed78062996515b4db7e1b78d73208b0"}]
When I (perhaps stupidly) re-ran the POST request with the SAME data, I got this: -
When I (perhaps stupidly) re-ran the POST request with the SAME data, I got this: -
curl --request POST --url https://pokemons.mybluemix.net/api/pokemons --header 'accept: application/json' --header 'content-type: application/json' --data '{"data":{"moves":"slow"},"height":"70","name":"ivysaur","weight":200,"id":"6"}'
{"error":{"name":"Error","status":409,"message":"Document update conflict. (duplicate?)","error":"conflict","reason":"Document update conflict.","scope":"couch","statusCode":409,"request":{"method":"POST","headers":{"content-type":"application/json","accept":"application/json"},"uri":"https://XXXXXX:XXXXXX@757241f7-e17e-4fc1-b206-91919dd9ced5-bluemix.cloudant.com/pokemon_db","body":"{\"data\":{\"moves\":\"slow\"},\"height\":\"70\",\"name\":\"ivysaur\",\"weight\":200,\"_id\":\"6\",\"loopback__model__name\":\"pokemon\"}"},"headers":{"cache-control":"must-revalidate","content-type":"application/json","date":"Tue, 15 Aug 2017 15:36:22 GMT","x-couch-request-id":"e7ffd29868","x-content-type-options":"nosniff","x-cloudant-backend":"bm-dal-standard3","via":"1.1 lb1.bm-dal-standard3 (Glum/1.37.0)","strict-transport-security":"max-age=31536000","statusCode":409,"uri":"https://XXXXXX:XXXXXX@757241f7-e17e-4fc1-b206-91919dd9ced5-bluemix.cloudant.com/pokemon_db"},"errid":"non_200","description":"couch returned 409"}}
which kinda makes sense.
To prove this, I used the DELETE method: -
{"count":1}
retrieved the now updated list: -
curl --request GET --url https://pokemons.mybluemix.net/api/pokemons
[{"data":{"moves":"fast"},"height":"34","name":"charmeleon","weight":432,"id":"2"},{"data":{"moves":"very fast"},"height":"90","name":"venusaur","weight":80,"id":"3"},{"data":{"moves":"slow"},"height":"70","name":"ivysaur","weight":200,"id":"1"},{"data":{"moves":"fast"},"height":"50","name":"bulbasuar","weight":100,"id":"4"},{"data":{"moves":"slow"},"height":"70","name":"charmander","weight":122,"id":"9ed78062996515b4db7e1b78d73208b0"}]
and then reinserted ID 6: -
curl --request POST --url https://pokemons.mybluemix.net/api/pokemons --header 'accept: application/json' --header 'content-type: application/json' --data '{"data":{"moves":"slow"},"height":"70","name":"ivysaur","weight":200,"id":"6"}'
{"data":{"moves":"slow"},"height":"70","name":"ivysaur","weight":200,"id":"6"}
and (finally) retrieved the now updated list: -
curl --request GET --url https://pokemons.mybluemix.net/api/pokemons
[{"data":{"moves":"fast"},"height":"34","name":"charmeleon","weight":432,"id":"2"},{"data":{"moves":"very fast"},"height":"90","name":"venusaur","weight":80,"id":"3"},{"data":{"moves":"slow"},"height":"70","name":"ivysaur","weight":200,"id":"1"},{"data":{"moves":"fast"},"height":"50","name":"bulbasuar","weight":100,"id":"4"},{"data":{"moves":"slow"},"height":"70","name":"ivysaur","weight":200,"id":"6"},{"data":{"moves":"slow"},"height":"70","name":"charmander","weight":122,"id":"9ed78062996515b4db7e1b78d73208b0"}]
All of this is of use, because it's enabled me to get a better handle on how I can drive REST from a browser, from a plugin ( Restlet in my case ) and from the command-line, using curl.
Which is all nice.
For the record, here's how I test an API deployed to IBM API Connect: -
curl -k --request POST \
--url https://apimdev2019.hursley.ibm.com/daves-org/sb/DecisionService/rest/HelloWorldProject/1.0/HelloWorld \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '{"request":"David M M Hay"}'
--url https://apimdev2019.hursley.ibm.com/daves-org/sb/DecisionService/rest/HelloWorldProject/1.0/HelloWorld \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '{"request":"David M M Hay"}'
4 comments:
A useful post for those of us not quite entirely comfortable with REST and all it implies. Thanks!
Hey Ben
Thanks for the kind comments. Yeah, there is always so much to learn, which keeps us young/busy/tired :-)
Cheers, Dave
Another good and popular client is PostMan https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop
Keith
Good point, it's not one that I've made much use of it, thus far, but it's on the to-do list, along with a myriad of other things :-)
Thanks for your feedback, Dave
Post a Comment