How to Develop a REST API on an 8base Workspace

Using serverless functions to stand up REST endpoints on an 8base Workspace

By default, the 8base platform auto-generates an extremely powerful GraphQL API that gives you immediate API access to your data. Sometimes though, developers are using a 3rd party service or another tool that doesn’t easily support the authoring and execution of GraphQL queries. Instead, they require that a REST API (or discrete endpoints) be available.

Developing a REST API in 8base can easily be accomplished using the Webhook custom function type. Using Webhooks, a developer can quickly code and deploy serverless functions that become available using traditional HTTP verbs (GET, POST, PUT, DELETE, etc.) and a unique path.

Getting Started Building a REST API on 8base

To get started building a REST API on top of an 8base workspace, you’re going to need to have the following resources created/installed.

  1. An 8base Workspace (Free tier or Paid Plan)
  2. 8base CLI installed (Instructions available here)
  3. A Text Editor or IDE (VS Code, Atom, Sublime, or any other way to write code)

Once all those things are ready, go ahead and open the command line and use the following commands to generate a new 8base server-side project.‍

That’s it!

Generating the Serverless Functions for your REST API

Let’s go ahead and generate all of our serverless functions. We can do this pretty quickly using the 8base CLI’s generator commands. Using the generators, we’ll be able to create each one of our functions for each endpoint of our REST API.

As you’ve probably noticed at this point, we’re building a REST API that gives access to our 8base workspace’s Users table. This is because the Users table is created with the workspace by default, thus you don’t need to create any new tables for the tutorial. That said, the same pattern we’ll cover would work for any other database table you choose to use (or multiple).

Additionally — since we are just building this API for the Users table — it’s okay that all these functions are grouped at the top level of the src/webhooks director. If you are building a REST API that is going to deal with lots more tables or more custom endpoints, this directory structure might quickly feel busy/un-organized.

Nothing stopping you from restructuring your directory to better suit your organizational needs! All you need to do is make sure that the function declaration in the 8base.yml file has a valid path to the function’s handler file/script. For example, take a look at the following directory structure and 8base.yml file:

Example directory structure for 8base project REST API functions

For the sake of simplicity, let stick with the directory structure that was generated for us by the CLI! It’s only important to know that such reconfiguration is possible.

Writing our REST APIs Serverless Functions

Now that we have our serverless functions generated, let’s go ahead and start adding some code to them. What’s important to know about a Webhook function is that two important objects get passed through to the function via the event argument. They are data and pathParameters.

The data argument is where any data sent via a POST or PUT request can get accessed. Meanwhile, any query params or URL params sent via the request become accessible in the pathParameters object. Therefore, if a GET request was made to the endpoint /users/{id}?local=en, the value for id and local would both be available via event.pathParameters[KEY].‍

GET User endpoint

Knowing this, let’s set up the GET User (/users/{id}) endpoint! To help with our GraphQL queries inside the function, add the GraphQL Tag NPM package using npm install -s graphql-tag. Then, go ahead and copy the code below into your getUser function’s handler file.

You’ll likely spot an unrecognized import; responseBuilder. Webhook’s require that the following keys get declared in returned objects — statusCode, body, and (optionally) headers. Instead of writing out and every single response object explicitly, we can start generating them using a handy responseBuilder function.

So let’s go ahead and create a new directory and file using the following commands and then place our responseBuilder function in there.

Copy in the following script.

Awesome! Almost as if we were building a controller method that runs a SQL query and then returns some serialized data, here were exercising the same pattern but using a serverless function that utilizes the GraphQL API.

As you can imagine, the other functions are likely going to be similar. Let’s go ahead and set them all up before we move into testing.‍

GET Users endpoint

Let’s now set up a way to list all Users via our REST API. Go ahead and copy the code below into your getUsers function’s handler file.

POST User endpoint

Let’s now set up a way to add new Users via our REST API. Go ahead and copy the code below into your newUser function’s handler file.

PUT User endpoint

Let’s now set up a way to edit Users via our REST API. Go ahead and copy the code below into your editUser function’s handler file.

DELETE User endpoint

Let’s now set up a way to edit Users via our REST API. Go ahead and copy the code below into your deleteUser function’s handler file.

Testing our REST API locally

Nice work so far! Pretty straightforward, right? What’s next is an extremely important step; testing. That is, how do we run these functions locally to make sure they are behaving as expected?

You may have noticed a directory called mocks that is in each of the function’s directories. Essentially, mocks allow us to structure a JSON payload that gets passed as the event argument to our function when testing locally. The JSON object that gets declared in a mock file will be the same argument passed to the function when testing — nothing more, nothing less.

That said, let’s go ahead and run our getUsers function since it ignores the event argument. We can do this using the invoke-local CLI command, as well as expect a response that looks like the following:

Copy the id of the first returned user in the response. We’re going to use it to create a mock for our getUser function. So, now add the following JSON in the src/webhooks/getUser/mocks/request.json file.

With this mock set up, let’s go ahead and see if we can successfully use our REST API to get a user by their ID set in the URL params.

Now, what if you want to specify data? Like, when you want to test an update? The exact sample principle applies. We add a data key to our mock with the data we expect to be sent to our endpoint. Try it yourself by adding the following JSON in the src/webhooks/editUser/mocks/request.json file.

Lastly, not all API requests are always successful… We added error handling to our functions because of this! Additionally, it would be a real pain to continuously be editing your mock file to first test a success, then failure, etc.

To help with this, you’re able to create as many different mock files as you want and reference them by name! The CLI generator will help you and place the mock in the appropriate directory. For example:

When running your tests now, you can use the different mocks to insure that both your error handling and successful responses are being properly returned. All you have to do is reference the mock file you wish to use by name via the -m flag.

Deploying our REST API to 8base

Deployment is going to be the easiest part here. Run 8base deploy… that’s it.

However, you may be asking yourself a burning question at this point, “where do I find my endpoints?” Once everything is done being deployed, go ahead and run 8base describe in the CLI. You should get something like this back:

8base CLI Describe Command for REST API

All your endpoints are now available at{PATH_IN_TABLE_ABOVE}.

‍Wrap Up

8base is an easy to use and scalable application backend that has an auto-generating GraphQL API. That said, for those developers building applications that require REST API interfaces, I hope this tutorial gave you some useful clues on how much can be accomplished using 8base!

Feel free to reach out with any questions!

Loves art, writing, and code.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store