Create a Zero-Setup Microservice with Unbounded

Pop quiz: let’s say we want to quickly set up a microservice that stores data persistently, doesn’t cost anything to run when idle, yet is ready to scale immediately when needed. What’s the best technology stack to implement this?

One answer for the service side of things would be the well-known Serverless framework on AWS Lambda. But in this article, I’ll show you a new way to handle the data storage: instead of setting up a dedicated database instance, we’ll use Unbounded.

Unbounded is a database-as-a-service which, in various ways, takes a different approach from what you may be used to in NoSQL data stores. Since this article is the first in a series, we’ll only focus on a few properties of Unbounded which enable us to get our service up and running more easily.

To start with, we’ll install Serverless and create a new project:

$ npm install -g serverless
...
$ serverless
Serverless: No project detected. Do you want to create a new one?

Answer “Y” to create a new project, and select the “AWS Node.js” project type. For the service name, I chose “movies,” since we’re going to be making a movie database (yes, I know, there’s already a somewhat well-known movie database or two out there, but bear with me).

Now let’s change to our project directory and install the “express” package and some middleware to make our service easier to develop:

$ cd movies
$ ls
handler.js  serverless.yml
$ npm init
...
$ npm install --save express serverless-http body-parser

Since we’re using express, we need to edit the serverless.yml file to route all requests to our index function. Here’s an example file you can copy:

Then, we’ll replace the contents of handler.js with the following:

So far so good; assuming we have AWS credentials set up, running the “serverless deploy” command will give us a microservice with one endpoint to list our movies. Currently, this endpoint returns an empty JSON array, since we don’t have any data yet.

To help remedy that, we’ll install the Unbounded client library. Unbounded returns data using promises, so I’m also going to install the awaitjs package to allow us to easily use async/await with express (Unbounded supports callbacks as well, but hey, it’s 2020, let’s live on the edge):

$ npm install --save @unbounded/unbounded @awaitjs/express

Now let’s update our service code:

This should (we hope) be fairly straightforward if you’re familiar with Node and express. We create an Unbounded connection by specifying a region name (“aws-us-east-2”), an email address, and a password (see *** note below). We’ve added two new express handlers to create and retrieve a single object, and updated the “GET /movies” handler to get all movies from the database. To implement this, we used the “insert”, “match” and “query” calls on the Unbounded client instance. Since Unbounded records are plain JSON objects, we can send the results of our “match/query” calls directly to express.

But now comes the twist: what else do we need to do to set up our backend data store before we’re finished?

Nothing.

If we replace the example email and password with our own email and a made-up password, then redeploy our service, it’s ready to test immediately:

$ curl -X POST [https://xxxxxxxxx.execute-api.us-east-2.amazonaws.com/dev/movies](https://xxxxxxxxx.execute-api.us-east-2.amazonaws.com/dev/movies) -d 'name=Back to the Future&year=1985'

{"id":"P0ePhfWRdZu4UNZV20Mw"}

$ curl [https://xxxxxxxxx.execute-api.us-east-2.amazonaws.com/dev/movies](https://xxxxxxxxx.execute-api.us-east-2.amazonaws.com/dev/movies)/P0ePhfWRdZu4UNZV20Mw

{"name":"Back to the Future","year":1985,"reviews":[],"id":"P0ePhfWRdZu4UNZV20Mw"}

This is possible because we’re using some properties of Unbounded meant to get you up and running quickly:

  • When inserting data, if a user doesn’t exist with the specified email address, Unbounded will create a new user (if you want to keep your data forever, you’ll have to eventually verify that your email is real by logging in at the admin site).

  • When inserting data into a database that doesn’t exist, Unbounded automatically creates the database.

  • By default, databases are created with a single primary key field named “id”.

  • When inserting objects, any unspecified primary key values are created as random strings.

  • We don’t need a schema because by default, because Unbounded places no restrictions on what data can be inserted. Properties can contain embedded objects or arrays as well as simple JSON values (we’ll use this later when populating our “reviews” property).

Of course, in a real scenario, we’re not limited to this basic configuration for using Unbounded, nor are we limited to simple key/value queries to retrieve our objects. But we’ll start covering those and many other features in a future article.

For now, we invite you to get started experimenting with Unbounded on your own. Check out our main documentation portal or Javascript client module for technical information, and feel free to send us feedback at datateam@unbounded.cloud or on Twitter as we continue to refine and expand our APIs.

Have fun!

— W.W.

(and check out part 2 of this article here)

*** A note about passwords: we put a password directly in the source code only as an example. This is poor practice because pushing this source to a public repository would result in a leak of sensitive information. If you plan to deploy a real service, use the secret keeping mechanisms that are built into Serverless.