Read this in other languages: 한국어.
This project shows how serverless, event-driven architectures can execute code that scales automatically in response to demand from HTTP REST API calls. No resources are consumed until the API endpoints are called. When they are called, resources are provisioned to exactly match the current load needed by each HTTP method independently.
It shows four OpenWhisk actions (written in JavaScript) that write and read data in a MySQL database. This demonstrates how actions can work with supporting data services and execute logic in response to HTTP requests.
One action is mapped to HTTP POST requests. It inserts the supplied cat name and color parameters into the database. A second action is mapped to PUT requests to update those fields for an existing cat. A third action is mapped to GET requests that return specific cat data. A fourth action deletes a given cat data.
The Node.js runtime on Bluemix provides a built-in whitelist of npm modules. This demo also highlights how additional Node.js dependencies – such as the MySQL client – can be packaged in a ZIP file with custom actions to provide a high level of extensibility.
- OpenWhisk
- ClearDB or Compose (MySQL)
You should have a basic understanding of the OpenWhisk programming model. If not, try the action, trigger, and rule demo first.
Also, you'll need a Bluemix account and the latest OpenWhisk command line tool (wsk
) installed and on your PATH.
As an alternative to this end-to-end example, you might also consider the more basic "building block" version of this sample.
- Provision MySQL
- Create OpenWhisk actions and mappings
- Test API endpoints
- Delete actions and mappings
- Recreate deployment manually
Log into Bluemix and provision a ClearDB or a Compose for MySQL database instance. ClearDB has a free tier for simple testing, while Compose has tiers for larger workloads.
-
For ClearDB, log into the ClearDB dashboard, and select the default database created for you. Get the user, password and host information under "Endpoint Information".
-
For Compose, get the information from the "Service Credentials" tab in the Bluemix console.
Copy template.local.env
to a new file named local.env
and update the MYSQL_HOSTNAME
, MYSQL_USERNAME
, MYSQL_PASSWORD
and MYSQL_DATABASE
for your MySQL instance.
deploy.sh
is a convenience script reads the environment variables from local.env
and creates the OpenWhisk actions and API mappings on your behalf. Later you will run these commands yourself.
./deploy.sh --install
Note: If you see any error messages, refer to the Troubleshooting section below. You can also explore Alternative deployment methods.
There are four helper scripts that simulate HTTP API clients to create, get, update and delete entities against the /v1/cat
endpoint.
# POST /v1/cat {"name": "Tarball", "color": "Black"}
client/cat-post.sh Tarball Black
# GET /v1/cat?id=1
client/cat-get.sh 1 # Or whatever integer ID was returned by the command above
# PUT /v1/cat {"id": 1, "name": "Tarball", "color": "Gray"}
client/cat-put.sh 1 Tarball Gray
# DELETE /v1/cat?id=1
client/cat-delete.sh 1
Use deploy.sh
again to tear down the OpenWhisk actions and mappings. You will recreate them step-by-step in the next section.
./deploy.sh --uninstall
This section provides a deeper look into what the deploy.sh
script executes so that you understand how to work with OpenWhisk triggers, actions, rules, and packages in more detail.
Create four actions to manage cat data, one for each method (POST, PUT, GET, and DELETE) of our API. The code for the actions is located in /actions
. Let's start with the action action that creates a cat record first.
Note: There are a number of built-in packages available in the OpenWhisk Node.js runtime environment. If you need additional packages, you can upload them in a ZIP file along with your action file. More information on the single file versus zipped archive approaches is available in the getting started guide.
Because all of the actions rely on the MySQL database service, it's convenient to set the credentials once at the package level. This makes them available to all the actions in the package so we don't need to define them for each action at creation and run time.
source local.env
wsk package create cat \
--param "MYSQL_HOSTNAME" $MYSQL_HOSTNAME \
--param "MYSQL_USERNAME" $MYSQL_USERNAME \
--param "MYSQL_PASSWORD" $MYSQL_PASSWORD \
--param "MYSQL_DATABASE" $MYSQL_DATABASE
The JavaScript code for the POST action is in /actions/cat-post-action/index.js
. This function depends on the mysql
client npm package which we need to connect to the database. Install the package using npm install
(which parses package.json
) and create a ZIP file that includes both your application and its dependencies.
cd actions/cat-post-action
npm install
zip -rq action.zip *
Next use the OpenWhisk CLI to create an action from action.zip
.
# Create
wsk action create cat/cat-post \
--kind nodejs:6 action.zip \
--web true
Then manually invoke the action using the wsk
CLI to test.
# Test
wsk action invoke \
--blocking \
--param name Tarball \
--param color Black \
cat/cat-post
Repeat the steps above to create and test the corresponding GET, PUT, and DELETE actions.
Note: Replace the number 1 in your tests below to reflect the actual id returned from the POST action result above.
# Create
cd ../../actions/cat-get-action
npm install
zip -rq action.zip *
wsk action create cat/cat-get \
--kind nodejs:6 action.zip \
--web true
# Test
wsk action invoke \
--blocking \
--param id 1 \
cat/cat-get
# Create
cd ../../actions/cat-put-action
npm install
zip -rq action.zip *
wsk action create cat/cat-put \
--kind nodejs:6 action.zip \
--web true
# Test
wsk action invoke \
--blocking \
--param name Tarball \
--param color Gray \
--param id 1 \
cat/cat-put
wsk action invoke \
--blocking \
--param id 1 \
cat/cat-get
# Create
cd ../../actions/cat-delete-action
npm install
zip -rq action.zip *
wsk action create cat/cat-delete \
--kind nodejs:6 action.zip \
--web true
# Test
wsk action invoke \
--blocking \
--param id 1 \
cat/cat-delete
wsk action invoke \
--blocking \
--param id 1 \
cat/cat-get
Now map a resource endpoint (/cat
) to the GET
, DELETE
, PUT
, and POST
HTTP methods, associate them with the corresponding OpenWhisk actions, and use the client scripts to test.
# Create
wsk api create -n "Cats API" /v1 /cat post cat/cat-post
wsk api create /v1 /cat put cat/cat-put
wsk api create /v1 /cat get cat/cat-get
wsk api create /v1 /cat delete cat/cat-delete
# Test
# POST /v1/cat {"name": "Tarball", "color": "Black"}
client/cat-post.sh Tarball Black
# GET /v1/cat?id=1
client/cat-get.sh 1 # Replace 1 with the id returned from the POST action above
# PUT /v1/cat {"id": 1, "name": "Tarball", "color": "Gray"}
client/cat-put.sh 1 Tarball Gray
# DELETE /v1/cat?id=1
client/cat-delete.sh 1
Remove the API mappings and delete the actions.
wsk api delete /v1
wsk action delete cat/cat-post
wsk action delete cat/cat-put
wsk action delete cat/cat-get
wsk action delete cat/cat-delete
wsk package delete cat
Check for errors first in the OpenWhisk activation log. Tail the log on the command line with wsk activation poll
or drill into details visually with the monitoring console on Bluemix.
If the error is not immediately obvious, make sure you have the latest version of the wsk
CLI installed. If it's older than a few weeks, download an update.
wsk property get --cliversion
deploy.sh
will be replaced with wskdeploy
in the future. wskdeploy
uses a manifest to deploy declared triggers, actions, and rules to OpenWhisk.
You can also use the following button to clone a copy of this repository and deploy to Bluemix as part of a DevOps toolchain. Supply your OpenWhisk and MySQL credentials under the Delivery Pipeline icon, click Create, then run the Deploy stage for the Delivery Pipeline.