Fast API Prototyping with Webtask.io and Serverless.
Tags: webtask, rest, softwareengineering, serverless
Published: 2017-10-04 07:13:58

---
title: "Fast API Prototyping with Webtask.io and Serverless."
published: true
tags: webtask,rest,software-engineering,serverless
canonical_url: 
---

![](https://cdn-images-1.medium.com/max/1024/1*6lR-YCYovFX1ZujxZYjpAg.jpeg)<figcaption>Photo by <a href="https://unsplash.com/photos/WR-ifjFy4CI?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">ShiroÂ hatori</a></figcaption>

Function as a Service (FaaS) commonly referred as _serverless computing_, feels like the answer to every engineer’s prayers. Simple functions, doing only one small thing and running in infrastructure that scales automatically for a small price, or even for free&nbsp;ðŸ˜!

[**Webtask**](https://webtask.io/) is the Function as a Service implementation from the Auth0 team. It’s perfect for prototyping and easy to get started with. They just released their Serverless integration [last&nbsp;week](https://serverless.com/blog/serverless-webtasks/).

I’m working with [**Serverless**](https://serverless.com) on my current project, and I’ve wanted to take Webtask for a spin for a while, so I decided this was the perfect time for&nbsp;it.

In a few minutes, I had a REST API, deployed, and running with the help of Express, RethinkDB, Webtask, and Serverless.

### Getting started&nbsp;ðŸ

Install the serverless framework and create a new&nbsp;project:

{% gist https://gist.github.com/eduardoromero/0e06c07bb10ede7c84c25a55e82249e6 %}

Go into the project’s folder and add the dependencies with&nbsp;NPM:

{% gist https://gist.github.com/eduardoromero/a5a974511e795d6d5049c1d2101575a7 %}

- express and body-parser will handle routing and JSON responses.
- webtask-tools wraps the express app and binds it to the webtask&nbsp;handler.
- rethinkdbdash is a RethinkDB [driver](https://github.com/neumino/rethinkdbdash); it has some cool features like connection pooling, an easier interface, and outstanding performance.

Update serverless.yml. Change the service name and add the IP of the RethinkDB server:

{% gist https://gist.github.com/eduardoromero/f7e7607ea244721671a8a0c84a3d64d3 %}

The only differences from the default config should be the service name and the environment and defaults&nbsp;options.

The options tell the _provider_ (webtasks in this case) to set RETHINKDB\_SERVER as an environment variable and to take its value from either the environment (env), an option from the command line when deploying (--rethinkdb-server) or, if neither is set, from the defaults&nbsp;section.

The API will be running from Auth0’s FaaS infrastructure. RethinkDB needs to be reachable from the internet. I launched a Digital Ocean instance for&nbsp;that.

The final step is to set up a Webtask&nbsp;account:

{% gist https://gist.github.com/eduardoromero/e485b02eab39245b6befca0f1bda7f92 %}

### Show me the code!&nbsp;ðŸ¤“

At this point, there is already a Function that can be deployed, run and tested. Give it a&nbsp;try:

{% gist https://gist.github.com/eduardoromero/e875358109d7cbf88193a081930749b7 %}

It is important to run npm update to install all packages before deploying a function. Dependencies will be pulled from node\_modules and uploaded with the function.

![](https://cdn-images-1.medium.com/max/1024/1*AugVGTQo6OHDe7ylWZDzyw.png)<figcaption>Running <strong>sls deploy </strong>will return the URL of the function ðŸŽ‰â€Š–â€ŠReturns a JSON response with a successÂ message.</figcaption>

The service is running already and zero code. Wow! That is really something!

> I realized that this was an excellent first approach to the FaaS paradigm. Definitely easier than setting up an account for AWS&nbsp;Î».

Now into the actual&nbsp;code…

#### Express + RethinkDB

Like most express apps, start by adding express, body-parser, and webtask-tools. Create the app and add the database as a middleware to all&nbsp;routes:

{% gist https://gist.github.com/eduardoromero/7860d8a6a056228386382bcd9b6cd024 %}

The RethinkDB instance is now available as db through every endpoint.

#### The API

- GET /: Retrieves all documents from RethinkDB.
- GET /:id: Returns a particular document with the given&nbsp;id.

{% gist https://gist.github.com/eduardoromero/f822a801cf83039f711c593998628014 %}

It is a simplistic version with no filtering and basic pagination.

The endpoint will get the response from RethinkDB and return it to the client. If anything goes wrong, it will send the error&nbsp;instead.

- POST /: Creates a new document.
- PUT /: Updates an existing document.

{% gist https://gist.github.com/eduardoromero/043dd254836e9135910573a781e2e7d2 %}

Creating and modifying data is just as&nbsp;simple.

The endpoint gets the JSON from the request and saves it into the shares table. The code is almost the same for both functions.

RethinkDB has support for _upserts_. When the conflict option is set to update if the body of the request has an existing id it will replace the document. The default behavior is to throw an error if the document with that id exists, which is what the POSTs method is&nbsp;doing.

With returnChanges, the query will return an Array with the resulting changes of the operation in a special object with two properties: new\_val and old\_val. We use new\_val to return the _upserted_ item in the response. In the case of a POST, the object will include the id of the new document.

RethinkDB accepts an Array or an Item when inserting. Lines 6 and 11 normalize the response. If the request had an array, it would return an array with the changes. If it were just one item, it would return only one&nbsp;item.

Besides returning the actual data, it includes the response from RethinkDB. It contains an object with helpful information that looks like&nbsp;this:

```
"response": {
    "changes": [
        {
            "new_val": {
                "id": "044ec21c-78b9-47aa-9eb6-e7e5658237db",
                "name": "Tania ðŸ˜"
            },
            "old_val": {
                "id": "044ec21c-78b9-47aa-9eb6-e7e5658237db",
                "name": "Tania"
            }
        }
    ],
    "deleted": 0,
    "errors": 0,
    "inserted": 0,
    "replaced": 1,
    "skipped": 0,
    "unchanged": 0
}
```

It can be helpful for the requester to know what happened to the&nbsp;data.

- DELETE /:id: Removes the document with the given id from the&nbsp;table.

{% gist https://gist.github.com/eduardoromero/339fe12e2a61d988d753b3b531ce60e8 %}

The endpoint gets the id from the request, and ask RethinkDB to remove that document. If anything goes wrong (i.e., the id doesn’t exist) it sends the error back to the&nbsp;client.

That’s all. A fully working –barebonesâ€Š–â€Šfunction as a service-based REST API. The code is straightforward. Small functions that are easy to read and understand.

Next steps will be adding Authentication to the requests and some business logic so the service is more&nbsp;helpful.

> I will continue working on it and will elaborate about it in another&nbsp;post.

Webtask and Serverless make it easy to start _“dipping your toes”_ into the _Function as a Service_ world. It focuses around NodeJS with only two event sources HTTP Requests and Scheduled events. Compared to AWS Lambda it’s faster to get started and easier to approach.

Webtask’s free tier is limited to a request per second. But that should be enough for testing; maybe even for a basic&nbsp;service.

### More resources ðŸ“š

- [**Webtask.io**](https://webtask.io/docs/101), the FaaS from the Auth0 guys. It’s easy and straightforward. Works with Node 8 out of the box and it takes less than a minute to get started. Super useful to get started with Slack hooks, Bots, and APIs. It has a fully-featured Web Editor that makes things even simpler. It has real-time logs, 500k of JSON storage, a cron-like scheduler, and Auth0 support is baked&nbsp;in.
- [**Serverless**](https://serverless.com/framework/) is a toolkit to work with serverless architectures from any provider (AWS Lambda, Google Functions, Azure Functions, OpenWhisk, Webtask, etc.). With the help of its Event Gateway, you can even combine different providers and make them all work together.
- [**RethinkDB**](https://www.rethinkdb.com/api/javascript/skip/) is an Open Source NoSQL Database with a very nice querying language ([ReQL](https://www.rethinkdb.com/docs/introduction-to-reql/)) and advanced features like clustering, near-linear scaling, and real-time feeds. It’s my go-to NoSQL data&nbsp;store.
- [**Thinky**](https://github.com/neumino/thinky) a Javascript ORM for RethinkDB. An easier way to map skinny JSON objects to RethinkDB documents.

_Thanks to_ [_Rafa Salazar_](https://medium.com/u/ff471ed75d8d)_,_ [_David NÃºÃ±ez_](https://medium.com/u/96892ff0fe88)_,_ [_Andres Cespedes_](https://medium.com/u/ad3d4c815e6a) _and_ [_Martin Moscosa_](https://medium.com/u/d4888e26f384) _for helping with this&nbsp;article._