Design a serverless REST API – IBM cloud functions and cloudant

In this tutorial, we are going to create a serverless web application using cloudant and IBM Cloud™ Functions. Our REST API will be a simple todo list where we can view, add, edit and delete todos.

Objectives

  1. Deploy a serverless backend and a database
  2. Create Actions for different tasks
    1. Add todo
    2. View todos
    3. Edit todo
    4. Delete todo
  3. Expose a REST API for all the above Actions

If you prefer video tutorial you can watch this video or keep reading.

In order to follow this tutorial you will need a IBM cloud account. If you do not have one you can register here. They have a free tier. This Lite account is free – no credit card required.

You can follow their official tutorial on creating a REST API. This tutorial is a good starting point if you are just trying out.

01. Create a database

Our first step will be creating a database for our todolist REST API. Once you are logged in and visit catalog you will see cloudant as a featured product (If not you can click on services on the left side and under category click on databases, You will see cloudant among other databases). Now click on cloudant and it will open a new window.

  1. Under Multitenant I’ll select Chennai as my region but you should pick a region near you.
  2. Under Configure Cloudant instance we have to pick a *unique name, Lets name it Cloudant-todolist
  3. We will keep everything same and pick the free Lite plan.
  4. Click Create.

Now it should redirect you to Resources List page if not you can click on this link. Under services you can check your newly created Cloudant instance.

Wait for it to active and then click on it. It should open a new window and you will see a Lunch Dashboard button top-right of your screen, click on it. It will open a new window and In the upper right, click on Create Database. Enter todolist as name and select Non-Partitioned under Partitioning. Click Create to create the database.

Ok, Our database is created now lets switch back to the other page (The page with Lunch Dashboard button). In the left side click on Service credentials.

  1. Click New credential.
  2. Set the name to for-todolist. Leave the role as Manager.
  3. Click Add to add the new credentials.

Our first step is completed, We have created our Cloudant instance and our todolist database, also we created credential so we can interact with the database.

02. Create serverless actions

Now we are going to create a sequence of actions for each of our API routes. Let’s start by creating our first action, add todos to our database.

Sequence of actions to save the todo entry

  • 1. In the browser, open a tab and go to Functions.
  • 2. Go to the Actions list.
  • 3. Create a new action:
    1. Set Name as prepare-entry-for-save as name.
    2. Click Create Package to create a new package with name todolist.
    3. Pick Node.js as Runtime.
    4. Click Create to create the action.
  • 4. In the new dialog replace the existing code with the code snippet below:
/**
 * Prepare the todo entry to be persisted
 */
function main(params) {
  if (!params.name) {
    return Promise.reject({ error: 'no name is provided'});
  }

  return {
    doc: {
       createdAt: new Date(),
       name: params.name,
       completed: false,
    }
  };
}
  • 5. Thereafter click Save.

Now we have to add the action to a sequence:

  1. On the left pane, click on Enclosing Sequences and then Add To Sequence.
  2. Under Create New set the Sequence Name to save-todo-to-sequence and choose todolist as package.
  3. Select todolist for the Enclosing Package
  4. Then finish by clicking Create and Add.

Now, we have created a sequence, Let’s add the second action to that sequence:

  1. Click on the entry save-todo-to-sequence. It opens sequence details. Then click Add on the upper right.
  2. Now instead of Create New select Use Public. Pick Cloudant.
  3. Under Actions choose create-document.
  4. Create a New Binding and complete the form as follows:
    1. Set Name to binding-for-todolist.
    2. For Instance select your instance, for the credentials for-todolist as created earlier, and as Database pick todolist.
  5. Click Add, thereafter Save.
  6. To test the entire sequence, click on Invoke with parameters and enter the JSON below and Click Invoke.
{
   "name":"Go to Gym"
}

Sequence of actions to retrieve entries

The second sequence will retrieve the existing todos entries and format them.

  1. Under Functions, click on Actions and then Create.
  2. Then, after selecting Action, use set-read-input as name. Again, select todolist as package and a Node.js version as runtime. Click Create.
  3. In the action details, replace the existing code with the code snippet below and click Save.
function main(params) {
  return {
    params: {
      include_docs: true
    }
  };
}
  1. Similar to earlier, click on Enclosing SequencesAdd to Sequence and Create New.
  2. Enter read-todolist-entries-sequence for the Sequence Name
  3. Select todolist for the Enclosing Package and click Create and Add.

Next we have to add two more actions to the sequence

  1. Click on read-todolist-entries-sequence and then click Add.
  2. Under Use Public, choose IBM Cloudant and then list-documents
  3. Under My Bindings, choose binding-for-todolist and Add
  4. Click Add again to create and add the third action, use format-entries for the name.
  5. Click todolist for the Enclosing Package and then click Create and Add.
  6. Click on format-entries and replace the code with below and click on Save.
