Let's now show how these web actions can be turned into an API using the API Gateway. First we will choose /myapi as the base path. This is the part of the path before the actual endpoint. For example: example.com/basepath/endpoint. This is useful for grouping enpoints together in a logical way and is how IBM Cloud Functions organizes your endpoints into a single API.
To create an API we will run the following command
ibmcloud fn api create BASE_PATH API_PATH API_VERB ACTION{% hint style="warning" %} The example above is merely an example of the syntax used to create an API endpoint and should not be run. {% endhint %}
First we will create the hello endpoint. Note that all actions used in an API must be web actions, so we mustn't forget to run ibmcloud fn action update hello --web true prior to following commands below.
- Run the following command to create a simple GET endpoint for the hello action
ibmcloud fn api create /myapi /foo get hellook: created API /myapi/foo GET for action /_/hello
https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/aac6bc4a6f94f19dd008e64513b62bf155af5703a95a142f0c9a6ea83af81300/myapi/foo- Check to see the api was create
ibmcloud fn api listok: APIs
Action Verb API Name URL
/joesphine.watson@gmail.com_ns/hello get /myapi https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/d9903f40439f1a268b7dcbac42a389cdde605f3f3bef57f69789be6df438361e/myapi/hello- Now lets invoke that API via curl
curl https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/aac6bc4a6f94f19dd008e64513b62bf155af5703a95a142f0c9a6ea83af81300/myapi/foo{
"greeting": "Hello, undefined from undefined"
}We will now be creating endpoints for the other web actions created in the previous section.
Now we must be mindful that by default the IBM Cloud Functions expects that return type will be JSON. Since for the remaining functions this is not the case, we must be mindful to set the appropriate response types with the --response-type TYPE flag. Valid types include http, json, text, svg.
- Create the endpoint for the http endpoint
ibmcloud fn api create /myapi /redirect get redirect --response-type http ok: created API /myapi/redirect GET for action /_/redirect
https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/d9903f40439f1a268b7dcbac42a389cdde605f3f3bef57f69789be6df438361e/myapi/redirect- Check to make sure that the redirect works
curl https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/d9903f40439f1a268b7dcbac42a389cdde605f3f3bef57f69789be6df438361e/myapi/redirect...
< HTTP/1.1 302 Found
< Date: Wed, 20 Nov 2019 16:04:09 GMT
< Content-Type: text/plain
< Content-Length: 0
< Connection: keep-alive
< Set-Cookie: __cfduid=d8e6927590dacedec6ea476916d381c781574265849; expires=Fri, 20-Dec-19 16:04:09 GMT; path=/; domain=.functions.cloud.ibm.com; HttpOnly
< X-Request-ID: fb4b9e9f86b058fa1cf2f990be22a8da
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS
< Access-Control-Allow-Headers: Authorization, Origin, X-Requested-With, Content-Type, Accept, User-Agent
< x-openwhisk-activation-id: 24b94b370cf049e2b94b370cf0e9e207
< location: http://openwhisk.org
< IBM_Cloud_Functions: OpenWhisk
< CF-Cache-Status: DYNAMIC
< Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
< CF-RAY: 538ba8760c57c7c1-DEN
< Access-Control-Allow-Credentials: true
< X-Request-Id: 4Gk6GDz6VV2xHVwrOtJbsfS5UQuot5gI
...- Create the endpoint form the html action
ibmcloud fn api create /myapi /html get html --response-type httpok: created API /myapi/html GET for action /_/html
https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/d9903f40439f1a268b7dcbac42a389cdde605f3f3bef57f69789be6df438361e/myapi/html- Check the endpoints output:
curl https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/d9903f40439f1a268b7dcbac42a389cdde605f3f3bef57f69789be6df438361e/myapi/html<html><body>Hello World!</body></html>- Finally we create a PUT endpoint for the manual JSON action.
ibmcloud fn api create /myapi /manual put manual --response-type jsonok: created API /myapi/manual PUT for action /_/manual
https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/d9903f40439f1a268b7dcbac42a389cdde605f3f3bef57f69789be6df438361e/myapi/manual- Test the output of the PUT action
curl -XPUT https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/d9903f40439f1a268b7dcbac42a389cdde605f3f3bef57f69789be6df438361e/myapi/manual\?hello\=world{
body: {
"__ow_method": "put",
"__ow_path": "",
"hello": "world"
},
"headers": {
"Content-Type": "application/json"
},
"statusCode": 200
}- Test that a GET request does not work since we have not set up a GET endpoint
curl -XGET https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/d9903f40439f1a268b7dcbac42a389cdde605f3f3bef57f69789be6df438361e/myapi/manual\?hello\=world{"status":404,"message":"Error: Whoops. Verb not supported."}Let's take stock of our API by listing out all the endpoints:
ibmcloud fn api listok: APIs
Action Verb API Name URL
/josephine.watson@gmail.com_ns/hello get /myapi https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/d9903f40439f1a268b7dcbac42a389cdde605f3f3bef57f69789be6df438361e/myapi/hello
/josephine.watson@gmail.com_ns/html get /myapi https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/d9903f40439f1a268b7dcbac42a389cdde605f3f3bef57f69789be6df438361e/myapi/html
/josephine.watson@gmail.com_ns/manual put /myapi https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/d9903f40439f1a268b7dcbac42a389cdde605f3f3bef57f69789be6df438361e/myapi/manual
/josephine.watson@gmail.com_ns/redirect get /myapi https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/d9903f40439f1a268b7dcbac42a389cdde605f3f3bef57f69789be6df438361e/myapi/redirectAs we can begin to tell, as the number of API endpoints increases, documenting and managing them becomes increasingly difficult. One solution to this to use the OpenAPI Specification. This has a plethora of tools around for documenting, creating stub projects, etc in a variety of languages. And it is supported by IBM Cloud Functions!
We can see the OpenAPI Specification for myapi using the following command:
ibmcloud fn api get /myapiYou should see a long JSON document that starts something like:
{
"swagger": "2.0",
"basePath": "/myapi",
"info": {
"title": "/myapi",
"version": "1.0.0"
},
...
}We will want to write that to a file with:
ibmcloud fn api get /myapi > myapi.jsonNow we can delete the existing API we have created and restore using this document:
- Delete the existing API
ibmcloud fn api delete /myapiok: deleted API /myapi- Check that the endpoints are gone:
ibmcloud fn api listok: APIs
Action Verb API Name URL- Restore the endpoints from the OpenAPI Specification:
ibmcloud fn api create -c myapi.jsonok: created API /myapi/redirect get for action /josephine.watson@gmail.com_ns/redirect
https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/d9903f40439f1a268b7dcbac42a389cdde605f3f3bef57f69789be6df438361e/myapi/redirect
ok: created API /myapi/hello get for action /josephine.watson@gmail.com_ns/hello
https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/d9903f40439f1a268b7dcbac42a389cdde605f3f3bef57f69789be6df438361e/myapi/hello
ok: created API /myapi/html get for action /josephine.watson@gmail.com_ns/html
https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/d9903f40439f1a268b7dcbac42a389cdde605f3f3bef57f69789be6df438361e/myapi/html
ok: created API /myapi/manual put for action /josephine.watson@gmail.com_ns/manual
https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/d9903f40439f1a268b7dcbac42a389cdde605f3f3bef57f69789be6df438361e/myapi/manual- We can now see that endpoints are restored:
ibmcloud fn api listok: APIs
Action Verb API Name URL
/josephine.watson@gmail.com_ns/hello get /myapi https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/d9903f40439f1a268b7dcbac42a389cdde605f3f3bef57f69789be6df438361e/myapi/hello
/josephine.watson@gmail.com_ns/html get /myapi https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/d9903f40439f1a268b7dcbac42a389cdde605f3f3bef57f69789be6df438361e/myapi/html
/josephine.watson@gmail.com_ns/manual put /myapi https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/d9903f40439f1a268b7dcbac42a389cdde605f3f3bef57f69789be6df438361e/myapi/manual
/josephine.watson@gmail.com_ns/redirect get /myapi https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/d9903f40439f1a268b7dcbac42a389cdde605f3f3bef57f69789be6df438361e/myapi/redirectThis OpenAPI Specification can now be stored in your code repository, and used to update endpoints, documentation, or event generate stub code!