Skip to content

Latest commit

 

History

History
255 lines (217 loc) · 10.3 KB

File metadata and controls

255 lines (217 loc) · 10.3 KB

API

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.

Managing APIs

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 %}

Hello Endpoint

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.

  1. Run the following command to create a simple GET endpoint for the hello action
ibmcloud fn api create /myapi /foo get hello
ok: created API /myapi/foo GET for action /_/hello
https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/aac6bc4a6f94f19dd008e64513b62bf155af5703a95a142f0c9a6ea83af81300/myapi/foo
  1. Check to see the api was create
ibmcloud fn api list
ok: 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
  1. 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.

Other Response Types

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.

  1. 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
  1. 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
...
  1. Create the endpoint form the html action
ibmcloud fn api create /myapi /html get html --response-type http
ok: created API /myapi/html GET for action /_/html
https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/d9903f40439f1a268b7dcbac42a389cdde605f3f3bef57f69789be6df438361e/myapi/html
  1. Check the endpoints output:
curl https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/d9903f40439f1a268b7dcbac42a389cdde605f3f3bef57f69789be6df438361e/myapi/html
<html><body>Hello World!</body></html>
  1. Finally we create a PUT endpoint for the manual JSON action.
ibmcloud fn api create /myapi /manual put manual --response-type json
ok: created API /myapi/manual PUT for action /_/manual
https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/d9903f40439f1a268b7dcbac42a389cdde605f3f3bef57f69789be6df438361e/myapi/manual
  1. 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
}
  1. 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 list
ok: 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/redirect

Using OpenAPI Specification

As 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 /myapi

You 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.json

Now we can delete the existing API we have created and restore using this document:

  1. Delete the existing API
ibmcloud fn api delete /myapi
ok: deleted API /myapi
  1. Check that the endpoints are gone:
ibmcloud fn api list
ok: APIs
Action                            Verb             API Name  URL
  1. Restore the endpoints from the OpenAPI Specification:
ibmcloud fn api create -c myapi.json
ok: 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
  1. We can now see that endpoints are restored:
ibmcloud fn api list
ok: 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/redirect

This OpenAPI Specification can now be stored in your code repository, and used to update endpoints, documentation, or event generate stub code!