function main(params) {
  return {
    entries: params.rows.map((row) => { return {
      name: row.doc.name,
      completed: row.doc.completed,
      _id:row.doc._id,
      _rev:row.doc._rev,
      createdAt:row.doc.createdAt
    }})
  };
}

Sequence of actions to edit entries

This sequence will edit the existing todos. Modify the name or completed field.

  1. Same as before click on Actions and then Create, use update-todo-item as name. Select todolist as package and a Node.js version as runtime. Click Create.
  2. In the action details, replace the existing code with the code snippet below and click Save.
function main(params) {
    if(!params.doc){
        return Promise.reject({ error: 'no doc is provided'});
    }
	return { doc:{...params.doc, createdAt:new Date()}};
}
  1. Lets create a sequence, click on Enclosing SequencesAdd to Sequence and Create New.
  2. Enter update-todo-entry-sequence for the Sequence Name
  3. Select todolist for the Enclosing Package and click Create and Add.

Next modify the todo

  1. Click on update-todo-entries-sequence and then click Add.
  2. Under Use Public, choose IBM Cloudant and then update-documents
  3. Under My Bindings, choose binding-for-todolist and Add.

That’s it this is all we need to do to update a todo in the database. You have to add the doc as parameter in order to update the todo. Below you can see an example:

{
  "doc": {
  "_id": "169b184b75a44b5b4ff90d12e17570b3",
  "_rev": "2-483e51539177dc264a9190318aead703",
  "completed": false,
  "createdAt": "2020-12-07T08:33:13.706Z",
  "name": "Go to Gym"
 }
}

Sequence of actions to delete entries

This sequence will delete a existing todo from the DB.

  1. Click on Actions and then Create, use delete-todo-item as name. Select todolist as package and a Node.js version as runtime. Click Create.
  2. In the action details, replace the existing code with the code snippet below and click Save.
 function main(params) {
      if (!params.docid || !params.docrev) {
    return Promise.reject({ error: 'docid and docrev is required'});
  }
	return { docid: params.docid,docrev:params.docrev };
}
  1. Lets create a sequence for this one too like all the above, click on Enclosing SequencesAdd to Sequence and Create New.
  2. Enter delete-todo-entry-from-sequence for the Sequence Name
  3. Select todolist for the Enclosing Package and click Create and Add.

Next a pre made public action to delete the todo

  1. Click on delete-todo-entry-from-sequence and then click Add.
  2. Under Use Public, choose IBM Cloudant and then delete-documents
  3. Under My Bindings, choose binding-for-todolist and Add.

You have to pass docid and docrev as parameter in order to delete a doc. An example:

{
    "docid": "169b184b75a44b5b4ff90d12e17570b3",
    "docrev": "3-d47c013b6229535610479a4cd3917405"
}

Ok, Now we are done creating all the router for our REST API.

03. Create an API

We have to enable our four action sequence as Web actions. Lets click on save-todo-to-sequence and Next to the name, click on Web Action, check Enable as Web Action and Save. Do the same for the other three sequence.

  1. Go to APIs and click Create API.
  2. Set the API name to todolist and set the base path to /api.
  3. Click on Create operation and create an operation to retrieve Todolist entries:
    1. Set path to /entries
    2. Set verb to GET
    3. Select the read-todolist-entries-sequence action
  4. Click on Create operation and create an operation to add a todo entry:
    1. Set path to /entries
    2. Set verb to PUT
    3. Select the save-todo-to-sequence action
  5. Click on Create operation and create an operation to edit a todo entry:
    1. Set path to /entries
    2. Set verb to PATCH
    3. Select the update-todo-entry-sequence action
  6. Click on Create operation and create an operation to delete a todo entry:
    1. Set path to /entries
    2. Set verb to DELETE
    3. Select the delete-todo-entry-from-sequence action

Scroll to the end of the page to Create the API. That’s it we have successfully created our REST API. Take a note of the API route so you can use it later.

My Thoughts on IBM Cloud

I’m a self taught web developer and I heavily relay on documentations to learn/create something but IBM lacks it in big time. I have tried most of the cloud platforms available and learned one thing that complexity of creating something(user experience) does not really matter as most of the people who will be using they all are developers so if you have good documentations anyone can easily follow. I would suggest to improve the documentation add lots of code snippet. Create tutorial of different topics/small real-world useful apps both video and text versions.

Let me know in the comments if anyone have any questions. Stay safe and spread kindness. ?

Dipankar Maikap

Dipankar Maikap

I'm a freelance web developer. I work out of Kolkata, India. My favorite number is 77.

Leave a Reply