September 29, 2019
We will be creating APIs and subscribing and consuming them using RESTful APIs which are exposed by the WSO2 API Manager (2.6) platform.
The RESTful APIs of API Manager gives an extended platform to the end-users and developers to create APIs, create an application and to subscribe to them using REST clients without touching any UIs of API Manager. This simply makes life easier when creating hundreds of APIs and testing the platform.
In this demo, we will be covering and performing the following subjects …
You can find more details on exposed APIs and Docs here. We will be using API Docs of API Manager v2.6. Also please find the Postman collection used for this demo at the end of this article
Before executing any of the REST API, we have to invoke the dynamic client registration endpoint and want to get an Access Token to further continue and use the exposed APIs.
Download and start the WSO2 API Manager by directing to <APIM>/bin folder and executing the following
# linux envfoo@bar:~$ sh wso2server.sh# windows envwso2server.bat
After a successful startup, use the following endpoint reference to register a dynamic client
POST: https://localhost:9443/client-registration/v0.14/registerAuthorization: Basic <Base64(admin:admin)>Content-Type: application/json{"callbackUrl": "localhost","clientName": "rest_api_demo","owner": "admin","grantType": "password refresh_token","saasApp": true}
curl command
curl -X POST \https://localhost:9443/client-registration/v0.14/register \-H 'Authorization: Basic YWRtaW46YWRtaW4=' \-H 'Content-Type: application/json' \-d '{"callbackUrl": "localhost","clientName": "rest_api_demo","owner": "admin","grantType": "password refresh_token","saasApp": true}'
Markdown the clientId and clientSecret values from the response to generate an access token using the token endpoint.
Execute the following endpoint reference to generate an access token using the obtained clientId and clientSecret values.
POST: https://localhost:8243/tokenAuthorization: Basic <Base64(ClientID:ClientSecret)>Content-Type: application/x-www-form-urlencodedgrant_type=passwordusername=adminpassword=adminscope=apim:api_view apim:api_create apim:api_publish apim:subscribe
curl command
curl -X POST \https://localhost:8243/token \-H 'Authorization: Basic <Base64(ClientID:ClientSecret)>' \-H 'Content-Type: application/x-www-form-urlencoded' \-d 'grant_type=password&username=admin&password=admin&scope=apim%3Aapi_view%20apim%3Aapi_create%20apim%3Aapi_publish%20apim%3Asubscribe'
Now we have successfully generated an access token to use with our Store and Publisher REST APIs. Copy the generated access token from the response and keep it for future executions.
We will be using the exact request as defined here to create a test API for our demo. Our demo API will be the default shipped PizzaShackAPI. Please find the request endpoint reference below
POST: https://localhost:9443/api/am/publisher/v0.14/apisAuthorization: Bearer <Access Token>Content-Type: application/json{"name": "PizzaShackAPI","description": "This document describe a RESTFul API for Pizza Shack online pizza delivery store.\r\n","context": "/pizzashack","version": "1.0.0","provider": "admin","apiDefinition": "{\"paths\":{\"/order\":{\"post\":{\"x-auth-type\":\"Application & Application User\",\"x-throttling-tier\":\"Unlimited\",\"description\":\"Create a new Order\",\"parameters\":[{\"schema\":{\"$ref\":\"#/definitions/Order\"},\"description\":\"Order object that needs to be added\",\"name\":\"body\",\"required\":true,\"in\":\"body\"}],\"responses\":{\"201\":{\"headers\":{\"Location\":{\"description\":\"The URL of the newly created resource.\",\"type\":\"string\"}},\"schema\":{\"$ref\":\"#/definitions/Order\"},\"description\":\"Created.\"}}}},\"/menu\":{\"get\":{\"x-auth-type\":\"Application & Application User\",\"x-throttling-tier\":\"Unlimited\",\"description\":\"Return a list of available menu items\",\"parameters\":[],\"responses\":{\"200\":{\"headers\":{},\"schema\":{\"title\":\"Menu\",\"properties\":{\"list\":{\"items\":{\"$ref\":\"#/definitions/MenuItem\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"OK.\"}}}}},\"schemes\":[\"https\"],\"produces\":[\"application/json\"],\"swagger\":\"2.0\",\"definitions\":{\"MenuItem\":{\"title\":\"Pizza menu Item\",\"properties\":{\"price\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"},\"image\":{\"type\":\"string\"}},\"required\":[\"name\"]},\"Order\":{\"title\":\"Pizza Order\",\"properties\":{\"customerName\":{\"type\":\"string\"},\"delivered\":{\"type\":\"boolean\"},\"address\":{\"type\":\"string\"},\"pizzaType\":{\"type\":\"string\"},\"creditCardNumber\":{\"type\":\"string\"},\"quantity\":{\"type\":\"number\"},\"orderId\":{\"type\":\"string\"}},\"required\":[\"orderId\"]}},\"consumes\":[\"application/json\"],\"info\":{\"title\":\"PizzaShackAPI\",\"description\":\"This document describe a RESTFul API for Pizza Shack online pizza delivery store.\\n\",\"license\":{\"name\":\"Apache 2.0\",\"url\":\"http://www.apache.org/licenses/LICENSE-2.0.html\"},\"contact\":{\"email\":\"architecture@pizzashack.com\",\"name\":\"John Doe\",\"url\":\"http://www.pizzashack.com\"},\"version\":\"1.0.0\"}}","wsdlUri": null,"status": "CREATED","responseCaching": "Disabled","cacheTimeout": 300,"destinationStatsEnabled": false,"isDefaultVersion": false,"type": "HTTP","transport":["http","https"],"tags": ["pizza"],"tiers": ["Unlimited"],"maxTps":{"sandbox": 5000,"production": 1000},"visibility": "PUBLIC","visibleRoles": [],"endpointConfig": "{\"production_endpoints\":{\"url\":\"https://localhost:9443/am/sample/pizzashack/v1/api/\",\"config\":null},\"sandbox_endpoints\":{\"url\":\"https://localhost:9443/am/sample/pizzashack/v1/api/\",\"config\":null},\"endpoint_type\":\"http\"}","endpointSecurity":{"username": "user","type": "basic","password": "pass"},"gatewayEnvironments": "Production and Sandbox","sequences":[{"name":"json_validator","type": "in"},{"name":"log_out_message","type": "out"}],"subscriptionAvailability": null,"subscriptionAvailableTenants": [],"businessInformation":{"businessOwnerEmail": "marketing@pizzashack.com","technicalOwnerEmail": "architecture@pizzashack.com","technicalOwner": "John Doe","businessOwner": "Jane Roe"},"corsConfiguration":{"accessControlAllowOrigins": ["*"],"accessControlAllowHeaders":["authorization","Access-Control-Allow-Origin","Content-Type","SOAPAction"],"accessControlAllowMethods":["GET","PUT","POST","DELETE","PATCH","OPTIONS"],"accessControlAllowCredentials": false,"corsConfigurationEnabled": false}}
curl command
curl -X POST \https://localhost:9443/api/am/publisher/v0.14/apis \-H 'Authorization: Bearer <Access Token>' \-H 'Content-Type: application/json' \-d '{"name": "PizzaShackAPI","description": "This document describe a RESTFul API for Pizza Shack online pizza delivery store.\r\n","context": "/pizzashack","version": "1.0.0","provider": "admin","apiDefinition": "{\"paths\":{\"/order\":{\"post\":{\"x-auth-type\":\"Application & Application User\",\"x-throttling-tier\":\"Unlimited\",\"description\":\"Create a new Order\",\"parameters\":[{\"schema\":{\"$ref\":\"#/definitions/Order\"},\"description\":\"Order object that needs to be added\",\"name\":\"body\",\"required\":true,\"in\":\"body\"}],\"responses\":{\"201\":{\"headers\":{\"Location\":{\"description\":\"The URL of the newly created resource.\",\"type\":\"string\"}},\"schema\":{\"$ref\":\"#/definitions/Order\"},\"description\":\"Created.\"}}}},\"/menu\":{\"get\":{\"x-auth-type\":\"Application & Application User\",\"x-throttling-tier\":\"Unlimited\",\"description\":\"Return a list of available menu items\",\"parameters\":[],\"responses\":{\"200\":{\"headers\":{},\"schema\":{\"title\":\"Menu\",\"properties\":{\"list\":{\"items\":{\"$ref\":\"#/definitions/MenuItem\"},\"type\":\"array\"}},\"type\":\"object\"},\"description\":\"OK.\"}}}}},\"schemes\":[\"https\"],\"produces\":[\"application/json\"],\"swagger\":\"2.0\",\"definitions\":{\"MenuItem\":{\"title\":\"Pizza menu Item\",\"properties\":{\"price\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"},\"image\":{\"type\":\"string\"}},\"required\":[\"name\"]},\"Order\":{\"title\":\"Pizza Order\",\"properties\":{\"customerName\":{\"type\":\"string\"},\"delivered\":{\"type\":\"boolean\"},\"address\":{\"type\":\"string\"},\"pizzaType\":{\"type\":\"string\"},\"creditCardNumber\":{\"type\":\"string\"},\"quantity\":{\"type\":\"number\"},\"orderId\":{\"type\":\"string\"}},\"required\":[\"orderId\"]}},\"consumes\":[\"application/json\"],\"info\":{\"title\":\"PizzaShackAPI\",\"description\":\"This document describe a RESTFul API for Pizza Shack online pizza delivery store.\\n\",\"license\":{\"name\":\"Apache 2.0\",\"url\":\"http://www.apache.org/licenses/LICENSE-2.0.html\"},\"contact\":{\"email\":\"architecture@pizzashack.com\",\"name\":\"John Doe\",\"url\":\"http://www.pizzashack.com\"},\"version\":\"1.0.0\"}}","wsdlUri": null,"status": "CREATED","responseCaching": "Disabled","cacheTimeout": 300,"destinationStatsEnabled": false,"isDefaultVersion": false,"type": "HTTP","transport": ["http","https"],"tags": ["pizza"],"tiers": ["Unlimited"],"maxTps": {"sandbox": 5000,"production": 1000},"visibility": "PUBLIC","visibleRoles": [],"endpointConfig": "{\"production_endpoints\":{\"url\":\"https://localhost:9443/am/sample/pizzashack/v1/api/\",\"config\":null},\"sandbox_endpoints\":{\"url\":\"https://localhost:9443/am/sample/pizzashack/v1/api/\",\"config\":null},\"endpoint_type\":\"http\"}","endpointSecurity": {"username": "user","type": "basic","password": "pass"},"gatewayEnvironments": "Production and Sandbox","sequences": [{"name":"json_validator","type": "in"},{"name":"log_out_message","type": "out"}],"subscriptionAvailability": null,"subscriptionAvailableTenants": [],"businessInformation": {"businessOwnerEmail": "marketing@pizzashack.com","technicalOwnerEmail": "architecture@pizzashack.com","technicalOwner": "John Doe","businessOwner": "Jane Roe"},"corsConfiguration": {"accessControlAllowOrigins": ["*"],"accessControlAllowHeaders": ["authorization","Access-Control-Allow-Origin","Content-Type","SOAPAction"],"accessControlAllowMethods": ["GET","PUT","POST","DELETE","PATCH","OPTIONS"],"accessControlAllowCredentials": false,"corsConfigurationEnabled": false}}'
After successful execution, copy the id value from the response. We will be using the id value to identify our Pizza Shack API when subscribing to an application.
Now we have to change the status of our created API from CREATED to PUBLISHED state.
POST: https://localhost:9443/api/am/publisher/v0.14/apis/change-lifecycle?apiId=<API Id Value>&action=PublishAuthorization: Bearer <Access Token>
curl command
curl -X POST \'https://localhost:9443/api/am/publisher/v0.14/apis/change-lifecycle?apiId=<API ID>&action=Publish' \-H 'Authorization: Bearer <Access Token>' \
Before subscribing an API, we have to create an application for it with the appropriate throttling tiers/subscription level.
We can also use the DefaultApplication from the Store to subscribe to an API, but for the demo, we will be creating a new application
Below presented is the request endpoint reference to create a new application.
POST: https://localhost:9443/api/am/store/v0.14/applicationsAuthorization: Bearer <Access Token>Content-Type: application/json{"throttlingTier": "Unlimited","description": "Demo App","name": "DemoApp","callbackUrl": "http://localhost"}
curl command
curl -X POST \https://localhost:9443/api/am/store/v0.14/applications \-H 'Authorization: Bearer <Access Token>' \-H 'Content-Type: application/json' \-d '{"throttlingTier": "Unlimited","description": "Demo App","name": "DemoApp","callbackUrl": "http://localhost"}'
Note down the applicationId value from the successful response.
At last, now we are in the section of subscribing to our created PizzaShackAPI with the above-generated DemoApp.
For subscription, we can use either the id value of our created API or the unique name of our PizzaShackAPI. Using the id value of an API is a straightforward execution. But sometimes, using the unique name will be more helpful when you know the minimal of an API.
admin has created an API named DemoAPI with version v1.0.0 then the unique name will be as admin-DemoAPI-v1.0.0foo from a tenant named bar has created an API named TenantAPI with the version 1.0 then the unique name will be as foo-AT-bar.com-TenantAPI-1.0POST: https://localhost:9443/api/am/store/v0.14/subscriptionsAuthorization: Bearer <Access Token>Content-Type: application/json{"tier": "Unlimited","apiIdentifier": "<API ID Value || API Unique Name>","applicationId": "<Application ID Value>"}
curl command
curl -X POST \https://localhost:9443/api/am/store/v0.14/subscriptions \-H 'Authorization: Bearer <Access Token>' \-H 'Content-Type: application/json' \-d '{"tier": "Unlimited","apiIdentifier": "admin-PizzaShackAPI-1.0.0","applicationId": "Application ID"}'
Next, we will be generating Production Keys for our DemoApp to generate an access token for API consumption.
POST: https://localhost:9443/api/am/store/v0.14/applications/generate-keys?applicationId=<Application ID Value>Authorization: Bearer <Access Token>Content-Type: application/json{"validityTime": "3600","keyType": "PRODUCTION","accessAllowDomains": [ "ALL" ],"scopes": [ "am_application_scope", "default" ],"supportedGrantTypes": [ "urn:ietf:params:oauth:grant-type:saml2-bearer", "iwa:ntlm", "refresh_token", "client_credentials", "password" ]}
curl command
curl -X POST \'https://localhost:9443/api/am/store/v0.14/applications/generate-keys?applicationId=<Application ID>' \-H 'Authorization: Bearer <Access Token>' \-H 'Content-Type: application/json' \-d '{"validityTime": "3600","keyType": "PRODUCTION","accessAllowDomains": [ "ALL" ],"scopes": [ "am_application_scope", "default" ],"supportedGrantTypes": [ "urn:ietf:params:oauth:grant-type:saml2-bearer", "iwa:ntlm", "refresh_token", "client_credentials", "password" ]}'
Note down both the consumerKey and consumerSecret values to generate an Access Token.
POST: https://localhost:8243/tokenAuthorization: Basic <Base64(ConsumerKey:ConsumerSecret)>Content-Type: application/x-www-form-urlencodedgrant_type=passwordusername=adminpassword=adminscope=default
curl command
curl -X POST \https://localhost:8243/token \-H 'Authorization: Basic <Base64(ConsumerKey:ConsumerSecret)>' \-H 'Content-Type: application/x-www-form-urlencoded' \-d 'grant_type=password&username=admin&password=admin&scope=default'
Note the access_token value to invoke and consumer our Pizza Shack API
At last, now we are going to invoke and consume our created Pizza Shack API using the below request endpoint reference with the above-generated access token.
GET: https://localhost:8243/pizzashack/1.0.0/menuAuthorization: Beaer <Access Token>
curl command
curl -X GET \https://localhost:8243/pizzashack/1.0.0/menu \-H 'Authorization: Bearer <Access Token>' \
After all these struggles, We have successfully created an API, application and subscribed and invoked them and achieved our goals.
I know it is hard to manage and remember these curl commands and you need a way to organize them. Therefore, please find the Postman REST API collection of this demo to make life easier.
Postman Collection